missing files
This commit is contained in:
183
code/game/objects/items/weapons/inducer.dm
Normal file
183
code/game/objects/items/weapons/inducer.dm
Normal file
@@ -0,0 +1,183 @@
|
||||
/obj/item/weapon/inducer
|
||||
name = "inducer"
|
||||
desc = "A tool for inductively charging internal power cells."
|
||||
icon = 'icons/obj/tools.dmi'
|
||||
icon_state = "inducer-engi"
|
||||
item_state = "inducer-engi"
|
||||
origin_tech = "engineering=4;magnets=4;powerstorage=4"
|
||||
force = 7
|
||||
var/powertransfer = 1000
|
||||
var/opened = FALSE
|
||||
var/cell_type = /obj/item/weapon/stock_parts/cell/high
|
||||
var/obj/item/weapon/stock_parts/cell/cell
|
||||
var/recharging = FALSE
|
||||
|
||||
/obj/item/weapon/inducer/Initialize()
|
||||
. = ..()
|
||||
if(!cell && cell_type)
|
||||
cell = new cell_type
|
||||
|
||||
/obj/item/weapon/inducer/proc/induce(obj/item/weapon/stock_parts/cell/target, coefficient)
|
||||
var/totransfer = min(cell.charge,(powertransfer * coefficient))
|
||||
var/transferred = target.give(totransfer)
|
||||
cell.use(transferred)
|
||||
cell.update_icon()
|
||||
target.update_icon()
|
||||
|
||||
/obj/item/weapon/inducer/get_cell()
|
||||
return cell
|
||||
|
||||
/obj/item/weapon/inducer/emp_act(severity)
|
||||
..()
|
||||
if(cell)
|
||||
cell.emp_act()
|
||||
|
||||
/obj/item/weapon/inducer/attack_obj(obj/O, mob/living/carbon/user)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
|
||||
if(cantbeused(user))
|
||||
return
|
||||
|
||||
if(recharge(O, user))
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/inducer/proc/cantbeused(mob/user)
|
||||
if(!user.IsAdvancedToolUser())
|
||||
to_chat(user, "<span class='warning'>You don't have the dexterity to use \the [src]!</span>")
|
||||
return TRUE
|
||||
|
||||
if(!cell)
|
||||
to_chat(user, "<span class='warning'>\The [src] doesn't have a power cell installed!</span>")
|
||||
return TRUE
|
||||
|
||||
if(!cell.charge)
|
||||
to_chat(user, "<span class='warning'>\The [src]'s battery is dead!</span>")
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/obj/item/weapon/inducer/attackby(obj/item/weapon/W, mob/user)
|
||||
if(istype(W,/obj/item/weapon/screwdriver))
|
||||
playsound(src, W.usesound, 50, 1)
|
||||
if(!opened)
|
||||
to_chat(user, "<span class='notice'>You unscrew the battery compartment.</span>")
|
||||
opened = TRUE
|
||||
update_icon()
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You close the battery compartment.</span>")
|
||||
opened = FALSE
|
||||
update_icon()
|
||||
return
|
||||
if(istype(W,/obj/item/weapon/stock_parts/cell))
|
||||
if(opened)
|
||||
if(!cell)
|
||||
if(!user.transferItemToLoc(W, src))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You insert \the [W] into \the [src].</span>")
|
||||
cell = W
|
||||
update_icon()
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='notice'>\The [src] already has \a [cell] installed!</span>")
|
||||
return
|
||||
|
||||
if(cantbeused(user))
|
||||
return
|
||||
|
||||
if(recharge(W, user))
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/inducer/proc/recharge(atom/movable/A, mob/user)
|
||||
if(recharging)
|
||||
return TRUE
|
||||
else
|
||||
recharging = TRUE
|
||||
var/obj/item/weapon/stock_parts/cell/C = A.get_cell()
|
||||
var/obj/item/weapon/gun/energy/E
|
||||
var/obj/O
|
||||
var/coefficient = 1
|
||||
if(istype(A, /obj/item/weapon/gun/energy))
|
||||
coefficient = 0.075 // 14 loops to recharge an egun from 0-1000
|
||||
E = A
|
||||
if(istype(A, /obj))
|
||||
O = A
|
||||
if(C)
|
||||
if(C.charge >= C.maxcharge)
|
||||
to_chat(user, "<span class='notice'>\The [A] is fully charged!</span>")
|
||||
recharging = FALSE
|
||||
return TRUE
|
||||
user.visible_message("[user] starts recharging \the [A] with \the [src]","<span class='notice'>You start recharging [A] with \the [src]</span>")
|
||||
while(C.charge < C.maxcharge)
|
||||
if(E)
|
||||
E.chambered = null // Prevents someone from firing continuously while recharging the gun.
|
||||
if(do_after(user, 10, target = user) && cell.charge)
|
||||
induce(C, coefficient)
|
||||
do_sparks(1, FALSE, A)
|
||||
if(O)
|
||||
O.update_icon()
|
||||
else
|
||||
break
|
||||
if(E)
|
||||
E.recharge_newshot() //We're done charging, so we'll let someone fire it now.
|
||||
user.visible_message("[user] recharged \the [A]!","<span class='notice'>You recharged \the [A]!</span>")
|
||||
recharging = FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/weapon/inducer/attack(mob/M, mob/user)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
return ..()
|
||||
|
||||
if(cantbeused(user))
|
||||
return
|
||||
|
||||
if(recharge(M, user))
|
||||
return
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/weapon/inducer/attack_self(mob/user)
|
||||
if(opened && cell)
|
||||
user.visible_message("[user] removes \the [cell] from \the [src]!","<span class='notice'>You remove \the [cell].</span>")
|
||||
cell.update_icon()
|
||||
user.put_in_hands(cell)
|
||||
cell = null
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/weapon/inducer/examine(mob/living/M)
|
||||
..()
|
||||
if(cell)
|
||||
to_chat(M, "<span class='notice'>It's display shows: [cell.charge]W</span>")
|
||||
else
|
||||
to_chat(M,"<span class='notice'>It's display is dark.</span>")
|
||||
if(opened)
|
||||
to_chat(M,"<span class='notice'>It's battery compartment is open.</span>")
|
||||
|
||||
/obj/item/weapon/inducer/update_icon()
|
||||
cut_overlays()
|
||||
if(opened)
|
||||
if(!cell)
|
||||
add_overlay("inducer-nobat")
|
||||
else
|
||||
add_overlay("inducer-bat")
|
||||
|
||||
/obj/item/weapon/inducer/sci
|
||||
icon_state = "inducer-sci"
|
||||
item_state = "inducer-sci"
|
||||
desc = "A tool for inductively charging internal power cells. This one has a science color scheme, and is less potent than it's engineering counterpart."
|
||||
cell_type = null
|
||||
powertransfer = 500
|
||||
opened = TRUE
|
||||
|
||||
/obj/item/weapon/inducer/sci/Initialize()
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
|
||||
209
code/game/objects/structures/manned_turret.dm
Normal file
209
code/game/objects/structures/manned_turret.dm
Normal file
@@ -0,0 +1,209 @@
|
||||
/////// MANNED TURRET ////////
|
||||
|
||||
/obj/machinery/manned_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/turrets.dmi'
|
||||
icon_state = "machinegun"
|
||||
can_buckle = TRUE
|
||||
density = TRUE
|
||||
max_integrity = 100
|
||||
obj_integrity = 100
|
||||
buckle_lying = FALSE
|
||||
layer = ABOVE_MOB_LAYER
|
||||
var/view_range = 10
|
||||
var/cooldown = 0
|
||||
var/projectile_type = /obj/item/projectile/bullet/weakbullet3
|
||||
var/rate_of_fire = 1
|
||||
var/number_of_shots = 40
|
||||
var/cooldown_duration = 90
|
||||
var/atom/target
|
||||
var/turf/target_turf
|
||||
var/warned = FALSE
|
||||
var/list/calculated_projectile_vars
|
||||
|
||||
/obj/machinery/manned_turret/Destroy()
|
||||
target = null
|
||||
target_turf = null
|
||||
..()
|
||||
|
||||
//BUCKLE HOOKS
|
||||
|
||||
/obj/machinery/manned_turret/unbuckle_mob(mob/living/buckled_mob,force = FALSE)
|
||||
playsound(src,'sound/mecha/mechmove01.ogg', 50, 1)
|
||||
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 = 0
|
||||
buckled_mob.pixel_y = 0
|
||||
if(buckled_mob.client)
|
||||
buckled_mob.reset_perspective()
|
||||
anchored = FALSE
|
||||
. = ..()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
|
||||
/obj/machinery/manned_turret/user_buckle_mob(mob/living/M, mob/living/carbon/user)
|
||||
if(user.incapacitated() || !istype(user))
|
||||
return
|
||||
M.forceMove(get_turf(src))
|
||||
..()
|
||||
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, 1)
|
||||
anchored = TRUE
|
||||
if(user.client)
|
||||
user.client.change_view(view_range)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
|
||||
/obj/machinery/manned_turret/process()
|
||||
if(!LAZYLEN(buckled_mobs))
|
||||
return PROCESS_KILL
|
||||
update_positioning()
|
||||
|
||||
/obj/machinery/manned_turret/proc/update_positioning()
|
||||
var/mob/living/controller = buckled_mobs[1]
|
||||
if(!istype(controller))
|
||||
return
|
||||
var/client/C = controller.client
|
||||
if(C)
|
||||
var/atom/A = C.mouseObject
|
||||
var/turf/T = get_turf(A)
|
||||
if(istype(T)) //They're hovering over something in the map.
|
||||
direction_track(controller, T)
|
||||
calculated_projectile_vars = calculate_projectile_angle_and_pixel_offsets(controller, C.mouseParams)
|
||||
|
||||
/obj/machinery/manned_turret/proc/direction_track(mob/user, atom/targeted)
|
||||
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/manned_turret/proc/checkfire(atom/targeted_atom, mob/user)
|
||||
target = targeted_atom
|
||||
if(target == user || 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, 'sound/weapons/sear.ogg', 100, 1)
|
||||
return
|
||||
else
|
||||
cooldown = world.time + cooldown_duration
|
||||
warned = FALSE
|
||||
volley(user)
|
||||
|
||||
/obj/machinery/manned_turret/proc/volley(mob/user)
|
||||
target_turf = get_turf(target)
|
||||
for(var/i in 1 to number_of_shots)
|
||||
addtimer(CALLBACK(src, /obj/machinery/manned_turret/.proc/fire_helper, user), i*rate_of_fire)
|
||||
|
||||
/obj/machinery/manned_turret/proc/fire_helper(mob/user)
|
||||
update_positioning() //REFRESH MOUSE TRACKING!!
|
||||
var/turf/targets_from = get_turf(src)
|
||||
if(QDELETED(target))
|
||||
target = target_turf
|
||||
var/obj/item/projectile/P = new projectile_type(targets_from)
|
||||
P.current = targets_from
|
||||
P.starting = targets_from
|
||||
P.firer = user
|
||||
P.original = target
|
||||
playsound(src, 'sound/weapons/Gunshot_smg.ogg', 75, 1)
|
||||
P.xo = target.x - targets_from.x
|
||||
P.yo = target.y - targets_from.y
|
||||
P.Angle = calculated_projectile_vars[1] + rand(-9, 9)
|
||||
P.p_x = calculated_projectile_vars[2]
|
||||
P.p_y = calculated_projectile_vars[3]
|
||||
P.fire()
|
||||
|
||||
/obj/machinery/manned_turret/ultimate // Admin-only proof of concept for autoclicker automatics
|
||||
name = "Infinity Gun"
|
||||
view_range = 12
|
||||
projectile_type = /obj/item/projectile/bullet/weakbullet3
|
||||
|
||||
/obj/machinery/manned_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/item/gun_control
|
||||
name = "turret controls"
|
||||
icon = 'icons/obj/weapons.dmi'
|
||||
icon_state = "offhand"
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
flags = ABSTRACT | NODROP | NOBLUDGEON
|
||||
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
var/obj/machinery/manned_turret/turret
|
||||
|
||||
/obj/item/gun_control/Initialize()
|
||||
. = ..()
|
||||
turret = loc
|
||||
if(!istype(turret))
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
/obj/item/gun_control/Destroy()
|
||||
turret = null
|
||||
..()
|
||||
|
||||
/obj/item/gun_control/CanItemAutoclick()
|
||||
return TRUE
|
||||
|
||||
/obj/item/gun_control/attack_obj(obj/O, mob/living/user)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
O.attacked_by(src, user)
|
||||
|
||||
/obj/item/gun_control/attack(mob/living/M, mob/living/user)
|
||||
user.lastattacked = M
|
||||
M.lastattacker = user
|
||||
M.attacked_by(src, user)
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/item/gun_control/afterattack(atom/targeted_atom, mob/user, flag, params)
|
||||
..()
|
||||
var/obj/machinery/manned_turret/E = user.buckled
|
||||
E.calculated_projectile_vars = calculate_projectile_angle_and_pixel_offsets(user, params)
|
||||
E.direction_track(user, targeted_atom)
|
||||
E.checkfire(targeted_atom, user)
|
||||
Reference in New Issue
Block a user