diff --git a/code/game/objects/items/candle.dm b/code/game/objects/items/candle.dm index f0c3ee84e98..46ee95d119b 100644 --- a/code/game/objects/items/candle.dm +++ b/code/game/objects/items/candle.dm @@ -17,6 +17,10 @@ // No visible message light(show_message = 0) +/obj/item/candle/Destroy() + processing_objects.Remove(src) + return ..() + /obj/item/candle/update_icon() var/i if(wax>150) diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index d99ed06bb6c..ef1589f50b7 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -10,8 +10,7 @@ var/model_info dir = SOUTH - -/obj/item/robot_parts/New(var/newloc, var/model) +/obj/item/robot_parts/New(newloc, model) ..(newloc) if(model_info && model) model_info = model @@ -57,9 +56,13 @@ desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell." icon_state = "chest" part = list("groin","chest") - var/wires = 0.0 + var/wired = FALSE var/obj/item/weapon/stock_parts/cell/cell = null +/obj/item/robot_parts/chest/Destroy() + QDEL_NULL(cell) + return ..() + /obj/item/robot_parts/head name = "head" desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals." @@ -68,6 +71,11 @@ var/obj/item/device/flash/flash1 = null var/obj/item/device/flash/flash2 = null +/obj/item/robot_parts/head/Destroy() + QDEL_NULL(flash1) + QDEL_NULL(flash2) + return ..() + /obj/item/robot_parts/robot_suit name = "endoskeleton" desc = "A complex metal backbone with standard limb sockets and pseudomuscle anchors." @@ -88,89 +96,108 @@ /obj/item/robot_parts/robot_suit/New() ..() - src.updateicon() + updateicon() + +/obj/item/robot_parts/robot_suit/Destroy() + QDEL_NULL(l_arm) + QDEL_NULL(r_arm) + QDEL_NULL(l_leg) + QDEL_NULL(r_leg) + QDEL_NULL(chest) + QDEL_NULL(head) + forced_ai = null + return ..() /obj/item/robot_parts/robot_suit/proc/updateicon() - src.overlays.Cut() - if(src.l_arm) - src.overlays += "l_arm+o" - if(src.r_arm) - src.overlays += "r_arm+o" - if(src.chest) - src.overlays += "chest+o" - if(src.l_leg) - src.overlays += "l_leg+o" - if(src.r_leg) - src.overlays += "r_leg+o" - if(src.head) - src.overlays += "head+o" + overlays.Cut() + if(l_arm) + overlays += "l_arm+o" + if(r_arm) + overlays += "r_arm+o" + if(chest) + overlays += "chest+o" + if(l_leg) + overlays += "l_leg+o" + if(r_leg) + overlays += "r_leg+o" + if(head) + overlays += "head+o" /obj/item/robot_parts/robot_suit/proc/check_completion() - if(src.l_arm && src.r_arm) - if(src.l_leg && src.r_leg) - if(src.chest && src.head) + if(l_arm && r_arm) + if(l_leg && r_leg) + if(chest && head) feedback_inc("cyborg_frames_built",1) return 1 return 0 -/obj/item/robot_parts/robot_suit/attackby(obj/item/W as obj, mob/user as mob, params) +/obj/item/robot_parts/robot_suit/attackby(obj/item/W, mob/user, params) ..() if(istype(W, /obj/item/stack/sheet/metal) && !l_arm && !r_arm && !l_leg && !r_leg && !chest && !head) + var/obj/item/stack/sheet/metal/M = W var/obj/item/weapon/ed209_assembly/B = new /obj/item/weapon/ed209_assembly - B.loc = get_turf(src) + B.forceMove(get_turf(src)) to_chat(user, "You armed the robot frame") - W:use(1) + M.use(1) if(user.get_inactive_hand()==src) user.unEquip(src) user.put_in_inactive_hand(B) qdel(src) if(istype(W, /obj/item/robot_parts/l_leg)) - if(src.l_leg) return + if(l_leg) + return user.drop_item() - W.loc = src - src.l_leg = W - src.updateicon() + W.forceMove(src) + l_leg = W + updateicon() if(istype(W, /obj/item/robot_parts/r_leg)) - if(src.r_leg) return + if(r_leg) + return user.drop_item() - W.loc = src - src.r_leg = W - src.updateicon() + W.forceMove(src) + r_leg = W + updateicon() if(istype(W, /obj/item/robot_parts/l_arm)) - if(src.l_arm) return + if(l_arm) + return user.drop_item() - W.loc = src - src.l_arm = W - src.updateicon() + W.forceMove(src) + l_arm = W + updateicon() if(istype(W, /obj/item/robot_parts/r_arm)) - if(src.r_arm) return + if(r_arm) + return user.drop_item() - W.loc = src - src.r_arm = W - src.updateicon() + W.forceMove(src) + r_arm = W + updateicon() if(istype(W, /obj/item/robot_parts/chest)) - if(src.chest) return - if(W:wires && W:cell) + var/obj/item/robot_parts/chest/CH = W + if(chest) + return + if(CH.wired && CH.cell) user.drop_item() - W.loc = src - src.chest = W - src.updateicon() - else if(!W:wires) + W.forceMove(src) + chest = W + updateicon() + else if(!CH.wired) to_chat(user, "You need to attach wires to it first!") else to_chat(user, "You need to attach a cell to it first!") if(istype(W, /obj/item/robot_parts/head)) - if(src.head) return - if(W:flash2 && W:flash1) + var/obj/item/robot_parts/head/HD = W + if(head) + return + if(HD.flash2 && HD.flash1) user.drop_item() - W.loc = src - src.head = W - src.updateicon() + W.forceMove(src) + head = W + updateicon() else to_chat(user, "You need to attach a flash to it first!") @@ -183,11 +210,11 @@ if(istype(W, /obj/item/device/mmi)) var/obj/item/device/mmi/M = W if(check_completion()) - if(!istype(loc,/turf)) - to_chat(user, "You can't put \the [W] in, the frame has to be standing on the ground to be perfectly precise.") + if(!isturf(loc)) + to_chat(user, "You can't put [M] in, the frame has to be standing on the ground to be perfectly precise.") return if(!M.brainmob) - to_chat(user, "Sticking an empty [W] into the frame would sort of defeat the purpose.") + to_chat(user, "Sticking an empty [M] into the frame would sort of defeat the purpose.") return if(!M.brainmob.key) @@ -202,15 +229,15 @@ ghost_can_reenter = 1 break if(!ghost_can_reenter) - to_chat(user, "\The [W] is completely unresponsive; there's no point.") + to_chat(user, "[M] is completely unresponsive; there's no point.") return if(M.brainmob.stat == DEAD) - to_chat(user, "Sticking a dead [W] into the frame would sort of defeat the purpose.") + to_chat(user, "Sticking a dead [M] into the frame would sort of defeat the purpose.") return if(M.brainmob.mind in ticker.mode.head_revolutionaries) - to_chat(user, "The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept the [W].") + to_chat(user, "The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept the [M].") return if(jobban_isbanned(M.brainmob, "Cyborg") || jobban_isbanned(M.brainmob,"nonhumandept")) @@ -218,7 +245,8 @@ return var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(loc), unfinished = 1) - if(!O) return + if(!O) + return user.drop_item() @@ -257,9 +285,9 @@ O.job = "Cyborg" O.cell = chest.cell - chest.cell.loc = O + chest.cell.forceMove(O) chest.cell = null - W.loc = O//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame. + M.forceMove(O) //Should fix cybros run time erroring when blown up. It got deleted before, along with the frame. // Since we "magically" installed a cell, we also have to update the correct component. if(O.cell) var/datum/robot_component/cell_component = O.components["power cell"] @@ -271,7 +299,8 @@ feedback_inc("cyborg_birth",1) callHook("borgify", list(O)) - src.loc = O + forceMove(O) + O.robot_suit = src if(!locomotion) O.lockcharge = 1 @@ -308,8 +337,8 @@ return if(href_list["Name"]) - var/new_name = reject_bad_name(input(usr, "Enter new designation. Set to blank to reset to default.", "Cyborg Debug", src.created_name),1) - if(!in_range(src, usr) && src.loc != usr) + var/new_name = reject_bad_name(input(usr, "Enter new designation. Set to blank to reset to default.", "Cyborg Debug", created_name),1) + if(!in_range(src, usr) && loc != usr) return if(new_name) created_name = new_name @@ -337,22 +366,22 @@ /obj/item/robot_parts/chest/attackby(obj/item/W as obj, mob/user as mob, params) ..() if(istype(W, /obj/item/weapon/stock_parts/cell)) - if(src.cell) + if(cell) to_chat(user, "You have already inserted a cell!") return else user.drop_item() - W.loc = src - src.cell = W + W.forceMove(src) + cell = W to_chat(user, "You insert the cell!") if(istype(W, /obj/item/stack/cable_coil)) - if(src.wires) + if(wired) to_chat(user, "You have already inserted wire!") return else var/obj/item/stack/cable_coil/coil = W coil.use(1) - src.wires = 1.0 + wired = TRUE to_chat(user, "You insert the wire!") return @@ -362,18 +391,18 @@ if(istype(user,/mob/living/silicon/robot)) to_chat(user, "How do you propose to do that?") return - else if(src.flash1 && src.flash2) + else if(flash1 && flash2) to_chat(user, "You have already inserted the eyes!") return - else if(src.flash1) + else if(flash1) user.drop_item() - W.loc = src - src.flash2 = W + W.forceMove(src) + flash2 = W to_chat(user, "You insert the flash into the eye socket!") else user.drop_item() - W.loc = src - src.flash1 = W + W.forceMove(src) + flash1 = W to_chat(user, "You insert the flash into the eye socket!") else if(istype(W, /obj/item/weapon/stock_parts/manipulator)) to_chat(user, "You install some manipulators and modify the head, creating a functional spider-bot!") @@ -381,15 +410,10 @@ user.drop_item() qdel(W) qdel(src) - return - return -/obj/item/robot_parts/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W,/obj/item/weapon/card/emag)) - if(sabotaged) - to_chat(user, "[src] is already sabotaged!") - else - to_chat(user, "You slide [W] into the dataport on [src] and short out the safeties.") - sabotaged = 1 - return - ..() +/obj/item/robot_parts/emag_act(user) + if(sabotaged) + to_chat(user, "[src] is already sabotaged!") + else + to_chat(user, "You slide the emag into the dataport on [src] and short out the safeties.") + sabotaged = 1 diff --git a/code/game/objects/items/weapons/bee_briefcase.dm b/code/game/objects/items/weapons/bee_briefcase.dm index 7d2b718da82..3252fe4d856 100644 --- a/code/game/objects/items/weapons/bee_briefcase.dm +++ b/code/game/objects/items/weapons/bee_briefcase.dm @@ -18,6 +18,10 @@ var/sound_file = 'sound/misc/briefcase_bees.ogg' var/next_sound = 0 +/obj/item/weapon/bee_briefcase/Destroy() + blood_list.Cut() + return ..() + /obj/item/weapon/bee_briefcase/examine(mob/user) ..() if(loc == user) @@ -70,6 +74,6 @@ //Release up to 5 bees per use. Without using strange reagent, that means two uses. WITH strange reagent, you can get more if you don't release the last bee for(var/bee = min(5, bees_left), bee > 0, bee--) var/mob/living/simple_animal/hostile/poison/bees/syndi/B = new /mob/living/simple_animal/hostile/poison/bees/syndi(null) - B.master_and_friends = blood_list //Doesn't automatically add the person who opens the case, so the bees will attack the user unless they gave their blood + B.master_and_friends = blood_list.Copy() //Doesn't automatically add the person who opens the case, so the bees will attack the user unless they gave their blood B.forceMove(get_turf(user)) //RELEASE THE BEES! bees_left -= 5 diff --git a/code/modules/hydroponics/beekeeping/beebox.dm b/code/modules/hydroponics/beekeeping/beebox.dm index 18f87a8a45a..7bfa00d35c3 100644 --- a/code/modules/hydroponics/beekeeping/beebox.dm +++ b/code/modules/hydroponics/beekeeping/beebox.dm @@ -51,11 +51,13 @@ /obj/structure/beebox/Destroy() processing_objects.Remove(src) + for(var/mob/living/simple_animal/hostile/poison/bees/B in bees) + B.beehome = null bees.Cut() bees = null - honeycombs.Cut() - honeycombs = null - queen_bee = null + QDEL_LIST(honeycombs) + QDEL_LIST(honey_frames) + QDEL_NULL(queen_bee) return ..() diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 7e7aa825411..7c5297e07c4 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -75,6 +75,7 @@ plant_hud_set_water() /obj/machinery/hydroponics/Destroy() + remove_from_all_data_huds() QDEL_NULL(myseed) return ..() diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm index 379a15a296a..7f2c3587349 100644 --- a/code/modules/hydroponics/seed_extractor.dm +++ b/code/modules/hydroponics/seed_extractor.dm @@ -44,7 +44,7 @@ icon_state = "sextractor" density = 1 anchored = 1 - var/piles = list() + var/list/piles = list() var/max_seeds = 1000 var/seed_multiplier = 1 @@ -56,6 +56,10 @@ component_parts += new /obj/item/weapon/stock_parts/manipulator(null) RefreshParts() +/obj/machinery/seed_extractor/Destroy() + QDEL_LIST(piles) + return ..() + /obj/machinery/seed_extractor/RefreshParts() for(var/obj/item/weapon/stock_parts/matter_bin/B in component_parts) max_seeds = 1000 * B.rating @@ -125,14 +129,14 @@ /obj/machinery/seed_extractor/attack_hand(mob/user) interact(user) - + /obj/machinery/seed_extractor/attack_ghost(mob/user) interact(user) /obj/machinery/seed_extractor/interact(mob/user) if(stat) return 0 - + add_fingerprint(user) user.set_machine(src) diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm index 9aa93f9f92b..ae79eda23d3 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seeds.dm @@ -69,9 +69,7 @@ genes += new /datum/plant_gene/reagent(reag_id, reagents_add[reag_id]) /obj/item/seeds/Destroy() - for(var/thing in genes) - qdel(thing) - genes.Cut() + QDEL_LIST(genes) return ..() /obj/item/seeds/proc/Copy() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 2b0ded32896..8ab82e7d9ca 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -41,6 +41,7 @@ var/list/robot_verbs_default = list( // Components are basically robot organs. var/list/components = list() + var/obj/item/robot_parts/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of.. var/obj/item/device/mmi/mmi = null var/obj/item/device/pda/silicon/robot/rbPDA = null @@ -255,6 +256,7 @@ var/list/robot_verbs_default = list( QDEL_NULL(module) QDEL_NULL(camera) QDEL_NULL(cell) + QDEL_NULL(robot_suit) return ..() /mob/living/silicon/robot/proc/pick_module() @@ -644,20 +646,13 @@ var/list/robot_verbs_default = list( else if(wiresexposed && wires.IsAllCut()) //Cell is out, wires are exposed, remove MMI, produce damaged chassis, baleet original mob. if(!mmi) - to_chat(user, "\The [src] has no brain to remove.") + to_chat(user, "[src] has no brain to remove.") return - to_chat(user, "You jam the crowbar into the robot and begin levering [mmi].") + to_chat(user, "You jam the crowbar into the robot and begin levering the securing bolts.") if(do_after(user, 30 * W.toolspeed, target = src)) - to_chat(user, "You damage some parts of the chassis, but eventually manage to rip out [mmi]!") - var/obj/item/robot_parts/robot_suit/C = new/obj/item/robot_parts/robot_suit(loc) - C.l_leg = new/obj/item/robot_parts/l_leg(C) - C.r_leg = new/obj/item/robot_parts/r_leg(C) - C.l_arm = new/obj/item/robot_parts/l_arm(C) - C.r_arm = new/obj/item/robot_parts/r_arm(C) - C.updateicon() - new/obj/item/robot_parts/chest(loc) - qdel(src) + user.visible_message("[user] deconstructs [src]!", "You unfasten the securing bolts, and [src] falls to pieces!") + deconstruct() else // Okay we're not removing the cell or an MMI, but maybe something else? var/list/removable_components = list() @@ -1135,6 +1130,49 @@ var/list/robot_verbs_default = list( update_icons() +/mob/living/silicon/robot/proc/deconstruct() + var/turf/T = get_turf(src) + if(robot_suit) + robot_suit.forceMove(T) + robot_suit.l_leg.forceMove(T) + robot_suit.l_leg = null + robot_suit.r_leg.forceMove(T) + robot_suit.r_leg = null + new /obj/item/stack/cable_coil(T, robot_suit.chest.wired) + robot_suit.chest.forceMove(T) + robot_suit.chest.wired = FALSE + robot_suit.chest = null + robot_suit.l_arm.forceMove(T) + robot_suit.l_arm = null + robot_suit.r_arm.forceMove(T) + robot_suit.r_arm = null + robot_suit.head.forceMove(T) + robot_suit.head.flash1.forceMove(T) + robot_suit.head.flash1.burn_out() + robot_suit.head.flash1 = null + robot_suit.head.flash2.forceMove(T) + robot_suit.head.flash2.burn_out() + robot_suit.head.flash2 = null + robot_suit.head = null + robot_suit.updateicon() + else + new /obj/item/robot_parts/robot_suit(T) + new /obj/item/robot_parts/l_leg(T) + new /obj/item/robot_parts/r_leg(T) + new /obj/item/stack/cable_coil(T, 1) + new /obj/item/robot_parts/chest(T) + new /obj/item/robot_parts/l_arm(T) + new /obj/item/robot_parts/r_arm(T) + new /obj/item/robot_parts/head(T) + var/b + for(b=0, b!=2, b++) + var/obj/item/device/flash/F = new /obj/item/device/flash(T) + F.burn_out() + if(cell) //Sanity check. + cell.forceMove(T) + cell = null + qdel(src) + #define BORG_CAMERA_BUFFER 30 /mob/living/silicon/robot/Move(a, b, flag) var/oldLoc = src.loc diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm index 904762d6c27..ffd354961ef 100644 --- a/code/modules/mob/living/simple_animal/hostile/bees.dm +++ b/code/modules/mob/living/simple_animal/hostile/bees.dm @@ -58,15 +58,12 @@ /mob/living/simple_animal/hostile/poison/bees/Destroy() beegent = null + if(beehome) + if(beehome.bees) + beehome.bees.Remove(src) + beehome = null return ..() -/mob/living/simple_animal/hostile/poison/bees/death(gibbed) - beegent = null - ..() - -/mob/living/simple_animal/hostile/poison/bees/examine(mob/user) - ..() - /mob/living/simple_animal/hostile/poison/bees/proc/generate_bee_visuals() overlays.Cut() @@ -137,21 +134,6 @@ /mob/living/simple_animal/hostile/poison/bees/worker //Blank type define in case we need to give them special stuff later, plus organization (currently they are same as base type bee) - -/mob/living/simple_animal/hostile/poison/bees/worker/Destroy() - if(beehome) - if(beehome.bees) - beehome.bees.Remove(src) - beehome = null - return ..() - -/mob/living/simple_animal/hostile/poison/bees/worker/death(gibbed) - if(beehome) - if(beehome.bees) - beehome.bees.Remove(src) - beehome = null - ..() - /mob/living/simple_animal/hostile/poison/bees/worker/examine(mob/user) ..() @@ -313,6 +295,10 @@ beegent = new /datum/reagent/facid() //prepare to die var/list/master_and_friends = list() +/mob/living/simple_animal/hostile/poison/bees/syndi/Destroy() + master_and_friends.Cut() + return ..() + /mob/living/simple_animal/hostile/poison/bees/syndi/assign_reagent(datum/reagent/R) return diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 1df7348a839..911f66a5527 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -30,7 +30,7 @@ var/attack_same = 0 //Set us to 1 to allow us to attack our own faction, or 2, to only ever attack our own faction var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever) - + //typecache of things this mob will attack in DestroySurroundings() if it has environment_smash var/list/environment_target_typecache = list( /obj/machinery/door/window, @@ -44,15 +44,16 @@ var/atom/targets_from = null //all range/attack/etc. calculations should be done from this atom, defaults to the mob itself, useful for Vehicles and such var/list/emote_taunt = list() var/taunt_chance = 0 - + /mob/living/simple_animal/hostile/New() ..() if(!targets_from) targets_from = src environment_target_typecache = typecacheof(environment_target_typecache) - + /mob/living/simple_animal/hostile/Destroy() targets_from = null + target = null return ..() /mob/living/simple_animal/hostile/Life() @@ -80,7 +81,7 @@ if(AIShouldSleep(possible_targets)) // we try to acquire a new one AIStatus = AI_IDLE // otherwise we go idle return 1 - + /mob/living/simple_animal/hostile/attacked_by(obj/item/I, mob/living/user) if(stat == CONSCIOUS && !target && AIStatus != AI_OFF && !client && user) FindTarget(list(user), 1) @@ -91,8 +92,8 @@ if(P.firer && get_dist(src, P.firer) <= aggro_vision_range) FindTarget(list(P.firer), 1) Goto(P.starting, move_to_delay, 3) - return ..() - + return ..() + //////////////HOSTILE MOB TARGETTING AND AGGRESSION//////////// @@ -126,7 +127,7 @@ var/Target = PickTarget(.) GiveTarget(Target) return Target //We now have a target - + /mob/living/simple_animal/hostile/proc/PossibleThreats() . = list() for(var/pos_targ in ListTargets()) @@ -176,24 +177,24 @@ if(faction_check && !attack_same) return 0 return 1 - + if(ishuman(the_target)) var/mob/living/carbon/human/H = the_target if(is_type_in_list(src, H.species.ignored_by)) return 0 - + if(istype(the_target, /obj/mecha)) var/obj/mecha/M = the_target if(M.occupant)//Just so we don't attack empty mechs if(CanAttack(M.occupant)) return 1 - + if(istype(the_target, /obj/spacepod)) var/obj/spacepod/S = the_target if(S.pilot) //Just so we don't attack empty pods if(CanAttack(S.pilot)) return 1 - + if(istype(the_target, /obj/machinery/porta_turret)) var/obj/machinery/porta_turret/P = the_target if(P.faction in faction) @@ -292,7 +293,7 @@ /mob/living/simple_animal/hostile/death(gibbed) LoseTarget() ..(gibbed) - + /mob/living/simple_animal/hostile/proc/summon_backup(distance) do_alert_animation(src) playsound(loc, 'sound/machines/chime.ogg', 50, 1, -1)