diff --git a/code/datums/components/archaeology.dm b/code/datums/components/archaeology.dm deleted file mode 100644 index b5740650e9f..00000000000 --- a/code/datums/components/archaeology.dm +++ /dev/null @@ -1,95 +0,0 @@ -/datum/component/archaeology - dupe_mode = COMPONENT_DUPE_UNIQUE - var/list/archdrops = list(/obj/item/bikehorn = list(ARCH_PROB = 100, ARCH_MAXDROP = 1)) // honk~ - var/prob2drop - var/dug - var/datum/callback/callback - -/datum/component/archaeology/Initialize(list/_archdrops = list(), datum/callback/_callback) - archdrops = _archdrops - for(var/i in archdrops) - if(isnull(archdrops[i][ARCH_MAXDROP])) - archdrops[i][ARCH_MAXDROP] = 1 - stack_trace("ARCHAEOLOGY WARNING: [parent] contained a null max_drop value in [i].") - if(isnull(archdrops[i][ARCH_PROB])) - archdrops[i][ARCH_PROB] = 100 - stack_trace("ARCHAEOLOGY WARNING: [parent] contained a null probability value in [i].") - callback = _callback - RegisterSignal(parent, COMSIG_PARENT_ATTACKBY,.proc/Dig) - RegisterSignal(parent, COMSIG_ATOM_EX_ACT, .proc/BombDig) - RegisterSignal(parent, COMSIG_ATOM_SING_PULL, .proc/SingDig) - -/datum/component/archaeology/InheritComponent(datum/component/archaeology/A, i_am_original) - var/list/other_archdrops = A.archdrops - var/list/_archdrops = archdrops - for(var/I in other_archdrops) - _archdrops[I] += other_archdrops[I] - -/datum/component/archaeology/proc/Dig(datum/source, obj/item/I, mob/living/user) - if(dug) - to_chat(user, "Looks like someone has dug here already.") - return - - if(!isturf(user.loc)) - return - - if(I.tool_behaviour == TOOL_SHOVEL || I.tool_behaviour == TOOL_MINING) - to_chat(user, "You start digging...") - - if(I.use_tool(parent, user, 40, volume=50)) - to_chat(user, "You dig a hole.") - gets_dug() - dug = TRUE - SSblackbox.record_feedback("tally", "pick_used_mining", 1, I.type) - return COMPONENT_NO_AFTERATTACK - -/datum/component/archaeology/proc/gets_dug() - if(dug) - return - else - var/turf/open/OT = get_turf(parent) - for(var/thing in archdrops) - var/maxtodrop = archdrops[thing][ARCH_MAXDROP] - for(var/i in 1 to maxtodrop) - if(prob(archdrops[thing][ARCH_PROB])) // can't win them all! - new thing(OT) - - if(isopenturf(OT)) - if(OT.postdig_icon_change) - if(istype(OT, /turf/open/floor/plating/asteroid/) && !OT.postdig_icon) - var/turf/open/floor/plating/asteroid/AOT = parent - AOT.icon_plating = "[AOT.environment_type]_dug" - AOT.icon_state = "[AOT.environment_type]_dug" - else - if(isplatingturf(OT)) - var/turf/open/floor/plating/POT = parent - POT.icon_plating = "[POT.postdig_icon]" - POT.icon_state = "[OT.postdig_icon]" - - if(OT.slowdown) //Things like snow slow you down until you dig them. - OT.slowdown = 0 - dug = TRUE - if(callback) - callback.Invoke() - -/datum/component/archaeology/proc/SingDig(datum/source, S, current_size) - switch(current_size) - if(STAGE_THREE) - if(prob(30)) - gets_dug() - if(STAGE_FOUR) - if(prob(50)) - gets_dug() - else - if(current_size >= STAGE_FIVE && prob(70)) - gets_dug() - -/datum/component/archaeology/proc/BombDig(datum/source, severity, target) - switch(severity) - if(3) - return - if(2) - if(prob(20)) - gets_dug() - if(1) - gets_dug() diff --git a/code/datums/components/art.dm b/code/datums/components/art.dm deleted file mode 100644 index 125e2c4313d..00000000000 --- a/code/datums/components/art.dm +++ /dev/null @@ -1,40 +0,0 @@ -/datum/component/art - var/impressiveness = 0 - -/datum/component/art/Initialize(impress) - impressiveness = impress - if(isobj(parent)) - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_obj_examine) - else - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_other_examine) - if(isstructure(parent)) - RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand) - if(isitem(parent)) - RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/apply_moodlet) - -/datum/component/art/proc/apply_moodlet(mob/M, impress) - M.visible_message("[M] stops and looks intently at [parent].", \ - "You stop to take in [parent].") - switch(impress) - if (0 to BAD_ART) - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artbad", /datum/mood_event/artbad) - if (BAD_ART to GOOD_ART) - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artok", /datum/mood_event/artok) - if (GOOD_ART to GREAT_ART) - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgood", /datum/mood_event/artgood) - if(GREAT_ART to INFINITY) - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "artgreat", /datum/mood_event/artgreat) - - -/datum/component/art/proc/on_other_examine(datum/source, mob/M) - apply_moodlet(M, impressiveness) - -/datum/component/art/proc/on_obj_examine(datum/source, mob/M) - var/obj/O = parent - apply_moodlet(M, impressiveness *(O.obj_integrity/O.max_integrity)) - -/datum/component/art/proc/on_attack_hand(datum/source, mob/M) - to_chat(M, "You start examining [parent].") - if(!do_after(M, 20, target = parent)) - return - on_obj_examine(source, M) diff --git a/code/datums/components/bane.dm b/code/datums/components/bane.dm deleted file mode 100644 index aac56d099e5..00000000000 --- a/code/datums/components/bane.dm +++ /dev/null @@ -1,45 +0,0 @@ -/datum/component/bane - dupe_mode = COMPONENT_DUPE_ALLOWED - - var/mobtype - var/speciestype - var/damage_multiplier - -/datum/component/bane/Initialize(mobtype, damage_multiplier=1) - if(!isitem(parent)) - return COMPONENT_INCOMPATIBLE - - if(ispath(mobtype, /mob/living)) - src.mobtype = mobtype - else if(ispath(mobtype, /datum/species)) - speciestype = mobtype - else - return COMPONENT_INCOMPATIBLE - - src.damage_multiplier = damage_multiplier - -/datum/component/bane/RegisterWithParent() - if(speciestype) - RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/speciesCheck) - else - RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/mobCheck) - -/datum/component/bane/UnregisterFromParent() - UnregisterSignal(parent, COMSIG_ITEM_AFTERATTACK) - -/datum/component/bane/proc/speciesCheck(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters) - if(!is_species(target, speciestype)) - return - activate(source, target, user) - -/datum/component/bane/proc/mobCheck(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters) - if(!istype(target, mobtype)) - return - activate(source, target, user) - -/datum/component/bane/proc/activate(obj/item/source, mob/living/target, mob/attacker) - if(attacker.a_intent != INTENT_HARM) - return - - var/extra_damage = max(0, source.force * damage_multiplier) - target.apply_damage(extra_damage, source.damtype, attacker.zone_selected) diff --git a/code/datums/components/beetlejuice.dm b/code/datums/components/beetlejuice.dm deleted file mode 100644 index 8df118565a3..00000000000 --- a/code/datums/components/beetlejuice.dm +++ /dev/null @@ -1,60 +0,0 @@ -/datum/component/beetlejuice - var/keyword - var/list/first_heard - var/list/count - var/max_delay = 3 SECONDS //How fast they need to be said - var/min_count = 3 - var/cooldown = 30 SECONDS //Delay between teleports - var/active = TRUE - var/case_sensitive = FALSE - var/regex/R - -/datum/component/beetlejuice/Initialize() - if(!ismovable(parent)) - return COMPONENT_INCOMPATIBLE - - first_heard = list() - count = list() - - var/atom/movable/O = parent - keyword = O.name - if(ismob(O)) - var/mob/M = parent - keyword = M.real_name - update_regex() - - RegisterSignal(SSdcs, COMSIG_GLOB_LIVING_SAY_SPECIAL, .proc/say_react) - -/datum/component/beetlejuice/proc/update_regex() - R = regex("[REGEX_QUOTE(keyword)]","g[case_sensitive ? "" : "i"]") - -/datum/component/beetlejuice/vv_edit_var(var_name, var_value) - . = ..() - if (var_name == NAMEOF(src, keyword) || var_name == NAMEOF(src, case_sensitive)) - update_regex() - -/datum/component/beetlejuice/proc/say_react(datum/source, mob/speaker,message) - if(!speaker || !message || !active) - return - var/found = R.Find(message) - if(found) - var/occurences = 1 - while(R.Find(message)) - occurences++ - R.next = 1 - - if(!first_heard[speaker] || (first_heard[speaker] + max_delay < world.time)) - first_heard[speaker] = world.time - count[speaker] = 0 - count[speaker] += occurences - if(count[speaker] >= min_count) - first_heard -= speaker - count -= speaker - apport(speaker) - - -/datum/component/beetlejuice/proc/apport(atom/target) - var/atom/movable/AM = parent - do_teleport(AM,get_turf(target)) - active = FALSE - addtimer(VARSET_CALLBACK(src, active, TRUE), cooldown) diff --git a/code/datums/components/butchering.dm b/code/datums/components/butchering.dm deleted file mode 100644 index 5232a74b8e1..00000000000 --- a/code/datums/components/butchering.dm +++ /dev/null @@ -1,94 +0,0 @@ -//This is mostly translated and ready to go here, minus correcting a few things in other areas of the code. I just don't want to refactor meat harvesting at the moment. Maybe later. - -/datum/component/butchering - var/speed = 80 //time in deciseconds taken to butcher something - var/effectiveness = 100 //percentage effectiveness; numbers above 100 yield extra drops - var/bonus_modifier = 0 //percentage increase to bonus item chance - var/butcher_sound = 'sound/weapons/slice.ogg' //sound played when butchering - var/butchering_enabled = TRUE - var/can_be_blunt = FALSE - -/datum/component/butchering/Initialize(_speed, _effectiveness, _bonus_modifier, _butcher_sound, disabled, _can_be_blunt) - if(_speed) - speed = _speed - if(_effectiveness) - effectiveness = _effectiveness - if(_bonus_modifier) - bonus_modifier = _bonus_modifier - if(_butcher_sound) - butcher_sound = _butcher_sound - if(disabled) - butchering_enabled = FALSE - if(_can_be_blunt) - can_be_blunt = _can_be_blunt - if(isitem(parent)) - RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/onItemAttack) - -/datum/component/butchering/proc/onItemAttack(obj/item/source, mob/living/M, mob/living/user) - if(user.a_intent == INTENT_HARM && M.stat == DEAD && (M.butcher_results || M.guaranteed_butcher_results)) //can we butcher it? - if(butchering_enabled && (can_be_blunt || source.sharp)) - INVOKE_ASYNC(src, .proc/startButcher, source, M, user) - return COMPONENT_ITEM_NO_ATTACK - -/datum/component/butchering/proc/startButcher(obj/item/source, mob/living/M, mob/living/user) - to_chat(user, "You begin to butcher [M]...") - playsound(M.loc, butcher_sound, 50, TRUE, -1) - if(do_mob(user, M, speed) && M.Adjacent(source)) - Butcher(user, M) - -/datum/component/butchering/proc/Butcher(mob/living/butcher, mob/living/meat) - var/turf/T = meat.drop_location() - var/final_effectiveness = effectiveness - meat.butcher_difficulty - var/bonus_chance = max(0, (final_effectiveness - 100) + bonus_modifier) //so 125 total effectiveness = 25% extra chance - for(var/V in meat.butcher_results) - var/obj/bones = V - var/amount = meat.butcher_results[bones] - for(var/_i in 1 to amount) - if(!prob(final_effectiveness)) - if(butcher) - to_chat(butcher, "You fail to harvest some of the [initial(bones.name)] from [meat].") - else if(prob(bonus_chance)) - if(butcher) - to_chat(butcher, "You harvest some extra [initial(bones.name)] from [meat]!") - for(var/i in 1 to 2) - new bones (T) - else - new bones (T) - meat.butcher_results.Remove(bones) //in case you want to, say, have it drop its results on gib - for(var/V in meat.guaranteed_butcher_results) - var/obj/sinew = V - var/amount = meat.guaranteed_butcher_results[sinew] - for(var/i in 1 to amount) - new sinew (T) - meat.guaranteed_butcher_results.Remove(sinew) - if(butcher) - butcher.visible_message("[butcher] butchers [meat].", \ - "You butcher [meat].") - ButcherEffects(meat) - meat.harvest(butcher) - meat.gib(FALSE, FALSE, TRUE) - -/datum/component/butchering/proc/ButcherEffects(mob/living/meat) //extra effects called on butchering, override this via subtypes - return - -/* I believe I want this for disposals eventually? Commenting out for now to silence its errors. -///Special snowflake component only used for the recycler. -/datum/component/butchering/recycler - -/datum/component/butchering/recycler/Initialize(_speed, _effectiveness, _bonus_modifier, _butcher_sound, disabled, _can_be_blunt) - if(!istype(parent, /obj/machinery/recycler)) //EWWW - return COMPONENT_INCOMPATIBLE - . = ..() - if(. == COMPONENT_INCOMPATIBLE) - return - RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/onCrossed) - -/datum/component/butchering/recycler/proc/onCrossed(datum/source, mob/living/L) - if(!istype(L)) - return - var/obj/machinery/recycler/eater = parent - if(eater.safety_mode || (eater.stat & (BROKEN|NOPOWER))) //I'm so sorry. - return - if(L.stat == DEAD && (L.butcher_results || L.guaranteed_butcher_results)) - Butcher(parent, L) -*/ diff --git a/code/datums/components/caltrop.dm b/code/datums/components/caltrop.dm deleted file mode 100644 index cdf852f82a1..00000000000 --- a/code/datums/components/caltrop.dm +++ /dev/null @@ -1,62 +0,0 @@ -/datum/component/caltrop - var/min_damage - var/max_damage - var/probability - var/flags - - var/cooldown = 0 - -/datum/component/caltrop/Initialize(_min_damage = 0, _max_damage = 0, _probability = 100, _flags = NONE) - min_damage = _min_damage - max_damage = max(_min_damage, _max_damage) - probability = _probability - flags = _flags - - RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED), .proc/Crossed) - -/datum/component/caltrop/proc/Crossed(datum/source, atom/movable/AM) - var/atom/A = parent - if(!A.has_gravity()) - return - - if(!prob(probability)) - return - - if(ishuman(AM)) - var/mob/living/carbon/human/H = AM - if(HAS_TRAIT(H, TRAIT_PIERCEIMMUNE)) - return - - if((flags & CALTROP_IGNORE_WALKERS) && H.m_intent == MOVE_INTENT_WALK) - return - - var/picked_def_zone = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) - var/obj/item/bodypart/O = H.get_bodypart(picked_def_zone) - if(!istype(O)) - return - if(O.status == BODYPART_ROBOTIC) - return - - var/feetCover = (H.wear_suit && (H.wear_suit.body_cover_flags & FEET)) || (H.w_uniform && (H.w_uniform.body_cover_flags & FEET)) - - if(!(flags & CALTROP_BYPASS_SHOES) && (H.shoes || feetCover)) - return - - if((H.movement_type & MOVEMENT_FLYING) || H.buckled) - return - - var/damage = rand(min_damage, max_damage) - if(HAS_TRAIT(H, TRAIT_LIGHT_STEP)) - damage *= 0.75 - H.apply_damage(damage, BRUTE, picked_def_zone) - - if(cooldown < world.time - 10) //cooldown to avoid message spam. - if(!H.incapacitated(ignore_restraints = TRUE)) - H.visible_message("[H] steps on [A].", \ - "You step on [A]!") - else - H.visible_message("[H] slides on [A]!", \ - "You slide on [A]!") - - cooldown = world.time - H.Paralyze(60) diff --git a/code/datums/components/chasm.dm b/code/datums/components/chasm.dm deleted file mode 100644 index 8a8aca2080a..00000000000 --- a/code/datums/components/chasm.dm +++ /dev/null @@ -1,143 +0,0 @@ -// Used by /turf/open/chasm and subtypes to implement the "dropping" mechanic -/datum/component/chasm - var/turf/target_turf - var/fall_message = "GAH! Ah... where are you?" - var/oblivion_message = "You stumble and stare into the abyss before you. It stares back, and you fall into the enveloping dark." - - var/static/list/falling_atoms = list() // Atoms currently falling into chasms - var/static/list/forbidden_types = typecacheof(list( - /obj/singularity, - /obj/docking_port, - /obj/structure/lattice, - /obj/structure/stone_tile, - /obj/projectile, - /obj/effect/projectile, - /obj/effect/portal, - /obj/effect/abstract, - /obj/effect/hotspot, - /obj/landmark, - /obj/effect/temp_visual, - /obj/effect/light_emitter/tendril, - /obj/effect/collapse, - /obj/effect/particle_effect/ion_trails, - /obj/effect/dummy/phased_mob - )) - -/datum/component/chasm/Initialize(turf/target) - RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Entered) - target_turf = target - START_PROCESSING(SSobj, src) // process on create, in case stuff is still there - -/datum/component/chasm/proc/Entered(datum/source, atom/movable/AM) - START_PROCESSING(SSobj, src) - drop_stuff(AM) - -/datum/component/chasm/process(delta_time) - if (!drop_stuff()) - STOP_PROCESSING(SSobj, src) - -/datum/component/chasm/proc/is_safe() - //if anything matching this typecache is found in the chasm, we don't drop things - var/static/list/chasm_safeties_typecache = typecacheof(list(/obj/structure/lattice/catwalk, /obj/structure/stone_tile)) - - var/atom/parent = src.parent - var/list/found_safeties = typecache_filter_list(parent.contents, chasm_safeties_typecache) - for(var/obj/structure/stone_tile/S in found_safeties) - if(S.fallen) - LAZYREMOVE(found_safeties, S) - return LAZYLEN(found_safeties) - -/datum/component/chasm/proc/drop_stuff(AM) - . = 0 - if (is_safe()) - return FALSE - - var/atom/parent = src.parent - var/to_check = AM ? list(AM) : parent.contents - for (var/thing in to_check) - if (droppable(thing)) - . = 1 - INVOKE_ASYNC(src, .proc/drop, thing) - -/datum/component/chasm/proc/droppable(atom/movable/AM) - // avoid an infinite loop, but allow falling a large distance - if(falling_atoms[AM] && falling_atoms[AM] > 30) - return FALSE - if(!isliving(AM) && !isobj(AM)) - return FALSE - if(is_type_in_typecache(AM, forbidden_types) || AM.throwing || (AM.movement_type & MOVEMENT_FLOATING)) - return FALSE - //Flies right over the chasm - if(ismob(AM)) - var/mob/M = AM - if(M.buckled) //middle statement to prevent infinite loops just in case! - var/mob/buckled_to = M.buckled - if((!ismob(M.buckled) || (buckled_to.buckled != M)) && !droppable(M.buckled)) - return FALSE - if(M.is_flying()) - return FALSE - if(ishuman(AM)) - var/mob/living/carbon/human/H = AM - if(istype(H.belt, /obj/item/wormhole_jaunter)) - var/obj/item/wormhole_jaunter/J = H.belt - //To freak out any bystanders - H.visible_message("[H] falls into [parent]!") - J.chasm_react(H) - return FALSE - return TRUE - -/datum/component/chasm/proc/drop(atom/movable/AM) - //Make sure the item is still there after our sleep - if(!AM || QDELETED(AM)) - return - falling_atoms[AM] = (falling_atoms[AM] || 0) + 1 - var/turf/T = target_turf - - if(T) - // send to the turf below - AM.visible_message("[AM] falls into [parent]!", "[fall_message]") - T.visible_message("[AM] falls from above!") - AM.forceMove(T) - if(isliving(AM)) - var/mob/living/L = AM - L.Paralyze(100) - L.adjustBruteLoss(30) - falling_atoms -= AM - - else - // send to oblivion - AM.visible_message("[AM] falls into [parent]!", "[oblivion_message]") - if (isliving(AM)) - var/mob/living/L = AM - L.notransform = TRUE - L.afflict_stun(20 * 200) - L.resting = TRUE - - var/oldtransform = AM.transform - var/oldcolor = AM.color - var/oldalpha = AM.alpha - animate(AM, transform = matrix() - matrix(), alpha = 0, color = rgb(0, 0, 0), time = 10) - for(var/i in 1 to 5) - //Make sure the item is still there after our sleep - if(!AM || QDELETED(AM)) - return - AM.pixel_y-- - sleep(2) - - //Make sure the item is still there after our sleep - if(!AM || QDELETED(AM)) - return - - if(iscyborg(AM)) - var/mob/living/silicon/robot/S = AM - qdel(S.mmi) - - falling_atoms -= AM - qdel(AM) - if(AM && !QDELETED(AM)) //It's indestructible - var/atom/parent = src.parent - parent.visible_message("[parent] spits out [AM]!") - AM.alpha = oldalpha - AM.color = oldcolor - AM.transform = oldtransform - AM.throw_at_old(get_edge_target_turf(parent,pick(GLOB.alldirs)),rand(1, 10),rand(1, 10)) diff --git a/code/datums/components/construction.dm b/code/datums/components/construction.dm deleted file mode 100644 index 01df44752c9..00000000000 --- a/code/datums/components/construction.dm +++ /dev/null @@ -1,157 +0,0 @@ -#define FORWARD 1 -#define BACKWARD -1 - -#define ITEM_DELETE "delete" -#define ITEM_MOVE_INSIDE "move_inside" - - -/datum/component/construction - var/list/steps - var/result - var/index = 1 - var/desc - -/datum/component/construction/Initialize() - if(!isatom(parent)) - return COMPONENT_INCOMPATIBLE - - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine) - RegisterSignal(parent, COMSIG_PARENT_ATTACKBY,.proc/action) - update_parent(index) - -/datum/component/construction/proc/examine(datum/source, mob/user, list/examine_list) - if(desc) - examine_list += desc - -/datum/component/construction/proc/on_step() - if(index > steps.len) - spawn_result() - else - update_parent(index) - -/datum/component/construction/proc/action(datum/source, obj/item/I, mob/living/user) - return check_step(I, user) - -/datum/component/construction/proc/update_index(diff) - index += diff - on_step() - -/datum/component/construction/proc/check_step(obj/item/I, mob/living/user) - var/diff = is_right_key(I) - if(diff && custom_action(I, user, diff)) - update_index(diff) - return TRUE - return FALSE - -/datum/component/construction/proc/is_right_key(obj/item/I) // returns index step - var/list/L = steps[index] - if(check_used_item(I, L["key"])) - return FORWARD //to the first step -> forward - else if(check_used_item(I, L["back_key"])) - return BACKWARD //to the last step -> backwards - return FALSE - -/datum/component/construction/proc/check_used_item(obj/item/I, key) - if(!key) - return FALSE - - if(ispath(key) && istype(I, key)) - return TRUE - - else if(I.tool_behaviour == key) - return TRUE - - return FALSE - -/datum/component/construction/proc/custom_action(obj/item/I, mob/living/user, diff) - var/target_index = index + diff - var/list/current_step = steps[index] - var/list/target_step - - if(target_index > 0 && target_index <= steps.len) - target_step = steps[target_index] - - . = TRUE - - if(I.tool_behaviour) - . = I.use_tool(parent, user, 0, volume=50) - - else if(diff == FORWARD) - switch(current_step["action"]) - if(ITEM_DELETE) - . = user.transferItemToLoc(I, parent) - if(.) - qdel(I) - - if(ITEM_MOVE_INSIDE) - . = user.transferItemToLoc(I, parent) - - // Using stacks - else if(istype(I, /obj/item/stack)) - . = I.use_tool(parent, user, 0, volume=50, amount=current_step["amount"]) - - - // Going backwards? Undo the last action. Drop/respawn the items used in last action, if any. - if(. && diff == BACKWARD && target_step && !target_step["no_refund"]) - var/target_step_key = target_step["key"] - - switch(target_step["action"]) - if(ITEM_DELETE) - new target_step_key(drop_location()) - - if(ITEM_MOVE_INSIDE) - var/obj/item/located_item = locate(target_step_key) in parent - if(located_item) - located_item.forceMove(drop_location()) - - else if(ispath(target_step_key, /obj/item/stack)) - new target_step_key(drop_location(), target_step["amount"]) - -/datum/component/construction/proc/spawn_result() - // Some constructions result in new components being added. - if(ispath(result, /datum/component)) - parent.AddComponent(result) - qdel(src) - - else if(ispath(result, /atom)) - new result(drop_location()) - qdel(parent) - -/datum/component/construction/proc/update_parent(step_index) - var/list/step = steps[step_index] - var/atom/parent_atom = parent - - if(step["desc"]) - desc = step["desc"] - - if(step["icon_state"]) - parent_atom.icon_state = step["icon_state"] - -/datum/component/construction/proc/drop_location() - var/atom/parent_atom = parent - return parent_atom.drop_location() - - - -// Unordered construction. -// Takes a list of part types, to be added in any order, as steps. -// Calls spawn_result() when every type has been added. -/datum/component/construction/unordered/check_step(obj/item/I, mob/living/user) - for(var/typepath in steps) - if(istype(I, typepath) && custom_action(I, user, typepath)) - steps -= typepath - on_step() - return TRUE - return FALSE - -/datum/component/construction/unordered/on_step() - if(!steps.len) - spawn_result() - else - update_parent(steps.len) - -/datum/component/construction/unordered/update_parent(steps_left) - return - -/datum/component/construction/unordered/custom_action(obj/item/I, mob/living/user, typepath) - return TRUE diff --git a/code/datums/components/decal.dm b/code/datums/components/decal.dm deleted file mode 100644 index ec5465f31c6..00000000000 --- a/code/datums/components/decal.dm +++ /dev/null @@ -1,75 +0,0 @@ -/datum/component/decal - dupe_mode = COMPONENT_DUPE_ALLOWED - can_transfer = TRUE - var/cleanable - var/description - var/mutable_appearance/pic - - var/first_dir // This only stores the dir arg from init - -/datum/component/decal/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description, _alpha=255) - if(!isatom(parent) || !generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha)) - return COMPONENT_INCOMPATIBLE - first_dir = _dir - description = _description - cleanable = _cleanable - - apply() - -/datum/component/decal/RegisterWithParent() - if(first_dir) - RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, .proc/rotate_react) - if(cleanable) - RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react) - if(description) - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine) - -/datum/component/decal/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE)) - -/datum/component/decal/Destroy() - remove() - return ..() - -/datum/component/decal/PreTransfer() - remove() - -/datum/component/decal/PostTransfer() - remove() - apply() - -/datum/component/decal/proc/generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha) - if(!_icon || !_icon_state) - return FALSE - // It has to be made from an image or dir breaks because of a byond bug - var/temp_image = image(_icon, null, _icon_state, _layer, _dir) - pic = new(temp_image) - pic.color = _color - pic.alpha = _alpha - return TRUE - -/datum/component/decal/proc/apply(atom/thing) - var/atom/master = thing || parent - master.add_overlay(pic, TRUE) - if(isitem(master)) - addtimer(CALLBACK(master, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE) - -/datum/component/decal/proc/remove(atom/thing) - var/atom/master = thing || parent - master.cut_overlay(pic, TRUE) - if(isitem(master)) - addtimer(CALLBACK(master, /obj/item/.proc/update_slot_icon), 0, TIMER_UNIQUE) - -/datum/component/decal/proc/rotate_react(datum/source, old_dir, new_dir) - if(old_dir == new_dir) - return - remove() - pic.dir = turn(pic.dir, dir2angle(old_dir) - dir2angle(new_dir)) - apply() - -/datum/component/decal/proc/clean_react(datum/source, strength) - if(strength >= cleanable) - qdel(src) - -/datum/component/decal/proc/examine(datum/source, mob/user, list/examine_list) - examine_list += description diff --git a/code/datums/components/decals/blood.dm b/code/datums/components/decals/blood.dm deleted file mode 100644 index 3114ddb24e9..00000000000 --- a/code/datums/components/decals/blood.dm +++ /dev/null @@ -1,39 +0,0 @@ -/datum/component/decal/blood - dupe_mode = COMPONENT_DUPE_UNIQUE - -/datum/component/decal/blood/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_STRENGTH_BLOOD, _color, _layer=ABOVE_OBJ_LAYER) - if(!isitem(parent)) - return COMPONENT_INCOMPATIBLE - . = ..() - RegisterSignal(parent, COMSIG_ATOM_GET_EXAMINE_NAME, .proc/get_examine_name) - -/datum/component/decal/blood/generate_appearance(_icon, _icon_state, _dir, _layer, _color) - var/obj/item/I = parent - if(!_icon) - _icon = 'icons/effects/blood.dmi' - if(!_icon_state) - _icon_state = "itemblood" - var/icon = initial(I.icon) - var/icon_state = initial(I.icon_state) - if(!icon || !icon_state) - // It's something which takes on the look of other items, probably - icon = I.icon - icon_state = I.icon_state - var/static/list/blood_splatter_appearances = list() - //try to find a pre-processed blood-splatter. otherwise, make a new one - var/index = "[REF(icon)]-[icon_state]" - pic = blood_splatter_appearances[index] - - if(!pic) - var/icon/blood_splatter_icon = icon(initial(I.icon), initial(I.icon_state), , 1) //we only want to apply blood-splatters to the initial icon_state for each object - blood_splatter_icon.Blend("#fff", ICON_ADD) //fills the icon_state with white (except where it's transparent) - blood_splatter_icon.Blend(icon(_icon, _icon_state), ICON_MULTIPLY) //adds blood and the remaining white areas become transparant - pic = mutable_appearance(blood_splatter_icon, initial(I.icon_state)) - blood_splatter_appearances[index] = pic - return TRUE - -/datum/component/decal/blood/proc/get_examine_name(datum/source, mob/user, list/override) - var/atom/A = parent - override[EXAMINE_POSITION_ARTICLE] = A.gender == PLURAL? "some" : "a" - override[EXAMINE_POSITION_BEFORE] = " blood-stained " - return COMPONENT_EXNAME_CHANGED diff --git a/code/datums/components/earprotection.dm b/code/datums/components/earprotection.dm deleted file mode 100644 index 9256c4310a7..00000000000 --- a/code/datums/components/earprotection.dm +++ /dev/null @@ -1,11 +0,0 @@ -/datum/component/wearertargeting/earprotection - signals = list(COMSIG_CARBON_SOUNDBANG) - mobtype = /mob/living/carbon - proctype = .proc/reducebang - -/datum/component/wearertargeting/earprotection/Initialize(_valid_slots) - . = ..() - valid_slots = _valid_slots - -/datum/component/wearertargeting/earprotection/proc/reducebang(datum/source, list/reflist) - reflist[1]-- diff --git a/code/datums/components/edit_complainer.dm b/code/datums/components/edit_complainer.dm deleted file mode 100644 index e2cca2eb50c..00000000000 --- a/code/datums/components/edit_complainer.dm +++ /dev/null @@ -1,23 +0,0 @@ -// This is just a bit of fun while making an example for global signal -/datum/component/edit_complainer - var/list/say_lines - -/datum/component/edit_complainer/Initialize(list/text) - if(!ismovable(parent)) - return COMPONENT_INCOMPATIBLE - - var/static/list/default_lines = list( - "CentCom's profligacy frays another thread.", - "Another tug at the weave.", - "Who knows when the stresses will finally shatter the form?", - "Even now a light shines through the cracks.", - "CentCom once more twists knowledge beyond its authority.", - "There is an uncertain air in the mansus.", - ) - say_lines = text || default_lines - - RegisterSignal(SSdcs, COMSIG_GLOB_VAR_EDIT, .proc/var_edit_react) - -/datum/component/edit_complainer/proc/var_edit_react(datum/source, list/arguments) - var/atom/movable/master = parent - master.say(pick(say_lines)) diff --git a/code/datums/components/empprotection.dm b/code/datums/components/empprotection.dm deleted file mode 100644 index c85cdf31c72..00000000000 --- a/code/datums/components/empprotection.dm +++ /dev/null @@ -1,11 +0,0 @@ -/datum/component/empprotection - var/flags = NONE - -/datum/component/empprotection/Initialize(_flags) - if(!istype(parent, /atom)) - return COMPONENT_INCOMPATIBLE - flags = _flags - RegisterSignal(parent, list(COMSIG_ATOM_EMP_ACT), .proc/getEmpFlags) - -/datum/component/empprotection/proc/getEmpFlags(datum/source, severity) - return flags diff --git a/code/datums/components/explodable.dm b/code/datums/components/explodable.dm deleted file mode 100644 index f27fae30237..00000000000 --- a/code/datums/components/explodable.dm +++ /dev/null @@ -1,105 +0,0 @@ -///Component specifically for explosion sensetive things, currently only applies to heat based explosions but can later perhaps be used for things that are dangerous to handle carelessly like nitroglycerin. -/datum/component/explodable - var/devastation_range = 0 - var/heavy_impact_range = 0 - var/light_impact_range = 2 - var/flash_range = 3 - var/equipped_slot //For items, lets us determine where things should be hit. - -/datum/component/explodable/Initialize(devastation_range_override, heavy_impact_range_override, light_impact_range_override, flash_range_override) - if(!isatom(parent)) - return COMPONENT_INCOMPATIBLE - - RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/explodable_attack) - RegisterSignal(parent, COMSIG_TRY_STORAGE_INSERT, .proc/explodable_insert_item) - RegisterSignal(parent, COMSIG_ATOM_EX_ACT, .proc/detonate) - if(ismovable(parent)) - RegisterSignal(parent, COMSIG_MOVABLE_IMPACT, .proc/explodable_impact) - RegisterSignal(parent, COMSIG_MOVABLE_BUMP, .proc/explodable_bump) - if(isitem(parent)) - RegisterSignal(parent, list(COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_OBJ, COMSIG_ITEM_HIT_REACT), .proc/explodable_attack) - RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip) - RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop) - - - - if(devastation_range_override) - devastation_range = devastation_range_override - if(heavy_impact_range_override) - heavy_impact_range = heavy_impact_range_override - if(light_impact_range_override) - light_impact_range = light_impact_range_override - if(flash_range_override) - flash_range = flash_range_override - -/datum/component/explodable/proc/explodable_insert_item(datum/source, obj/item/I, mob/M, silent = FALSE, force = FALSE) - check_if_detonate(I) - -/datum/component/explodable/proc/explodable_impact(datum/source, atom/hit_atom, datum/thrownthing/throwingdatum) - check_if_detonate(hit_atom) - -/datum/component/explodable/proc/explodable_bump(datum/source, atom/A) - check_if_detonate(A) - -///Called when you use this object to attack sopmething -/datum/component/explodable/proc/explodable_attack(datum/source, atom/movable/target, mob/living/user) - check_if_detonate(target) - -///Called when you attack a specific body part of the thing this is equipped on. Useful for exploding pants. -/datum/component/explodable/proc/explodable_attack_zone(datum/source, damage, damagetype, def_zone) - if(!def_zone) - return - if(damagetype != BURN) //Don't bother if it's not fire. - return - if(!is_hitting_zone(def_zone)) //You didn't hit us! ha! - return - detonate() - -/datum/component/explodable/proc/on_equip(datum/source, mob/equipper, slot) - RegisterSignal(equipper, COMSIG_MOB_APPLY_DAMAGE, .proc/explodable_attack_zone) - -/datum/component/explodable/proc/on_drop(datum/source, mob/user) - UnregisterSignal(user, COMSIG_MOB_APPLY_DAMAGE) - -/// Checks if we're hitting the zone this component is covering -/datum/component/explodable/proc/is_hitting_zone(def_zone) - var/obj/item/item = parent - var/mob/living/L = item.loc //Get whoever is equipping the item currently - - if(!istype(L)) - return - - var/obj/item/bodypart/bodypart = L.get_bodypart(check_zone(def_zone)) - - var/list/equipment_items = list() - if(iscarbon(L)) - var/mob/living/carbon/C = L - equipment_items += list(C.head, C.wear_mask, C.back, C.gloves, C.shoes, C.glasses, C.ears) - if(ishuman(C)) - var/mob/living/carbon/human/H = C - equipment_items += list(H.wear_suit, H.w_uniform, H.belt, H.s_store, H.wear_id) - - for(var/bp in equipment_items) - if(!bp) - continue - - var/obj/item/I = bp - if(I.body_cover_flags & bodypart.body_part_flags) - return TRUE - return FALSE - - -/datum/component/explodable/proc/check_if_detonate(target) - if(!isitem(target)) - return - var/obj/item/I = target - if(!I.is_hot()) - return - detonate() //If we're touching a hot item we go boom - - -/// Expldoe and remove the object -/datum/component/explodable/proc/detonate() - var/atom/A = parent - explosion(A, devastation_range, heavy_impact_range, light_impact_range, flash_range) //epic explosion time - qdel(A) diff --git a/code/datums/components/fantasy/affix.dm b/code/datums/components/fantasy/affix.dm deleted file mode 100644 index ad1f44ce4d8..00000000000 --- a/code/datums/components/fantasy/affix.dm +++ /dev/null @@ -1,13 +0,0 @@ -/datum/fantasy_affix - var/placement // A bitflag of "slots" this affix takes up, for example pre/suffix - var/alignment - var/weight = 10 - -// For those occasional affixes which only make sense in certain circumstances -/datum/fantasy_affix/proc/validate(datum/component/fantasy/comp) - return TRUE - -/datum/fantasy_affix/proc/apply(datum/component/fantasy/comp, newName) - return newName - -/datum/fantasy_affix/proc/remove(datum/component/fantasy/comp) diff --git a/code/datums/components/fantasy/prefixes.dm b/code/datums/components/fantasy/prefixes.dm deleted file mode 100644 index 7445ab582bf..00000000000 --- a/code/datums/components/fantasy/prefixes.dm +++ /dev/null @@ -1,68 +0,0 @@ -/datum/fantasy_affix/cosmetic_prefixes - placement = AFFIX_PREFIX - alignment = AFFIX_GOOD | AFFIX_EVIL - - var/list/goodPrefixes - var/list/badPrefixes - -/datum/fantasy_affix/cosmetic_prefixes/New() - goodPrefixes = list( - "greater", - "major", - "blessed", - "superior", - "empowered", - "honed", - "true", - "glorious", - "robust", - ) - badPrefixes = list( - "lesser", - "minor", - "blighted", - "inferior", - "enfeebled", - "rusted", - "unsteady", - "tragic", - "gimped", - "cursed", - ) - - weight = (length(goodPrefixes) + length(badPrefixes)) * 10 - -/datum/fantasy_affix/cosmetic_prefixes/apply(datum/component/fantasy/comp, newName) - if(comp.quality > 0 || (comp.quality == 0 && prob(50))) - return "[pick(goodPrefixes)] [newName]" - else - return "[pick(badPrefixes)] [newName]" - -/datum/fantasy_affix/tactical - placement = AFFIX_PREFIX - alignment = AFFIX_GOOD - weight = 1 // Very powerful, no one should have such power - -/datum/fantasy_affix/tactical/apply(datum/component/fantasy/comp, newName) - var/obj/item/master = comp.parent - comp.appliedComponents += master.AddComponent(/datum/component/tactical) - return "tactical [newName]" - -/datum/fantasy_affix/pyromantic - placement = AFFIX_PREFIX - alignment = AFFIX_GOOD - -/datum/fantasy_affix/pyromantic/apply(datum/component/fantasy/comp, newName) - var/obj/item/master = comp.parent - comp.appliedComponents += master.AddComponent(/datum/component/igniter, clamp(comp.quality, 1, 10)) - return "pyromantic [newName]" - -/datum/fantasy_affix/vampiric - placement = AFFIX_PREFIX - alignment = AFFIX_GOOD - weight = 5 - -/datum/fantasy_affix/vampiric/apply(datum/component/fantasy/comp, newName) - var/obj/item/master = comp.parent - comp.appliedComponents += master.AddComponent(/datum/component/lifesteal, comp.quality) - return "vampiric [newName]" diff --git a/code/datums/components/fantasy/suffixes.dm b/code/datums/components/fantasy/suffixes.dm deleted file mode 100644 index 0dd37edb6f4..00000000000 --- a/code/datums/components/fantasy/suffixes.dm +++ /dev/null @@ -1,169 +0,0 @@ -/datum/fantasy_affix/cosmetic_suffixes - placement = AFFIX_SUFFIX - alignment = AFFIX_GOOD | AFFIX_EVIL - - var/list/goodSuffixes - var/list/badSuffixes - -/datum/fantasy_affix/cosmetic_suffixes/New() - goodSuffixes = list( - "dexterity", - "constitution", - "intelligence", - "wisdom", - "charisma", - "the forest", - "the hills", - "the plains", - "the sea", - "the sun", - "the moon", - "the void", - "the world", - "many secrets", - "many tales", - "many colors", - "rending", - "sundering", - "the night", - "the day", - ) - badSuffixes = list( - "draining", - "burden", - "discomfort", - "awkwardness", - "poor hygiene", - "timidity", - ) - - weight = (length(goodSuffixes) + length(badSuffixes)) * 10 - -/datum/fantasy_affix/cosmetic_suffixes/apply(datum/component/fantasy/comp, newName) - if(comp.quality > 0 || (comp.quality == 0 && prob(50))) - return "[newName] of [pick(goodSuffixes)]" - else - return "[newName] of [pick(badSuffixes)]" - -//////////// Good suffixes -/datum/fantasy_affix/bane - placement = AFFIX_SUFFIX - alignment = AFFIX_GOOD - -/datum/fantasy_affix/bane/apply(datum/component/fantasy/comp, newName) - . = ..() - // This is set up to be easy to add to these lists as I expect it will need modifications - var/static/list/possible_mobtypes - if(!possible_mobtypes) - // The base list of allowed mob/species types - possible_mobtypes = typecacheof(list( - /mob/living/simple_animal, - /mob/living/carbon, - /datum/species, - )) - // Some particular types to disallow if they're too broad/abstract - possible_mobtypes -= list( - /mob/living/simple_animal/hostile, - ) - // Some types to remove them and their subtypes - possible_mobtypes -= typecacheof(list( - /mob/living/carbon/human/species, - )) - - var/mob/picked_mobtype = pick(possible_mobtypes) - // This works even with the species picks since we're only accessing the name - - var/obj/item/master = comp.parent - comp.appliedComponents += master.AddComponent(/datum/component/bane, picked_mobtype) - return "[newName] of [initial(picked_mobtype.name)] slaying" - -/datum/fantasy_affix/summoning - placement = AFFIX_SUFFIX - alignment = AFFIX_GOOD - weight = 5 - -/datum/fantasy_affix/summoning/apply(datum/component/fantasy/comp, newName) - . = ..() - // This is set up to be easy to add to these lists as I expect it will need modifications - var/static/list/possible_mobtypes - if(!possible_mobtypes) - // The base list of allowed mob/species types - possible_mobtypes = typecacheof(list( - /mob/living/simple_animal, - /mob/living/carbon, - /datum/species, - )) - // Some particular types to disallow if they're too broad/abstract - possible_mobtypes -= list( - /mob/living/simple_animal/hostile, - ) - // Some types to remove them and their subtypes - possible_mobtypes -= typecacheof(list( - /mob/living/carbon/human/species, - /mob/living/simple_animal/hostile/megafauna, - )) - - var/mob/picked_mobtype = pick(possible_mobtypes) - // This works even with the species picks since we're only accessing the name - - var/obj/item/master = comp.parent - var/max_mobs = max(CEILING(comp.quality/2, 1), 1) - var/spawn_delay = 300 - 30 * comp.quality - comp.appliedComponents += master.AddComponent(/datum/component/summoning, list(picked_mobtype), 100, max_mobs, spawn_delay) - return "[newName] of [initial(picked_mobtype.name)] summoning" - -/datum/fantasy_affix/shrapnel - placement = AFFIX_SUFFIX - alignment = AFFIX_GOOD - -/datum/fantasy_affix/shrapnel/validate(datum/component/fantasy/comp) - if(isgun(comp.parent)) - return TRUE - return FALSE - -/datum/fantasy_affix/shrapnel/apply(datum/component/fantasy/comp, newName) - . = ..() - // higher means more likely - var/list/weighted_projectile_types = list(/obj/projectile/meteor = 1, - /obj/projectile/energy/nuclear_particle = 1, - /obj/projectile/beam/pulse = 1, - /obj/projectile/bullet/honker = 15, - /obj/projectile/temp = 15, - /obj/projectile/ion = 15, - /obj/projectile/magic/door = 15, - /obj/projectile/magic/locker = 15, - /obj/projectile/magic/fetch = 15, - /obj/projectile/beam/emitter = 15, - /obj/projectile/magic/flying = 15, - /obj/projectile/energy/net = 15, - /obj/projectile/bullet/incendiary/c9mm = 15, - /obj/projectile/temp/hot = 15, - /obj/projectile/beam/disabler = 15) - - var/obj/projectile/picked_projectiletype = pickweight(weighted_projectile_types) - - var/obj/item/master = comp.parent - comp.appliedComponents += master.AddComponent(/datum/component/shrapnel, picked_projectiletype) - return "[newName] of [initial(picked_projectiletype.name)] shrapnel" - -/datum/fantasy_affix/strength - placement = AFFIX_SUFFIX - alignment = AFFIX_GOOD - -/datum/fantasy_affix/strength/apply(datum/component/fantasy/comp, newName) - . = ..() - var/obj/item/master = comp.parent - comp.appliedComponents += master.AddComponent(/datum/component/knockback, CEILING(comp.quality/2, 1), FLOOR(comp.quality/10, 1)) - return "[newName] of strength" - -//////////// Bad suffixes - -/datum/fantasy_affix/fool - placement = AFFIX_SUFFIX - alignment = AFFIX_EVIL - -/datum/fantasy_affix/fool/apply(datum/component/fantasy/comp, newName) - . = ..() - var/obj/item/master = comp.parent - comp.appliedComponents += master.AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 50) - return "[newName] of the fool" diff --git a/code/datums/components/forced_gravity.dm b/code/datums/components/forced_gravity.dm deleted file mode 100644 index fe9cfc861b3..00000000000 --- a/code/datums/components/forced_gravity.dm +++ /dev/null @@ -1,20 +0,0 @@ -/datum/component/forced_gravity - var/gravity - var/ignore_space = FALSE //If forced gravity should also work on space turfs - -/datum/component/forced_gravity/Initialize(forced_value = 1) - if(!isatom(parent)) - return COMPONENT_INCOMPATIBLE - RegisterSignal(parent, COMSIG_ATOM_HAS_GRAVITY, .proc/gravity_check) - if(isturf(parent)) - RegisterSignal(parent, COMSIG_TURF_HAS_GRAVITY, .proc/turf_gravity_check) - - gravity = forced_value - -/datum/component/forced_gravity/proc/gravity_check(datum/source, turf/location, list/gravs) - if(!ignore_space && isspaceturf(location)) - return - gravs += gravity - -/datum/component/forced_gravity/proc/turf_gravity_check(datum/source, atom/checker, list/gravs) - return gravity_check(null, parent, gravs) diff --git a/code/datums/components/forensics.dm b/code/datums/components/forensics.dm deleted file mode 100644 index ff8d4e3ddfc..00000000000 --- a/code/datums/components/forensics.dm +++ /dev/null @@ -1,184 +0,0 @@ -/datum/component/forensics - dupe_mode = COMPONENT_DUPE_UNIQUE - can_transfer = TRUE - var/list/fingerprints //assoc print = print - var/list/hiddenprints //assoc ckey = realname/gloves/ckey - var/list/blood_DNA //assoc dna = bloodtype - var/list/fibers //assoc print = print - -/datum/component/forensics/InheritComponent(datum/component/forensics/F, original) //Use of | and |= being different here is INTENTIONAL. - fingerprints = fingerprints | F.fingerprints - hiddenprints = hiddenprints | F.hiddenprints - blood_DNA = blood_DNA | F.blood_DNA - fibers = fibers | F.fibers - check_blood() - return ..() - -/datum/component/forensics/Initialize(new_fingerprints, new_hiddenprints, new_blood_DNA, new_fibers) - if(!isatom(parent)) - return COMPONENT_INCOMPATIBLE - fingerprints = new_fingerprints - hiddenprints = new_hiddenprints - blood_DNA = new_blood_DNA - fibers = new_fibers - check_blood() - -/datum/component/forensics/RegisterWithParent() - check_blood() - RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_act) - -/datum/component/forensics/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_COMPONENT_CLEAN_ACT)) - -/datum/component/forensics/PostTransfer() - if(!isatom(parent)) - return COMPONENT_INCOMPATIBLE - -/datum/component/forensics/proc/wipe_fingerprints() - fingerprints = null - return TRUE - -/datum/component/forensics/proc/wipe_hiddenprints() - return //no. - -/datum/component/forensics/proc/wipe_blood_DNA() - blood_DNA = null - if(isitem(parent)) - qdel(parent.GetComponent(/datum/component/decal/blood)) - return TRUE - -/datum/component/forensics/proc/wipe_fibers() - fibers = null - return TRUE - -/datum/component/forensics/proc/clean_act(datum/source, strength) - if(strength >= CLEAN_STRENGTH_FINGERPRINTS) - wipe_fingerprints() - if(strength >= CLEAN_STRENGTH_BLOOD) - wipe_blood_DNA() - if(strength >= CLEAN_STRENGTH_FIBERS) - wipe_fibers() - -/datum/component/forensics/proc/add_fingerprint_list(list/_fingerprints) //list(text) - if(!length(_fingerprints)) - return - LAZYINITLIST(fingerprints) - for(var/i in _fingerprints) //We use an associative list, make sure we don't just merge a non-associative list into ours. - fingerprints[i] = i - return TRUE - -/datum/component/forensics/proc/add_fingerprint(mob/living/M, ignoregloves = FALSE) - if(!isliving(M)) - if(!iscameramob(M)) - return - if(isaicamera(M)) - var/mob/camera/aiEye/ai_camera = M - if(!ai_camera.ai) - return - M = ai_camera.ai - add_hiddenprint(M) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - add_fibers(H) - if(H.gloves) //Check if the gloves (if any) hide fingerprints - var/obj/item/clothing/gloves/G = H.gloves - if(G.transfer_prints) - ignoregloves = TRUE - if(!ignoregloves) - H.gloves.add_fingerprint(H, TRUE) //ignoregloves = 1 to avoid infinite loop. - return - var/full_print = md5(H.dna.uni_identity) - LAZYSET(fingerprints, full_print, full_print) - return TRUE - -/datum/component/forensics/proc/add_fiber_list(list/_fibertext) //list(text) - if(!length(_fibertext)) - return - LAZYINITLIST(fibers) - for(var/i in _fibertext) //We use an associative list, make sure we don't just merge a non-associative list into ours. - fibers[i] = i - return TRUE - -/datum/component/forensics/proc/add_fibers(mob/living/carbon/human/M) - var/fibertext - var/item_multiplier = isitem(src)?1.2:1 - if(M.wear_suit) - fibertext = "Material from \a [M.wear_suit]." - if(prob(10*item_multiplier) && !LAZYACCESS(fibers, fibertext)) - LAZYSET(fibers, fibertext, fibertext) - if(!(M.wear_suit.body_cover_flags & CHEST)) - if(M.w_uniform) - fibertext = "Fibers from \a [M.w_uniform]." - if(prob(12*item_multiplier) && !LAZYACCESS(fibers, fibertext)) //Wearing a suit means less of the uniform exposed. - LAZYSET(fibers, fibertext, fibertext) - if(!(M.wear_suit.body_cover_flags & HANDS)) - if(M.gloves) - fibertext = "Material from a pair of [M.gloves.name]." - if(prob(20*item_multiplier) && !LAZYACCESS(fibers, fibertext)) - LAZYSET(fibers, fibertext, fibertext) - else if(M.w_uniform) - fibertext = "Fibers from \a [M.w_uniform]." - if(prob(15*item_multiplier) && !LAZYACCESS(fibers, fibertext)) - // "Added fibertext: [fibertext]" - LAZYSET(fibers, fibertext, fibertext) - if(M.gloves) - fibertext = "Material from a pair of [M.gloves.name]." - if(prob(20*item_multiplier) && !LAZYACCESS(fibers, fibertext)) - LAZYSET(fibers, fibertext, fibertext) - else if(M.gloves) - fibertext = "Material from a pair of [M.gloves.name]." - if(prob(20*item_multiplier) && !LAZYACCESS(fibers, fibertext)) - LAZYSET(fibers, fibertext, fibertext) - return TRUE - -/datum/component/forensics/proc/add_hiddenprint_list(list/_hiddenprints) //list(ckey = text) - if(!length(_hiddenprints)) - return - LAZYINITLIST(hiddenprints) - for(var/i in _hiddenprints) //We use an associative list, make sure we don't just merge a non-associative list into ours. - hiddenprints[i] = _hiddenprints[i] - return TRUE - -/datum/component/forensics/proc/add_hiddenprint(mob/M) - if(!isliving(M)) - if(!iscameramob(M)) - return - if(isaicamera(M)) - var/mob/camera/aiEye/ai_camera = M - if(!ai_camera.ai) - return - M = ai_camera.ai - if(!M.key) - return - var/hasgloves = "" - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H.gloves) - hasgloves = "(gloves)" - var/current_time = time_stamp() - if(!LAZYACCESS(hiddenprints, M.key)) - LAZYSET(hiddenprints, M.key, "First: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]") - else - var/laststamppos = findtext(LAZYACCESS(hiddenprints, M.key), " Last: ") - if(laststamppos) - LAZYSET(hiddenprints, M.key, copytext(hiddenprints[M.key], 1, laststamppos)) - hiddenprints[M.key] += " Last: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]" //made sure to be existing by if(!LAZYACCESS);else - var/atom/A = parent - A.fingerprintslast = M.ckey - return TRUE - -/datum/component/forensics/proc/add_blood_DNA(list/dna) //list(dna_enzymes = type) - if(!length(dna)) - return - LAZYINITLIST(blood_DNA) - for(var/i in dna) - blood_DNA[i] = dna[i] - check_blood() - return TRUE - -/datum/component/forensics/proc/check_blood() - if(!isitem(parent)) - return - if(!length(blood_DNA)) - return - parent.LoadComponent(/datum/component/decal/blood) diff --git a/code/datums/components/heirloom.dm b/code/datums/components/heirloom.dm deleted file mode 100644 index 72b28b125dd..00000000000 --- a/code/datums/components/heirloom.dm +++ /dev/null @@ -1,22 +0,0 @@ -/datum/component/heirloom - var/datum/mind/owner - var/family_name - -/datum/component/heirloom/Initialize(new_owner, new_family_name) - if(!isitem(parent)) - return COMPONENT_INCOMPATIBLE - - owner = new_owner - family_name = new_family_name - - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine) - -/datum/component/heirloom/proc/examine(datum/source, mob/user, list/examine_list) - if(user.mind == owner) - examine_list += "It is your precious [family_name] family heirloom. Keep it safe!" - else if(isobserver(user)) - examine_list += "It is the [family_name] family heirloom, belonging to [owner]." - else - var/datum/antagonist/obsessed/creeper = user.mind.has_antag_datum(/datum/antagonist/obsessed) - if(creeper && creeper.trauma.obsession == owner) - examine_list += "This must be [owner]'s family heirloom! It smells just like them..." diff --git a/code/datums/components/igniter.dm b/code/datums/components/igniter.dm deleted file mode 100644 index a254a7729bf..00000000000 --- a/code/datums/components/igniter.dm +++ /dev/null @@ -1,36 +0,0 @@ -/datum/component/igniter - var/fire_stacks - -/datum/component/igniter/Initialize(fire_stacks=1) - if(!isitem(parent) && !ishostile(parent) && !isgun(parent) && !ismachinery(parent) && !isstructure(parent)) - return COMPONENT_INCOMPATIBLE - - src.fire_stacks = fire_stacks - -/datum/component/igniter/RegisterWithParent() - if(ismachinery(parent) || isstructure(parent) || isgun(parent)) // turrets, etc - RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit) - else if(isitem(parent)) - RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/item_afterattack) - else if(ishostile(parent)) - RegisterSignal(parent, COMSIG_HOSTILE_ATTACKINGTARGET, .proc/hostile_attackingtarget) - -/datum/component/igniter/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_ATTACKINGTARGET, COMSIG_PROJECTILE_ON_HIT)) - -/datum/component/igniter/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters) - if(!(clickchain_flags & CLICKCHAIN_HAS_PROXIMITY)) - return - do_igniter(target) - -/datum/component/igniter/proc/hostile_attackingtarget(mob/living/simple_animal/hostile/attacker, atom/target) - do_igniter(target) - -/datum/component/igniter/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle) - do_igniter(target) - -/datum/component/igniter/proc/do_igniter(atom/target) - if(isliving(target)) - var/mob/living/L = target - L.adjust_fire_stacks(fire_stacks) - L.IgniteMob() diff --git a/code/datums/components/infective.dm b/code/datums/components/infective.dm deleted file mode 100644 index 314e381bfe6..00000000000 --- a/code/datums/components/infective.dm +++ /dev/null @@ -1,88 +0,0 @@ -/datum/component/infective - dupe_mode = COMPONENT_DUPE_ALLOWED - var/list/datum/disease/diseases //make sure these are the static, non-processing versions! - var/expire_time - var/min_clean_strength = CLEAN_WEAK - -/datum/component/infective/Initialize(list/datum/disease/_diseases, expire_in) - if(islist(_diseases)) - diseases = _diseases - else - diseases = list(_diseases) - if(expire_in) - expire_time = world.time + expire_in - QDEL_IN(src, expire_in) - - if(!ismovable(parent)) - return COMPONENT_INCOMPATIBLE - RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean) - RegisterSignal(parent, COMSIG_MOVABLE_BUCKLE, .proc/try_infect_buckle) - RegisterSignal(parent, COMSIG_MOVABLE_BUMP, .proc/try_infect_collide) - RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/try_infect_crossed) - RegisterSignal(parent, COMSIG_MOVABLE_IMPACT_ZONE, .proc/try_infect_impact_zone) - if(isitem(parent)) - RegisterSignal(parent, COMSIG_ITEM_ATTACK_ZONE, .proc/try_infect_attack_zone) - RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/try_infect_attack) - RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/try_infect_equipped) - if(istype(parent, /obj/item/reagent_containers/food/snacks)) - RegisterSignal(parent, COMSIG_FOOD_EATEN, .proc/try_infect_eat) - else if(istype(parent, /obj/effect/debris/cleanable/blood/gibs)) - RegisterSignal(parent, COMSIG_GIBS_STREAK, .proc/try_infect_streak) - -/datum/component/infective/proc/try_infect_eat(datum/source, mob/living/eater, mob/living/feeder) - for(var/V in diseases) - eater.ForceContractDisease(V) - try_infect(feeder, BODY_ZONE_L_ARM) - -/datum/component/infective/proc/clean(datum/source, clean_strength) - if(clean_strength >= min_clean_strength) - qdel(src) - -/datum/component/infective/proc/try_infect_buckle(datum/source, mob/M, force) - if(isliving(M)) - try_infect(M) - -/datum/component/infective/proc/try_infect_collide(datum/source, atom/A) - var/atom/movable/P = parent - if(P.throwing) - //this will be handled by try_infect_impact_zone() - return - if(isliving(A)) - try_infect(A) - -/datum/component/infective/proc/try_infect_impact_zone(datum/source, mob/living/target, hit_zone) - try_infect(target, hit_zone) - -/datum/component/infective/proc/try_infect_attack_zone(datum/source, mob/living/carbon/target, mob/living/user, hit_zone) - try_infect(user, BODY_ZONE_L_ARM) - try_infect(target, hit_zone) - -/datum/component/infective/proc/try_infect_attack(datum/source, mob/living/target, mob/living/user) - if(!iscarbon(target)) //this case will be handled by try_infect_attack_zone - try_infect(target) - try_infect(user, BODY_ZONE_L_ARM) - -/datum/component/infective/proc/try_infect_equipped(datum/source, mob/living/L, slot) - var/old_permeability - if(isitem(parent)) - //if you are putting an infective item on, it obviously will not protect you, so set its permeability high enough that it will never block ContactContractDisease() - var/obj/item/I = parent - old_permeability = I.permeability_coefficient - I.permeability_coefficient = 1.01 - - try_infect(L, slot2body_zone(slot)) - - if(isitem(parent)) - var/obj/item/I = parent - I.permeability_coefficient = old_permeability - -/datum/component/infective/proc/try_infect_crossed(datum/source, atom/movable/M) - if(isliving(M)) - try_infect(M, BODY_ZONE_PRECISE_L_FOOT) - -/datum/component/infective/proc/try_infect_streak(datum/source, list/directions, list/output_diseases) - output_diseases |= diseases - -/datum/component/infective/proc/try_infect(mob/living/L, target_zone) - for(var/V in diseases) - L.ContactContractDisease(V, target_zone) diff --git a/code/datums/components/knockback.dm b/code/datums/components/knockback.dm deleted file mode 100644 index 7d5d5fe23ea..00000000000 --- a/code/datums/components/knockback.dm +++ /dev/null @@ -1,44 +0,0 @@ -/datum/component/knockback - var/throw_distance - var/throw_anchored - -/datum/component/knockback/Initialize(throw_distance=1, throw_anchored=FALSE) - if(!isitem(parent) && !ishostile(parent) && !isgun(parent) && !ismachinery(parent) && !isstructure(parent)) - return COMPONENT_INCOMPATIBLE - - src.throw_distance = throw_distance - src.throw_anchored = throw_anchored - -/datum/component/knockback/RegisterWithParent() - if(ismachinery(parent) || isstructure(parent) || isgun(parent)) // turrets, etc - RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit) - else if(isitem(parent)) - RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/item_afterattack) - else if(ishostile(parent)) - RegisterSignal(parent, COMSIG_HOSTILE_ATTACKINGTARGET, .proc/hostile_attackingtarget) - -/datum/component/knockback/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_ATTACKINGTARGET, COMSIG_PROJECTILE_ON_HIT)) - -/datum/component/knockback/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters) - if(!(clickchain_flags & CLICKCHAIN_HAS_PROXIMITY)) - return - do_knockback(target, user, get_dir(source, target)) - -/datum/component/knockback/proc/hostile_attackingtarget(mob/living/simple_animal/hostile/attacker, atom/target) - do_knockback(target, attacker, get_dir(attacker, target)) - -/datum/component/knockback/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle) - do_knockback(target, null, angle2dir(Angle)) - -/datum/component/knockback/proc/do_knockback(atom/target, mob/thrower, throw_dir) - if(!ismovable(target) || throw_dir == null) - return - var/atom/movable/throwee = target - if(throwee.anchored && !throw_anchored) - return - if(throw_distance < 0) - throw_dir = turn(throw_dir, 180) - throw_distance *= -1 - var/atom/throw_target = get_edge_target_turf(throwee, throw_dir) - throwee.safe_throw_at(throw_target, throw_distance, 1, thrower) diff --git a/code/datums/components/knockoff.dm b/code/datums/components/knockoff.dm deleted file mode 100644 index 7d399c7d26d..00000000000 --- a/code/datums/components/knockoff.dm +++ /dev/null @@ -1,44 +0,0 @@ -//Items with these will have a chance to get knocked off when disarming -/datum/component/knockoff - var/knockoff_chance = 100 //Chance to knockoff - var/list/target_zones //Aiming for these zones will cause the knockoff, null means all zones allowed - var/list/slots_knockoffable //Can be only knocked off from these slots, null means all slots allowed - -/datum/component/knockoff/Initialize(knockoff_chance,zone_override,slots_knockoffable) - if(!isitem(parent)) - return COMPONENT_INCOMPATIBLE - RegisterSignal(parent, COMSIG_ITEM_EQUIPPED,.proc/OnEquipped) - RegisterSignal(parent, COMSIG_ITEM_DROPPED,.proc/OnDropped) - - src.knockoff_chance = knockoff_chance - - if(zone_override) - target_zones = zone_override - - if(slots_knockoffable) - src.slots_knockoffable = slots_knockoffable - -/datum/component/knockoff/proc/Knockoff(mob/living/attacker,zone) - var/obj/item/I = parent - var/mob/living/carbon/human/wearer = I.loc - if(!istype(wearer)) - return - if(target_zones && !(zone in target_zones)) - return - if(!prob(knockoff_chance)) - return - if(!wearer.dropItemToGround(I)) - return - - wearer.visible_message("[attacker] knocks off [wearer]'s [I.name]!","[attacker] knocks off your [I.name]!") - -/datum/component/knockoff/proc/OnEquipped(datum/source, mob/living/carbon/human/H,slot) - if(!istype(H)) - return - if(slots_knockoffable && !(slot in slots_knockoffable)) - UnregisterSignal(H, COMSIG_HUMAN_DISARM_HIT) - return - RegisterSignal(H, COMSIG_HUMAN_DISARM_HIT, .proc/Knockoff, TRUE) - -/datum/component/knockoff/proc/OnDropped(datum/source, mob/living/M) - UnregisterSignal(M, COMSIG_HUMAN_DISARM_HIT) diff --git a/code/datums/components/lifesteal.dm b/code/datums/components/lifesteal.dm deleted file mode 100644 index 40422d1e561..00000000000 --- a/code/datums/components/lifesteal.dm +++ /dev/null @@ -1,38 +0,0 @@ -/datum/component/lifesteal - var/flat_heal // heals a constant amount every time a hit occurs - var/static/list/damage_heal_order = list(BRUTE, BURN, OXY) - -/datum/component/lifesteal/Initialize(flat_heal=0) - if(!isitem(parent) && !ishostile(parent) && !isgun(parent)) - return COMPONENT_INCOMPATIBLE - - src.flat_heal = flat_heal - -/datum/component/lifesteal/RegisterWithParent() - if(isgun(parent)) - RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit) - else if(isitem(parent)) - RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/item_afterattack) - else if(ishostile(parent)) - RegisterSignal(parent, COMSIG_HOSTILE_ATTACKINGTARGET, .proc/hostile_attackingtarget) - -/datum/component/lifesteal/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_ATTACKINGTARGET, COMSIG_PROJECTILE_ON_HIT)) - -/datum/component/lifesteal/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters) - if(!(clickchain_flags & CLICKCHAIN_HAS_PROXIMITY)) - return - do_lifesteal(user, target) - -/datum/component/lifesteal/proc/hostile_attackingtarget(mob/living/simple_animal/hostile/attacker, atom/target) - do_lifesteal(attacker, target) - -/datum/component/lifesteal/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle) - do_lifesteal(firer, target) - -/datum/component/lifesteal/proc/do_lifesteal(atom/heal_target, atom/damage_target) - if(isliving(heal_target) && isliving(damage_target)) - var/mob/living/healing = heal_target - var/mob/living/damaging = damage_target - if(damaging.stat != DEAD) - healing.heal_ordered_damage(flat_heal, damage_heal_order) diff --git a/code/datums/components/lockon_aiming.dm b/code/datums/components/lockon_aiming.dm deleted file mode 100644 index 35dc8654bd6..00000000000 --- a/code/datums/components/lockon_aiming.dm +++ /dev/null @@ -1,214 +0,0 @@ -#define LOCKON_AIMING_MAX_CURSOR_RADIUS 7 -#define LOCKON_IGNORE_RESULT "ignore_my_result" -#define LOCKON_RANGING_BREAK_CHECK if(current_ranging_id != this_id){return LOCKON_IGNORE_RESULT} - -/datum/component/lockon_aiming - dupe_mode = COMPONENT_DUPE_ALLOWED - var/lock_icon = 'icons/mob/cameramob.dmi' - var/lock_icon_state = "marker" - var/mutable_appearance/lock_appearance - var/list/image/lock_images - var/list/target_typecache - var/list/immune_weakrefs //list(weakref = TRUE) - var/mob_stat_check = TRUE //if a potential target is a mob make sure it's conscious! - var/lock_amount = 1 - var/lock_cursor_range = 5 - var/list/locked_weakrefs - var/update_disabled = FALSE - var/current_ranging_id = 0 - var/list/last_location - var/datum/callback/on_lock - var/datum/callback/can_target_callback - -/datum/component/lockon_aiming/Initialize(range, list/typecache, amount, list/immune, datum/callback/when_locked, icon, icon_state, datum/callback/target_callback) - if(!ismob(parent)) - return COMPONENT_INCOMPATIBLE - if(target_callback) - can_target_callback = target_callback - else - can_target_callback = CALLBACK(src, .proc/can_target) - if(range) - lock_cursor_range = range - if(typecache) - target_typecache = typecache - if(amount) - lock_amount = amount - immune_weakrefs = list(WEAKREF(parent) = TRUE) //Manually take this out if you want.. - if(immune) - for(var/i in immune) - if(isweakref(i)) - immune_weakrefs[i] = TRUE - else if(isatom(i)) - immune_weakrefs[WEAKREF(i)] = TRUE - if(when_locked) - on_lock = when_locked - if(icon) - lock_icon = icon - if(icon_state) - lock_icon_state = icon_state - generate_lock_visuals() - START_PROCESSING(SSfastprocess, src) - -/datum/component/lockon_aiming/Destroy() - clear_visuals() - STOP_PROCESSING(SSfastprocess, src) - return ..() - -/datum/component/lockon_aiming/proc/show_visuals() - LAZYINITLIST(lock_images) - var/mob/M = parent - if(!M.client) - return - for(var/i in locked_weakrefs) - var/datum/weakref/R = i - var/atom/A = R.resolve() - if(!A) - continue //It'll be cleared by processing. - var/image/I = new - I.appearance = lock_appearance - I.loc = A - M.client.images |= I - lock_images |= I - -/datum/component/lockon_aiming/proc/clear_visuals() - var/mob/M = parent - if(!M.client) - return - if(!lock_images) - return - for(var/i in lock_images) - M.client.images -= i - qdel(i) - lock_images.Cut() - -/datum/component/lockon_aiming/proc/refresh_visuals() - clear_visuals() - show_visuals() - -/datum/component/lockon_aiming/proc/generate_lock_visuals() - lock_appearance = mutable_appearance(icon = lock_icon, icon_state = lock_icon_state, layer = FLOAT_LAYER) - -/datum/component/lockon_aiming/proc/unlock_all(refresh_vis = TRUE) - LAZYCLEARLIST(locked_weakrefs) - if(refresh_vis) - refresh_visuals() - -/datum/component/lockon_aiming/proc/unlock(atom/A, refresh_vis = TRUE) - if(!A.weak_reference) - return - LAZYREMOVE(locked_weakrefs, A.weak_reference) - if(refresh_vis) - refresh_visuals() - -/datum/component/lockon_aiming/proc/lock(atom/A, refresh_vis = TRUE) - LAZYDISTINCTADD(locked_weakrefs, WEAKREF(A)) - if(refresh_vis) - refresh_visuals() - -/datum/component/lockon_aiming/proc/add_immune_atom(atom/A) - var/datum/weakref/R = WEAKREF(A) - if(immune_weakrefs && (immune_weakrefs[R])) - return - LAZYSET(immune_weakrefs, R, TRUE) - -/datum/component/lockon_aiming/proc/remove_immune_atom(atom/A) - if(!A.weak_reference || !immune_weakrefs) //if A doesn't have a weakref how did it get on the immunity list? - return - LAZYREMOVE(immune_weakrefs, A.weak_reference) - -/datum/component/lockon_aiming/process(delta_time) - if(update_disabled) - return - if(!last_location) - return - var/changed = FALSE - for(var/i in locked_weakrefs) - var/datum/weakref/R = i - if(istype(R)) - var/atom/thing = R.resolve() - if(!istype(thing) || (get_dist(thing, locate(last_location[1], last_location[2], last_location[3])) > lock_cursor_range)) - unlock(R) - changed = TRUE - else - unlock(R) - changed = TRUE - if(changed) - autolock() - -/datum/component/lockon_aiming/proc/autolock() - var/mob/M = parent - if(!M.client) - return FALSE - var/datum/position/current = mouse_absolute_datum_map_position_from_client(M.client) - var/turf/target = current.return_turf() - var/list/atom/targets = get_nearest(target, target_typecache, lock_amount, lock_cursor_range) - if(targets == LOCKON_IGNORE_RESULT) - return - unlock_all(FALSE) - for(var/i in targets) - if(immune_weakrefs[WEAKREF(i)]) - continue - lock(i, FALSE) - refresh_visuals() - on_lock.Invoke(locked_weakrefs) - -/datum/component/lockon_aiming/proc/can_target(atom/A) - var/mob/M = A - return is_type_in_typecache(A, target_typecache) && !(ismob(A) && mob_stat_check && M.stat != CONSCIOUS) && !immune_weakrefs[WEAKREF(A)] - -/datum/component/lockon_aiming/proc/get_nearest(turf/T, list/typecache, amount, range) - current_ranging_id++ - var/this_id = current_ranging_id - var/list/L = list() - var/turf/center = get_turf(T) - if(amount < 1 || range < 0 || !istype(center) || !islist(typecache)) - return - if(range == 0) - return typecache_filter_list(T.contents + T, typecache) - var/x = 0 - var/y = 0 - var/cd = 0 - while(cd <= range) - x = center.x - cd + 1 - y = center.y + cd - LOCKON_RANGING_BREAK_CHECK - for(x in x to center.x + cd) - T = locate(x, y, center.z) - if(T) - L |= special_list_filter(T.contents, can_target_callback) - if(L.len >= amount) - L.Cut(amount+1) - return L - LOCKON_RANGING_BREAK_CHECK - y = center.y + cd - 1 - x = center.x + cd - for(y in center.y - cd to y) - T = locate(x, y, center.z) - if(T) - L |= special_list_filter(T.contents, can_target_callback) - if(L.len >= amount) - L.Cut(amount+1) - return L - LOCKON_RANGING_BREAK_CHECK - y = center.y - cd - x = center.x + cd - 1 - for(x in center.x - cd to x) - T = locate(x, y, center.z) - if(T) - L |= special_list_filter(T.contents, can_target_callback) - if(L.len >= amount) - L.Cut(amount+1) - return L - LOCKON_RANGING_BREAK_CHECK - y = center.y - cd + 1 - x = center.x - cd - for(y in y to center.y + cd) - T = locate(x, y, center.z) - if(T) - L |= special_list_filter(T.contents, can_target_callback) - if(L.len >= amount) - L.Cut(amount+1) - return L - LOCKON_RANGING_BREAK_CHECK - cd++ - CHECK_TICK diff --git a/code/datums/components/magnetic_catch.dm b/code/datums/components/magnetic_catch.dm deleted file mode 100644 index 20cd8e1d78f..00000000000 --- a/code/datums/components/magnetic_catch.dm +++ /dev/null @@ -1,34 +0,0 @@ -/datum/component/magnetic_catch/Initialize() - if(!isatom(parent)) - return COMPONENT_INCOMPATIBLE - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine) - if(ismovable(parent)) - RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/crossed_react) - RegisterSignal(parent, COMSIG_MOVABLE_UNCROSSED, .proc/uncrossed_react) - for(var/i in get_turf(parent)) - if(i == parent) - continue - RegisterSignal(i, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react) - else - RegisterSignal(parent, COMSIG_ATOM_ENTERED, .proc/entered_react) - RegisterSignal(parent, COMSIG_ATOM_EXITED, .proc/exited_react) - for(var/i in parent) - RegisterSignal(i, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react) - -/datum/component/magnetic_catch/proc/examine(datum/source, mob/user, list/examine_list) - examine_list += "It has been installed with inertia dampening to prevent coffee spills." - -/datum/component/magnetic_catch/proc/crossed_react(datum/source, atom/movable/thing) - RegisterSignal(thing, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react, TRUE) - -/datum/component/magnetic_catch/proc/uncrossed_react(datum/source, atom/movable/thing) - UnregisterSignal(thing, COMSIG_MOVABLE_PRE_THROW) - -/datum/component/magnetic_catch/proc/entered_react(datum/source, atom/movable/thing, atom/oldloc) - RegisterSignal(thing, COMSIG_MOVABLE_PRE_THROW, .proc/throw_react, TRUE) - -/datum/component/magnetic_catch/proc/exited_react(datum/source, atom/movable/thing, atom/newloc) - UnregisterSignal(thing, COMSIG_MOVABLE_PRE_THROW) - -/datum/component/magnetic_catch/proc/throw_react(datum/source, list/arguments) - return COMPONENT_CANCEL_THROW diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm deleted file mode 100644 index 294c360ad37..00000000000 --- a/code/datums/components/material_container.dm +++ /dev/null @@ -1,352 +0,0 @@ -/** - *! This datum should be used for handling mineral contents of machines and whatever else is supposed to hold minerals and make use of them. - * - ** Variables: - ** - amount - Raw amount of the mineral this container is holding, calculated by the defined value MINERAL_MATERIAL_AMOUNT=2000. - ** - max_amount - Max raw amount of mineral this container can hold. - ** - sheet_type - Type of the mineral sheet the container handles, used for output. - ** - parent - Object that this container is being used by, used for output. - ** - MAX_STACK_SIZE - Size of a stack of mineral sheets. Constant. - */ - -/datum/component/material_container - var/total_amount = 0 - var/max_amount - var/sheet_type - var/list/materials //Map of key = material ref | Value = amount - var/show_on_examine - var/disable_attackby - var/list/allowed_typecache - var/last_inserted_id - var/precise_insertion = FALSE - var/datum/callback/precondition - var/datum/callback/after_insert - -/// Sets up the proper signals and fills the list of materials with the appropriate references. -/datum/component/material_container/Initialize(list/mat_list, max_amt = 0, _show_on_examine = FALSE, list/allowed_types, datum/callback/_precondition, datum/callback/_after_insert, _disable_attackby) - materials = list() - max_amount = max(0, max_amt) - show_on_examine = _show_on_examine - disable_attackby = _disable_attackby - - if(allowed_types) - if(ispath(allowed_types) && allowed_types == /obj/item/stack) - allowed_typecache = GLOB.typecache_stack - else - allowed_typecache = typecacheof(allowed_types) - - precondition = _precondition - after_insert = _after_insert - - RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy) - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/OnExamine) - - for(var/mat in mat_list) //Make the assoc list ref | amount - var/datum/material/M = getmaterialref(mat) || mat - materials[M] = 0 - -/datum/component/material_container/proc/OnExamine(datum/source, mob/user) - if(show_on_examine) - for(var/I in materials) - var/datum/material/M = I - var/amt = materials[I] - if(amt) - to_chat(user, "It has [amt] units of [lowertext(M.name)] stored.") - -/// Proc that allows players to fill the parent with mats -/datum/component/material_container/proc/OnAttackBy(datum/source, obj/item/I, mob/living/user) - var/list/tc = allowed_typecache - if(disable_attackby) - return - if(user.a_intent != INTENT_HELP) - return - if(I.item_flags & ITEM_ABSTRACT) - return - if((I.flags_1 & HOLOGRAM_1) || (I.item_flags & NO_MAT_REDEMPTION) || (tc && !is_type_in_typecache(I, tc))) - to_chat(user, "[parent] won't accept [I]!") - return - . = COMPONENT_NO_AFTERATTACK - var/datum/callback/pc = precondition - if(pc && !pc.Invoke(user)) - return - var/material_amount = get_item_material_amount(I) - if(!material_amount) - to_chat(user, "[I] does not contain sufficient amounts of metal or glass to be accepted by [parent].") - return - if(!has_space(material_amount)) - to_chat(user, "[parent] is full. Please remove metal or glass from [parent] in order to insert more.") - return - user_insert(I, user) - -/// Proc used for when player inserts materials -/datum/component/material_container/proc/user_insert(obj/item/I, mob/living/user) - set waitfor = FALSE - var/requested_amount - var/active_held = user.get_active_held_item() // differs from I when using MUTATION_TELEKINESIS - if(istype(I, /obj/item/stack) && precise_insertion) - var/atom/current_parent = parent - var/obj/item/stack/S = I - requested_amount = input(user, "How much do you want to insert?", "Inserting [S.singular_name]s") as num|null - if(isnull(requested_amount) || (requested_amount <= 0)) - return - if(QDELETED(I) || QDELETED(user) || QDELETED(src) || parent != current_parent || user.physical_can_use_topic(current_parent) < UI_INTERACTIVE || user.get_active_held_item() != active_held) - return - if(!user.temporarilyRemoveItemFromInventory(I)) - to_chat(user, "[I] is stuck to you and cannot be placed into [parent].") - return - var/inserted = insert_item(I, stack_amt = requested_amount) - if(inserted) - if(istype(I, /obj/item/stack)) - var/obj/item/stack/S = I - to_chat(user, "You insert [inserted] [S.singular_name][inserted>1 ? "s" : ""] into [parent].") - if(!QDELETED(I) && I == active_held && !user.put_in_hands(I)) - stack_trace("Warning: User could not put object back in hand during material container insertion, line [__LINE__]! This can lead to issues.") - I.forceMove(user.drop_location()) - else - to_chat(user, "You insert a material total of [inserted] into [parent].") - qdel(I) - if(after_insert) - after_insert.Invoke(I.type, last_inserted_id, inserted) - else if(I == active_held) - user.put_in_active_hand(I) - -/// Proc specifically for inserting items, returns the amount of materials entered. -/datum/component/material_container/proc/insert_item(obj/item/I, var/multiplier = 1, stack_amt) - if(!I) - return FALSE - if(istype(I, /obj/item/stack)) - return insert_stack(I, stack_amt, multiplier) - - multiplier = CEILING(multiplier, 0.01) - - var/material_amount = get_item_material_amount(I) - if(!material_amount || !has_space(material_amount)) - return FALSE - - last_inserted_id = insert_item_materials(I, multiplier) - return material_amount - -/datum/component/material_container/proc/insert_item_materials(obj/item/I, multiplier = 1) - var/primary_mat - var/max_mat_value = 0 - for(var/MAT in materials) - materials[MAT] += I.materials[MAT] * multiplier - total_amount += I.materials[MAT] * multiplier - if(I.materials[MAT] > max_mat_value) - primary_mat = MAT - return primary_mat - -/// Proc for putting a stack inside of the container -/datum/component/material_container/proc/insert_stack(obj/item/stack/S, amt, multiplier = 1) - if(isnull(amt)) - amt = S.amount - - if(amt <= 0) - return FALSE - - if(amt > S.amount) - amt = S.amount - - var/material_amt = get_item_material_amount(S) - if(!material_amt) - return FALSE - - amt = min(amt, round(((max_amount - total_amount) / material_amt))) - if(!amt) - return FALSE - - last_inserted_id = insert_item_materials(S,amt * multiplier) - S.use(amt) - return amt - -/// For inserting an amount of material -/datum/component/material_container/proc/insert_amount_mat(amt, var/datum/material/mat) - if(!istype(mat)) - mat = getmaterialref(mat) - if(amt > 0 && has_space(amt)) - var/total_amount_saved = total_amount - if(mat) - materials[mat] += amt - else - for(var/i in materials) - materials[i] += amt - total_amount += amt - return (total_amount - total_amount_saved) - return FALSE - -/// Uses an amount of a specific material, effectively removing it. -/datum/component/material_container/proc/use_amount_mat(amt, var/datum/material/mat) - if(!istype(mat)) - mat = getmaterialref(mat) - var/amount = materials[mat] - if(mat) - if(amount >= amt) - materials[mat] -= amt - total_amount -= amt - return amt - return FALSE - -/// Proc for transfering materials to another container. -/datum/component/material_container/proc/transer_amt_to(var/datum/component/material_container/T, amt, var/datum/material/mat) - if(!istype(mat)) - mat = getmaterialref(mat) - if((amt==0)||(!T)||(!mat)) - return FALSE - if(amt<0) - return T.transer_amt_to(src, -amt, mat) - var/tr = min(amt, materials[mat],T.can_insert_amount_mat(amt, mat)) - if(tr) - use_amount_mat(tr, mat) - T.insert_amount_mat(tr, mat) - return tr - return FALSE - -/// Proc for checking if there is room in the component, returning the amount or else the amount lacking. -/datum/component/material_container/proc/can_insert_amount_mat(amt, mat) - if(amt && mat) - var/datum/material/M = mat - if(M) - if((total_amount + amt) <= max_amount) - return amt - else - return (max_amount-total_amount) - - -/// For consuming a dictionary of materials. mats is the map of materials to use and the corresponding amounts, example: list(M/datum/material/glass =100, datum/material/iron=200) -/datum/component/material_container/proc/use_materials(list/mats, multiplier=1) - if(!mats || !length(mats)) - return FALSE - - var/list/mats_to_remove = list() //Assoc list MAT | AMOUNT - - for(var/x in mats) //Loop through all required materials - var/datum/material/req_mat = x - if(!istype(req_mat)) - req_mat = getmaterialref(req_mat) //Get the ref if necesary - if(!materials[req_mat]) //Do we have the resource? - return FALSE //Can't afford it - var/amount_required = mats[x] * multiplier - if(!(materials[req_mat] >= amount_required)) // do we have enough of the resource? - return FALSE //Can't afford it - mats_to_remove[req_mat] += amount_required //Add it to the assoc list of things to remove - continue - - var/total_amount_save = total_amount - - for(var/i in mats_to_remove) - total_amount_save -= use_amount_mat(mats_to_remove[i], i) - - return total_amount_save - total_amount - -/// For spawning mineral sheets at a specific location. Used by machines to output sheets. -/datum/component/material_container/proc/retrieve_sheets(sheet_amt, var/datum/material/M, target = null) - if(!M.sheet_type) - return 0 //Add greyscale sheet handling here later - if(sheet_amt <= 0) - return 0 - - if(!target) - target = get_turf(parent) - if(materials[M] < (sheet_amt * MINERAL_MATERIAL_AMOUNT)) - sheet_amt = round(materials[M] / MINERAL_MATERIAL_AMOUNT) - var/count = 0 - while(sheet_amt > MAX_STACK_SIZE) - new M.sheet_type(target, MAX_STACK_SIZE) - count += MAX_STACK_SIZE - use_amount_mat(sheet_amt * MINERAL_MATERIAL_AMOUNT, M) - sheet_amt -= MAX_STACK_SIZE - if(sheet_amt >= 1) - new M.sheet_type(target, sheet_amt) - count += sheet_amt - use_amount_mat(sheet_amt * MINERAL_MATERIAL_AMOUNT, M) - return count - - -/// Proc to get all the materials and dump them as sheets -/datum/component/material_container/proc/retrieve_all(target = null) - var/result = 0 - for(var/MAT in materials) - var/amount = materials[MAT] - result += retrieve_sheets(amount2sheet(amount), MAT, target) - return result - -/// Proc that returns TRUE if the container has space -/datum/component/material_container/proc/has_space(amt = 0) - return (total_amount + amt) <= max_amount - -/// Checks if its possible to afford a certain amount of materials. Takes a dictionary of materials. -/datum/component/material_container/proc/has_materials(list/mats, multiplier=1) - if(!mats || !mats.len) - return FALSE - - for(var/x in mats) //Loop through all required materials - var/datum/material/req_mat = x - if(!istype(req_mat)) - if(ispath(req_mat)) //Is this an actual material, or is it a category? - req_mat = getmaterialref(req_mat) //Get the ref - - else // Its a category. (For example MAT_CATEGORY_RIGID) - if(!has_enough_of_category(req_mat, mats[x], multiplier)) //Do we have enough of this category? - return FALSE - else - continue - - if(!has_enough_of_material(req_mat, mats[x], multiplier))//Not a category, so just check the normal way - return FALSE - - return TRUE - -/// Returns all the categories in a recipe. -/datum/component/material_container/proc/get_categories(list/mats) - var/list/categories = list() - for(var/x in mats) //Loop through all required materials - if(!istext(x)) //This means its not a category - continue - categories += x - return categories - - -/// Returns TRUE if you have enough of the specified material. -/datum/component/material_container/proc/has_enough_of_material(var/datum/material/req_mat, amount, multiplier=1) - if(!materials[req_mat]) //Do we have the resource? - return FALSE //Can't afford it - var/amount_required = amount * multiplier - if(materials[req_mat] >= amount_required) // do we have enough of the resource? - return TRUE - return FALSE //Can't afford it - -/// Returns TRUE if you have enough of a specified material category (Which could be multiple materials) -/datum/component/material_container/proc/has_enough_of_category(category, amount, multiplier=1) - for(var/i in SSmaterials.materials_by_category[category]) - var/datum/material/mat = i - if(materials[mat] >= amount) //we have enough - return TRUE - return FALSE - -/// Turns a material amount into the amount of sheets it should output -/datum/component/material_container/proc/amount2sheet(amt) - if(amt >= MINERAL_MATERIAL_AMOUNT) - return round(amt / MINERAL_MATERIAL_AMOUNT) - return FALSE - -/// Turns an amount of sheets into the amount of material amount it should output -/datum/component/material_container/proc/sheet2amount(sheet_amt) - if(sheet_amt > 0) - return sheet_amt * MINERAL_MATERIAL_AMOUNT - return FALSE - - -///returns the amount of material relevant to this container; if this container does not support glass, any glass in 'I' will not be taken into account -/datum/component/material_container/proc/get_item_material_amount(obj/item/I) - if(!istype(I)) - return FALSE - var/material_amount = 0 - for(var/MAT in materials) - material_amount += I.materials[MAT] - return material_amount - -/// Returns the amount of a specific material in this container. -/datum/component/material_container/proc/get_material_amount(var/datum/material/mat) - if(!istype(mat)) - mat = getmaterialref(mat) - return(materials[mat]) diff --git a/code/datums/components/mirage_border.dm b/code/datums/components/mirage_border.dm deleted file mode 100644 index a366f4b822f..00000000000 --- a/code/datums/components/mirage_border.dm +++ /dev/null @@ -1,42 +0,0 @@ -/datum/component/mirage_border - can_transfer = TRUE - var/obj/effect/abstract/mirage_holder/holder - -/datum/component/mirage_border/Initialize(turf/target, direction, range=world.view) - if(!isturf(parent)) - return COMPONENT_INCOMPATIBLE - if(!target || !istype(target) || !direction) - . = COMPONENT_INCOMPATIBLE - CRASH("[type] improperly instanced with the following args: target=\[[target]\], direction=\[[direction]\], range=\[[range]\]") - - holder = new(parent) - - var/x = target.x - var/y = target.y - var/z = target.z - var/turf/southwest = locate(clamp(x - (direction & WEST ? range : 0), 1, world.maxx), clamp(y - (direction & SOUTH ? range : 0), 1, world.maxy), clamp(z, 1, world.maxz)) - var/turf/northeast = locate(clamp(x + (direction & EAST ? range : 0), 1, world.maxx), clamp(y + (direction & NORTH ? range : 0), 1, world.maxy), clamp(z, 1, world.maxz)) - //holder.vis_contents += block(southwest, northeast) // This doesnt work because of beta bug memes - for(var/i in block(southwest, northeast)) - holder.vis_contents += i - if(direction & SOUTH) - holder.pixel_y -= world.icon_size * range - if(direction & WEST) - holder.pixel_x -= world.icon_size * range - -/datum/component/mirage_border/Destroy() - QDEL_NULL(holder) - return ..() - -/datum/component/mirage_border/PreTransfer() - holder.moveToNullspace() - -/datum/component/mirage_border/PostTransfer() - if(!isturf(parent)) - return COMPONENT_INCOMPATIBLE - holder.forceMove(parent) - -/obj/effect/abstract/mirage_holder - name = "Mirage holder" - anchored = TRUE - mouse_opacity = MOUSE_OPACITY_TRANSPARENT diff --git a/code/datums/components/nanites.dm b/code/datums/components/nanites.dm deleted file mode 100644 index e63d0c9ad1b..00000000000 --- a/code/datums/components/nanites.dm +++ /dev/null @@ -1,316 +0,0 @@ -/datum/component/nanites - dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS - - var/mob/living/host_mob - var/nanite_volume = 100 //amount of nanites in the system, used as fuel for nanite programs - var/max_nanites = 500 //maximum amount of nanites in the system - var/regen_rate = 0.5 //nanites generated per second - var/safety_threshold = 50 //how low nanites will get before they stop processing/triggering - var/cloud_id = 0 //0 if not connected to the cloud, 1-100 to set a determined cloud backup to draw from - var/next_sync = 0 - var/list/datum/nanite_program/programs = list() - var/max_programs = NANITE_PROGRAM_LIMIT - - var/stealth = FALSE //if TRUE, does not appear on HUDs and health scans, and does not display the program list on nanite scans - -/datum/component/nanites/Initialize(amount = 100, cloud = 0) - if(!isliving(parent) && !istype(parent, /datum/nanite_cloud_backup)) - return COMPONENT_INCOMPATIBLE - - nanite_volume = amount - cloud_id = cloud - - //Nanites without hosts are non-interactive through normal means - if(isliving(parent)) - host_mob = parent - - if(!(host_mob.mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD))) //Shouldn't happen, but this avoids HUD runtimes in case a silicon gets them somehow. - return COMPONENT_INCOMPATIBLE - - host_mob.hud_set_nanite_indicator() - START_PROCESSING(SSnanites, src) - - if(cloud_id) - cloud_sync() - -/datum/component/nanites/RegisterWithParent() - RegisterSignal(parent, COMSIG_HAS_NANITES, .proc/confirm_nanites) - RegisterSignal(parent, COMSIG_NANITE_UI_DATA, .proc/nanite_ui_data) - RegisterSignal(parent, COMSIG_NANITE_GET_PROGRAMS, .proc/get_programs) - RegisterSignal(parent, COMSIG_NANITE_SET_VOLUME, .proc/set_volume) - RegisterSignal(parent, COMSIG_NANITE_ADJUST_VOLUME, .proc/adjust_nanites) - RegisterSignal(parent, COMSIG_NANITE_SET_MAX_VOLUME, .proc/set_max_volume) - RegisterSignal(parent, COMSIG_NANITE_SET_CLOUD, .proc/set_cloud) - RegisterSignal(parent, COMSIG_NANITE_SET_SAFETY, .proc/set_safety) - RegisterSignal(parent, COMSIG_NANITE_SET_REGEN, .proc/set_regen) - RegisterSignal(parent, COMSIG_NANITE_ADD_PROGRAM, .proc/add_program) - RegisterSignal(parent, COMSIG_NANITE_SCAN, .proc/nanite_scan) - RegisterSignal(parent, COMSIG_NANITE_SYNC, .proc/sync) - - if(isliving(parent)) - RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, .proc/on_emp) - RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/on_death) - RegisterSignal(parent, COMSIG_MOB_ALLOWED, .proc/check_access) - RegisterSignal(parent, COMSIG_LIVING_ELECTROCUTE_ACT, .proc/on_shock) - RegisterSignal(parent, COMSIG_LIVING_MINOR_SHOCK, .proc/on_minor_shock) - RegisterSignal(parent, COMSIG_SPECIES_GAIN, .proc/check_viable_biotype) - RegisterSignal(parent, COMSIG_NANITE_SIGNAL, .proc/receive_signal) - RegisterSignal(parent, COMSIG_NANITE_COMM_SIGNAL, .proc/receive_comm_signal) - -/datum/component/nanites/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_HAS_NANITES, - COMSIG_NANITE_UI_DATA, - COMSIG_NANITE_GET_PROGRAMS, - COMSIG_NANITE_SET_VOLUME, - COMSIG_NANITE_ADJUST_VOLUME, - COMSIG_NANITE_SET_MAX_VOLUME, - COMSIG_NANITE_SET_CLOUD, - COMSIG_NANITE_SET_SAFETY, - COMSIG_NANITE_SET_REGEN, - COMSIG_NANITE_ADD_PROGRAM, - COMSIG_NANITE_SCAN, - COMSIG_NANITE_SYNC, - COMSIG_ATOM_EMP_ACT, - COMSIG_MOB_DEATH, - COMSIG_MOB_ALLOWED, - COMSIG_LIVING_ELECTROCUTE_ACT, - COMSIG_LIVING_MINOR_SHOCK, - COMSIG_MOVABLE_HEAR, - COMSIG_SPECIES_GAIN, - COMSIG_NANITE_SIGNAL, - COMSIG_NANITE_COMM_SIGNAL)) - -/datum/component/nanites/Destroy() - STOP_PROCESSING(SSnanites, src) - set_nanite_bar(TRUE) - QDEL_LIST(programs) - if(host_mob) - host_mob.hud_set_nanite_indicator() - host_mob = null - return ..() - -/datum/component/nanites/InheritComponent(datum/component/nanites/new_nanites, i_am_original, list/arguments) - if(new_nanites) - adjust_nanites(null, new_nanites.nanite_volume) - else - adjust_nanites(null, arguments[1]) //just add to the nanite volume - -/datum/component/nanites/process(delta_time) - adjust_nanites(null, regen_rate) - for(var/X in programs) - var/datum/nanite_program/NP = X - NP.on_process() - set_nanite_bar() - if(cloud_id && world.time > next_sync) - cloud_sync() - next_sync = world.time + NANITE_SYNC_DELAY - -//Syncs the nanite component to another, making it so programs are the same with the same programming (except activation status) -/datum/component/nanites/proc/sync(datum/signal_source, datum/component/nanites/source, full_overwrite = TRUE, copy_activation = FALSE) - var/list/programs_to_remove = programs.Copy() - var/list/programs_to_add = source.programs.Copy() - for(var/X in programs) - var/datum/nanite_program/NP = X - for(var/Y in programs_to_add) - var/datum/nanite_program/SNP = Y - if(NP.type == SNP.type) - programs_to_remove -= NP - programs_to_add -= SNP - SNP.copy_programming(NP, copy_activation) - break - if(full_overwrite) - for(var/X in programs_to_remove) - qdel(X) - for(var/X in programs_to_add) - var/datum/nanite_program/SNP = X - add_program(null, SNP.copy()) - -/datum/component/nanites/proc/cloud_sync() - if(!cloud_id) - return - var/datum/nanite_cloud_backup/backup = SSnanites.get_cloud_backup(cloud_id) - if(backup) - var/datum/component/nanites/cloud_copy = backup.nanites - if(cloud_copy) - sync(null, cloud_copy) - -/datum/component/nanites/proc/add_program(datum/source, datum/nanite_program/new_program, datum/nanite_program/source_program) - for(var/X in programs) - var/datum/nanite_program/NP = X - if(NP.unique && NP.type == new_program.type) - qdel(NP) - if(programs.len >= max_programs) - return COMPONENT_PROGRAM_NOT_INSTALLED - if(source_program) - source_program.copy_programming(new_program) - programs += new_program - new_program.on_add(src) - return COMPONENT_PROGRAM_INSTALLED - -/datum/component/nanites/proc/consume_nanites(amount, force = FALSE) - if(!force && safety_threshold && (nanite_volume - amount < safety_threshold)) - return FALSE - adjust_nanites(null, -amount) - return (nanite_volume > 0) - -/datum/component/nanites/proc/adjust_nanites(datum/source, amount) - nanite_volume = clamp(nanite_volume + amount, 0, max_nanites) - if(nanite_volume <= 0) //oops we ran out - qdel(src) - -/datum/component/nanites/proc/set_nanite_bar(remove = FALSE) - var/image/holder = host_mob.hud_list[DIAG_NANITE_FULL_HUD] - var/icon/I = icon(host_mob.icon, host_mob.icon_state, host_mob.dir) - holder.pixel_y = I.Height() - world.icon_size - holder.icon_state = null - if(remove || stealth) - return //bye icon - var/nanite_percent = (nanite_volume / max_nanites) * 100 - nanite_percent = clamp(CEILING(nanite_percent, 10), 10, 100) - holder.icon_state = "nanites[nanite_percent]" - -/datum/component/nanites/proc/on_emp(datum/source, severity) - nanite_volume *= (rand(0.60, 0.90)) //Lose 10-40% of nanites - adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume - if(prob(40/severity)) - cloud_id = 0 - for(var/X in programs) - var/datum/nanite_program/NP = X - NP.on_emp(severity) - -/datum/component/nanites/proc/on_shock(datum/source, shock_damage) - nanite_volume *= (rand(0.45, 0.80)) //Lose 20-55% of nanites - adjust_nanites(null, -(rand(5, 50))) //Lose 5-50 flat nanite volume - for(var/X in programs) - var/datum/nanite_program/NP = X - NP.on_shock(shock_damage) - -/datum/component/nanites/proc/on_minor_shock(datum/source) - adjust_nanites(null, -(rand(5, 15))) //Lose 5-15 flat nanite volume - for(var/X in programs) - var/datum/nanite_program/NP = X - NP.on_minor_shock() - -/datum/component/nanites/proc/on_death(datum/source, gibbed) - for(var/X in programs) - var/datum/nanite_program/NP = X - NP.on_death(gibbed) - -/datum/component/nanites/proc/receive_signal(datum/source, code, source = "an unidentified source") - for(var/X in programs) - var/datum/nanite_program/NP = X - NP.receive_signal(code, source) - -/datum/component/nanites/proc/receive_comm_signal(datum/source, comm_code, comm_message, comm_source = "an unidentified source") - for(var/X in programs) - if(istype(X, /datum/nanite_program/triggered/comm)) - var/datum/nanite_program/triggered/comm/NP = X - NP.receive_comm_signal(comm_code, comm_message, comm_source) - -/datum/component/nanites/proc/check_viable_biotype() - if(!(host_mob.mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD))) - qdel(src) //bodytype no longer sustains nanites - -/datum/component/nanites/proc/check_access(datum/source, obj/O) - for(var/datum/nanite_program/triggered/access/access_program in programs) - if(access_program.activated) - return O.check_access_list(access_program.access) - else - return FALSE - return FALSE - -/datum/component/nanites/proc/set_volume(datum/source, amount) - nanite_volume = clamp(amount, 0, max_nanites) - -/datum/component/nanites/proc/set_max_volume(datum/source, amount) - max_nanites = max(1, max_nanites) - -/datum/component/nanites/proc/set_cloud(datum/source, amount) - cloud_id = clamp(amount, 0, 100) - -/datum/component/nanites/proc/set_safety(datum/source, amount) - safety_threshold = clamp(amount, 0, max_nanites) - -/datum/component/nanites/proc/set_regen(datum/source, amount) - regen_rate = amount - -/datum/component/nanites/proc/confirm_nanites() - return TRUE //yup i exist - -/datum/component/nanites/proc/get_data(list/nanite_data) - nanite_data["nanite_volume"] = nanite_volume - nanite_data["max_nanites"] = max_nanites - nanite_data["cloud_id"] = cloud_id - nanite_data["regen_rate"] = regen_rate - nanite_data["safety_threshold"] = safety_threshold - nanite_data["stealth"] = stealth - -/datum/component/nanites/proc/get_programs(datum/source, list/nanite_programs) - nanite_programs |= programs - -/datum/component/nanites/proc/nanite_scan(datum/source, mob/user, full_scan) - if(!full_scan) - if(!stealth) - to_chat(user, "Nanites Detected") - to_chat(user, "Saturation: [nanite_volume]/[max_nanites]") - return TRUE - else - to_chat(user, "NANITES DETECTED") - to_chat(user, "================") - to_chat(user, "Saturation: [nanite_volume]/[max_nanites]") - to_chat(user, "Safety Threshold: [safety_threshold]") - to_chat(user, "Cloud ID: [cloud_id ? cloud_id : "Disabled"]") - to_chat(user, "================") - to_chat(user, "Program List:") - if(stealth) - to_chat(user, "%#$ENCRYPTED&^@") - else - for(var/X in programs) - var/datum/nanite_program/NP = X - to_chat(user, "[NP.name] | [NP.activated ? "Active" : "Inactive"]") - return TRUE - -/datum/component/nanites/proc/nanite_ui_data(datum/source, list/data, scan_level) - data["has_nanites"] = TRUE - data["nanite_volume"] = nanite_volume - data["regen_rate"] = regen_rate - data["safety_threshold"] = safety_threshold - data["cloud_id"] = cloud_id - var/list/mob_programs = list() - var/id = 1 - for(var/X in programs) - var/datum/nanite_program/P = X - var/list/mob_program = list() - mob_program["name"] = P.name - mob_program["desc"] = P.desc - mob_program["id"] = id - - if(scan_level >= 2) - mob_program["activated"] = P.activated - mob_program["use_rate"] = P.use_rate - mob_program["can_trigger"] = P.can_trigger - mob_program["trigger_cost"] = P.trigger_cost - mob_program["trigger_cooldown"] = P.trigger_cooldown / 10 - - if(scan_level >= 3) - mob_program["activation_delay"] = P.activation_delay - mob_program["timer"] = P.timer - mob_program["timer_type"] = P.get_timer_type_text() - var/list/extra_settings = list() - for(var/Y in P.extra_settings) - var/list/setting = list() - setting["name"] = Y - setting["value"] = P.get_extra_setting(Y) - extra_settings += list(setting) - mob_program["extra_settings"] = extra_settings - if(LAZYLEN(extra_settings)) - mob_program["has_extra_settings"] = TRUE - - if(scan_level >= 4) - mob_program["activation_code"] = P.activation_code - mob_program["deactivation_code"] = P.deactivation_code - mob_program["kill_code"] = P.kill_code - mob_program["trigger_code"] = P.trigger_code - id++ - mob_programs += list(mob_program) - data["mob_programs"] = mob_programs diff --git a/code/datums/components/ntnet_interface.dm b/code/datums/components/ntnet_interface.dm deleted file mode 100644 index 3a8fb559bf4..00000000000 --- a/code/datums/components/ntnet_interface.dm +++ /dev/null @@ -1,66 +0,0 @@ -//Thing meant for allowing datums and objects to access a NTnet network datum. -/datum/proc/ntnet_receive(datum/netdata/data) - return - -/datum/proc/ntnet_receive_broadcast(datum/netdata/data) - return - -/datum/proc/ntnet_send(datum/netdata/data, netid) - var/datum/component/ntnet_interface/NIC = GetComponent(/datum/component/ntnet_interface) - if(!NIC) - return FALSE - return NIC.__network_send(data, netid) - -/datum/component/ntnet_interface - var/hardware_id //text. this is the true ID. do not change this. stuff like ID forgery can be done manually. - var/network_name = "" //text - var/list/networks_connected_by_id = list() //id = datum/ntnet - var/differentiate_broadcast = TRUE //If false, broadcasts go to ntnet_receive. NOT RECOMMENDED. - -/datum/component/ntnet_interface/Initialize(force_name = "NTNet Device", autoconnect_station_network = TRUE) //Don't force ID unless you know what you're doing! - hardware_id = "[SSnetworks.get_next_HID()]" - network_name = force_name - if(!SSnetworks.register_interface(src)) - . = COMPONENT_INCOMPATIBLE - CRASH("Unable to register NTNet interface. Interface deleted.") - if(autoconnect_station_network) - register_connection(SSnetworks.station_network) - -/datum/component/ntnet_interface/Destroy() - unregister_all_connections() - SSnetworks.unregister_interface(src) - return ..() - -/datum/component/ntnet_interface/proc/__network_receive(datum/netdata/data) //Do not directly proccall! - SEND_SIGNAL(parent, COMSIG_COMPONENT_NTNET_RECEIVE, data) - if(differentiate_broadcast && data.broadcast) - parent.ntnet_receive_broadcast(data) - else - parent.ntnet_receive(data) - -/datum/component/ntnet_interface/proc/__network_send(datum/netdata/data, netid) //Do not directly proccall! - - if(netid) - if(networks_connected_by_id[netid]) - var/datum/ntnet/net = networks_connected_by_id[netid] - return net.process_data_transmit(src, data) - return FALSE - for(var/i in networks_connected_by_id) - var/datum/ntnet/net = networks_connected_by_id[i] - net.process_data_transmit(src, data) - return TRUE - -/datum/component/ntnet_interface/proc/register_connection(datum/ntnet/net) - if(net.interface_connect(src)) - networks_connected_by_id[net.network_id] = net - return TRUE - -/datum/component/ntnet_interface/proc/unregister_all_connections() - for(var/i in networks_connected_by_id) - unregister_connection(networks_connected_by_id[i]) - return TRUE - -/datum/component/ntnet_interface/proc/unregister_connection(datum/ntnet/net) - net.interface_disconnect(src) - networks_connected_by_id -= net.network_id - return TRUE diff --git a/code/datums/components/paintable.dm b/code/datums/components/paintable.dm deleted file mode 100644 index 511c51e0340..00000000000 --- a/code/datums/components/paintable.dm +++ /dev/null @@ -1,29 +0,0 @@ -/datum/component/spraycan_paintable - var/current_paint - -/datum/component/spraycan_paintable/Initialize() - RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/Repaint) - -/datum/component/spraycan_paintable/Destroy() - RemoveCurrentCoat() - return ..() - -/datum/component/spraycan_paintable/proc/RemoveCurrentCoat() - var/atom/A = parent - A.remove_atom_colour(FIXED_COLOUR_PRIORITY, current_paint) - -/datum/component/spraycan_paintable/proc/Repaint(datum/source, obj/item/toy/crayon/spraycan/spraycan, mob/living/user) - if(!istype(spraycan) || user.a_intent == INTENT_HARM) - return - . = COMPONENT_NO_AFTERATTACK - if(spraycan.is_capped) - to_chat(user, "Take the cap off first!") - return - RemoveCurrentCoat() - if(spraycan.use_charges(user, 2)) - var/colour = spraycan.paint_color - current_paint = colour - var/atom/A = parent - A.add_atom_colour(colour, FIXED_COLOUR_PRIORITY) - playsound(spraycan, 'sound/effects/spray.ogg', 5, TRUE, 5) - to_chat(user, "You spray [spraycan] on [A], painting it.") diff --git a/code/datums/components/plumbing/_plumbing.dm b/code/datums/components/plumbing/_plumbing.dm deleted file mode 100644 index 16152d72b01..00000000000 --- a/code/datums/components/plumbing/_plumbing.dm +++ /dev/null @@ -1,197 +0,0 @@ -/datum/component/plumbing - ///Index with "1" = /datum/ductnet/theductpointingnorth etc. "1" being the num2text from NORTH define - var/list/datum/ductnet/ducts = list() - ///shortcut to our parents' reagent holder - var/datum/reagents/reagents - ///TRUE if we wanna add proper pipe outless under our parent object. this is pretty good if i may so so myself - var/use_overlays = TRUE - ///We can't just cut all of the parents' overlays, so we'll track them here - var/list/image/ducterlays - ///directions in wich we act as a supplier - var/supply_connects - ///direction in wich we act as a demander - var/demand_connects - ///FALSE to pretty much just not exist in the plumbing world so we can be moved, TRUE to go plumbo mode - var/active = FALSE - ///if TRUE connects will spin with the parent object visually and codually, so you can have it work in any direction. FALSE if you want it to be static - var/turn_connects = TRUE - -/datum/component/plumbing/Initialize(start=TRUE, _turn_connects=TRUE) //turn_connects for wheter or not we spin with the object to change our pipes - if(parent && !ismovable(parent)) - return COMPONENT_INCOMPATIBLE - var/atom/movable/AM = parent - if(!AM.reagents) - return COMPONENT_INCOMPATIBLE - reagents = AM.reagents - turn_connects = _turn_connects - - RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED,COMSIG_PARENT_PREQDELETED), .proc/disable) - RegisterSignal(parent, list(COMSIG_OBJ_DEFAULT_UNFASTEN_WRENCH), .proc/toggle_active) - - if(start) - enable() - - if(use_overlays) - create_overlays() - -/datum/component/plumbing/process(delta_time) - if(!demand_connects || !reagents) - STOP_PROCESSING(SSfluids, src) - return - if(reagents.total_volume < reagents.maximum_volume) - for(var/D in GLOB.cardinals) - if(D & demand_connects) - send_request(D) -///Can we be added to the ductnet? -/datum/component/plumbing/proc/can_add(datum/ductnet/D, dir) - if(!active) - return - if(!dir || !D) - return FALSE - if(num2text(dir) in ducts) - return FALSE - - return TRUE -///called from in process(). only calls process_request(), but can be overwritten for children with special behaviour -/datum/component/plumbing/proc/send_request(dir) - process_request(amount = MACHINE_REAGENT_TRANSFER, reagent = null, dir = dir) -///check who can give us what we want, and how many each of them will give us -/datum/component/plumbing/proc/process_request(amount, reagent, dir) - var/list/valid_suppliers = list() - var/datum/ductnet/net - if(!ducts.Find(num2text(dir))) - return - net = ducts[num2text(dir)] - for(var/A in net.suppliers) - var/datum/component/plumbing/supplier = A - if(supplier.can_give(amount, reagent, net)) - valid_suppliers += supplier - for(var/A in valid_suppliers) - var/datum/component/plumbing/give = A - give.transfer_to(src, amount / valid_suppliers.len, reagent, net) -///returns TRUE when they can give the specified amount and reagent. called by process request -/datum/component/plumbing/proc/can_give(amount, reagent, datum/ductnet/net) - if(amount <= 0) - return - - if(reagent) //only asked for one type of reagent - for(var/A in reagents.reagent_list) - var/datum/reagent/R = A - if(R.type == reagent) - return TRUE - else if(reagents.total_volume > 0) //take whatever - return TRUE -///this is where the reagent is actually transferred and is thus the finish point of our process() -/datum/component/plumbing/proc/transfer_to(datum/component/plumbing/target, amount, reagent, datum/ductnet/net) - if(!reagents || !target || !target.reagents) - return FALSE - if(reagent) - reagents.trans_id_to(target.parent, reagent, amount) - else - reagents.trans_to(target.parent, amount) -///We create our luxurious piping overlays/underlays, to indicate where we do what. only called once if use_overlays = TRUE in Initialize() -/datum/component/plumbing/proc/create_overlays() - var/atom/movable/AM = parent - for(var/image/I in ducterlays) - AM.overlays.Remove(I) - qdel(I) - ducterlays = list() - for(var/D in GLOB.cardinals) - var/color - var/direction - if(D & demand_connects) - color = "red" //red because red is mean and it takes - else if(D & supply_connects) - color = "blue" //blue is nice and gives - else - continue - var/image/I - if(turn_connects) - switch(D) - if(NORTH) - direction = "north" - if(SOUTH) - direction = "south" - if(EAST) - direction = "east" - if(WEST) - direction = "west" - I = image('icons/obj/plumbing/plumbers.dmi', "[direction]-[color]", layer = AM.layer - 1) - else - I = image('icons/obj/plumbing/plumbers.dmi', color, layer = AM.layer - 1) //color is not color as in the var, it's just the name - I.dir = D - AM.add_overlay(I) - ducterlays += I -///we stop acting like a plumbing thing and disconnect if we are, so we can safely be moved and stuff -/datum/component/plumbing/proc/disable() - if(!active) - return - STOP_PROCESSING(SSfluids, src) - for(var/A in ducts) - var/datum/ductnet/D = ducts[A] - D.remove_plumber(src) - active = FALSE - for(var/D in GLOB.cardinals) - if(D & (demand_connects | supply_connects)) - for(var/obj/machinery/duct/duct in get_step(parent, D)) - duct.attempt_connect() - -///settle wherever we are, and start behaving like a piece of plumbing -/datum/component/plumbing/proc/enable() - if(active) - return - update_dir() - active = TRUE - - if(demand_connects) - START_PROCESSING(SSfluids, src) - for(var/D in GLOB.cardinals) - if(D & (demand_connects | supply_connects)) - for(var/obj/machinery/duct/duct in get_step(parent, D)) - duct.attempt_connect() - - //TODO: Let plumbers directly plumb into one another without ducts if placed adjacent to each other - -/// Toggle our machinery on or off. This is called by a hook from default_unfasten_wrench with anchored as only param, so we dont have to copypaste this on every object that can move -/datum/component/plumbing/proc/toggle_active(obj/O, new_state) - if(new_state) - enable() - else - disable() -/** We update our connects only when we settle down by taking our current and original direction to find our new connects -* If someone wants it to fucking spin while connected to something go actually knock yourself out -*/ -/datum/component/plumbing/proc/update_dir() - if(!turn_connects) - return - var/atom/movable/AM = parent - var/new_demand_connects - var/new_supply_connects - var/new_dir = AM.dir - var/angle = 180 - dir2angle(new_dir) - if(new_dir == SOUTH) - demand_connects = initial(demand_connects) - supply_connects = initial(supply_connects) - else - for(var/D in GLOB.cardinals) - if(D & initial(demand_connects)) - new_demand_connects += turn(D, angle) - if(D & initial(supply_connects)) - new_supply_connects += turn(D, angle) - demand_connects = new_demand_connects - supply_connects = new_supply_connects -///Give the direction of a pipe, and it'll return wich direction it originally was when it's object pointed SOUTH -/datum/component/plumbing/proc/get_original_direction(dir) - var/atom/movable/AM = parent - return turn(dir, dir2angle(AM.dir) - 180) - -///has one pipe input that only takes, example is manual output pipe -/datum/component/plumbing/simple_demand - demand_connects = NORTH -///has one pipe output that only supplies. example is liquid pump and manual input pipe -/datum/component/plumbing/simple_supply - supply_connects = NORTH -///input and output, like a holding tank -/datum/component/plumbing/tank - demand_connects = WEST - supply_connects = EAST diff --git a/code/datums/components/plumbing/acclimator.dm b/code/datums/components/plumbing/acclimator.dm deleted file mode 100644 index 239ae652238..00000000000 --- a/code/datums/components/plumbing/acclimator.dm +++ /dev/null @@ -1,18 +0,0 @@ -/datum/component/plumbing/acclimator - demand_connects = WEST - supply_connects = EAST - -/datum/component/plumbing/acclimator/Initialize(start=TRUE, _turn_connects=TRUE) - . = ..() - if(. && istype(parent, /obj/machinery/plumbing/acclimator)) - return TRUE - -/datum/component/plumbing/acclimator/can_give(amount, reagent) - . = ..() - if(.) - var/obj/machinery/plumbing/acclimator/AC = parent - if(AC.reagents.chem_temp >= AC.target_temperature && AC.target_temperature + AC.allowed_temperature_difference >= AC.reagents.chem_temp) //cooling here - return TRUE - if(AC.reagents.chem_temp <= AC.target_temperature && AC.target_temperature - AC.allowed_temperature_difference <= AC.reagents.chem_temp) //heating here - return TRUE - return FALSE diff --git a/code/datums/components/plumbing/chemical_acclimator.dm b/code/datums/components/plumbing/chemical_acclimator.dm deleted file mode 100644 index 239ae652238..00000000000 --- a/code/datums/components/plumbing/chemical_acclimator.dm +++ /dev/null @@ -1,18 +0,0 @@ -/datum/component/plumbing/acclimator - demand_connects = WEST - supply_connects = EAST - -/datum/component/plumbing/acclimator/Initialize(start=TRUE, _turn_connects=TRUE) - . = ..() - if(. && istype(parent, /obj/machinery/plumbing/acclimator)) - return TRUE - -/datum/component/plumbing/acclimator/can_give(amount, reagent) - . = ..() - if(.) - var/obj/machinery/plumbing/acclimator/AC = parent - if(AC.reagents.chem_temp >= AC.target_temperature && AC.target_temperature + AC.allowed_temperature_difference >= AC.reagents.chem_temp) //cooling here - return TRUE - if(AC.reagents.chem_temp <= AC.target_temperature && AC.target_temperature - AC.allowed_temperature_difference <= AC.reagents.chem_temp) //heating here - return TRUE - return FALSE diff --git a/code/datums/components/plumbing/filter.dm b/code/datums/components/plumbing/filter.dm deleted file mode 100644 index c1af5c5e0eb..00000000000 --- a/code/datums/components/plumbing/filter.dm +++ /dev/null @@ -1,59 +0,0 @@ -///The magical plumbing component used by the chemical filters. The different supply connects behave differently depending on the filters set on the chemical filter -/datum/component/plumbing/filter - demand_connects = NORTH - supply_connects = SOUTH | EAST | WEST //SOUTH is straight, EAST is left and WEST is right. We look from the perspective of the insert - -/datum/component/plumbing/filter/Initialize() - . = ..() - if(!istype(parent, /obj/machinery/plumbing/filter)) - return COMPONENT_INCOMPATIBLE - -/datum/component/plumbing/filter/can_give(amount, reagent, datum/ductnet/net) - . = ..() - if(.) - var/direction - for(var/A in ducts) - if(ducts[A] == net) - direction = get_original_direction(text2num(A)) //we need it relative to the direction, so filters don't change when we turn the filter - break - if(!direction) - return FALSE - if(reagent) - if(!can_give_in_direction(direction, reagent)) - return FALSE - -/datum/component/plumbing/filter/transfer_to(datum/component/plumbing/target, amount, reagent, datum/ductnet/net) - if(!reagents || !target || !target.reagents) - return FALSE - var/direction - for(var/A in ducts) - if(ducts[A] == net) - direction = get_original_direction(text2num(A)) - break - if(reagent) - reagents.trans_id_to(target.reagents, reagent, amount) - else - for(var/A in reagents.reagent_list) - var/datum/reagent/R = A - if(!can_give_in_direction(direction, R.type)) - continue - var/new_amount - if(R.volume < amount) - new_amount = amount - R.volume - reagents.trans_id_to(target.parent, R.type, amount) - amount = new_amount - if(amount <= 0) - break -///We check if the direction and reagent are valid to give. Needed for filters since different outputs have different behaviours -/datum/component/plumbing/filter/proc/can_give_in_direction(dir, reagent) - var/obj/machinery/plumbing/filter/F = parent - switch(dir) - if(SOUTH) //straight - if(!F.left.Find(reagent) && !F.right.Find(reagent)) - return TRUE - if(WEST) //right - if(F.right.Find(reagent)) - return TRUE - if(EAST) //left - if(F.left.Find(reagent)) - return TRUE diff --git a/code/datums/components/plumbing/reaction_chamber.dm b/code/datums/components/plumbing/reaction_chamber.dm deleted file mode 100644 index 8caf8a6b091..00000000000 --- a/code/datums/components/plumbing/reaction_chamber.dm +++ /dev/null @@ -1,43 +0,0 @@ -/datum/component/plumbing/reaction_chamber - demand_connects = WEST - supply_connects = EAST - -/datum/component/plumbing/reaction_chamber/Initialize(start=TRUE, _turn_connects=TRUE) - . = ..() - if(!istype(parent, /obj/machinery/plumbing/reaction_chamber)) - return COMPONENT_INCOMPATIBLE - -/datum/component/plumbing/reaction_chamber/can_give(amount, reagent) - . = ..() - var/obj/machinery/plumbing/reaction_chamber/RC = parent - if(!. || !RC.emptying) - return FALSE - -/datum/component/plumbing/reaction_chamber/send_request(dir) - var/obj/machinery/plumbing/reaction_chamber/RC = parent - if(RC.emptying || !LAZYLEN(RC.required_reagents)) - return - for(var/RT in RC.required_reagents) - var/has_reagent = FALSE - for(var/A in reagents.reagent_list) - var/datum/reagent/RD = A - if(RT == RD.type) - has_reagent = TRUE - if(RD.volume < RC.required_reagents[RT]) - process_request(min(RC.required_reagents[RT] - RD.volume, MACHINE_REAGENT_TRANSFER) , RT, dir) - return - if(!has_reagent) - process_request(min(RC.required_reagents[RT], MACHINE_REAGENT_TRANSFER), RT, dir) - return - reagents.flags &= ~NO_REACT - RC.emptying = TRUE - -/datum/component/plumbing/reaction_chamber/can_give(amount, reagent, datum/ductnet/net) - . = ..() - var/obj/machinery/plumbing/reaction_chamber/RC = parent - if(!. || !RC.emptying) - return FALSE - - - - diff --git a/code/datums/components/plumbing/splitter.dm b/code/datums/components/plumbing/splitter.dm deleted file mode 100644 index c4c322c2ab3..00000000000 --- a/code/datums/components/plumbing/splitter.dm +++ /dev/null @@ -1,47 +0,0 @@ -/datum/component/plumbing/splitter - demand_connects = NORTH - supply_connects = SOUTH | EAST - -/datum/component/plumbing/splitter/Initialize() - . = ..() - if(. && !istype(parent, /obj/machinery/plumbing/splitter)) - return FALSE - -/datum/component/plumbing/splitter/can_give(amount, reagent, datum/ductnet/net) - . = ..() - if(!.) - return - . = FALSE - var/direction - for(var/A in ducts) - if(ducts[A] == net) - direction = get_original_direction(text2num(A)) - break - var/obj/machinery/plumbing/splitter/S = parent - switch(direction) - if(SOUTH) - if(S.turn_straight && S.transfer_straight <= amount) - S.turn_straight = FALSE - return TRUE - if(EAST) - if(!S.turn_straight && S.transfer_side <= amount) - S.turn_straight = FALSE - return TRUE - -/datum/component/plumbing/splitter/transfer_to(datum/component/plumbing/target, amount, reagent, datum/ductnet/net) - var/direction - for(var/A in ducts) - if(ducts[A] == net) - direction = get_original_direction(text2num(A)) - break - var/obj/machinery/plumbing/splitter/S = parent - switch(direction) - if(SOUTH) - if(amount >= S.transfer_straight) - amount = S.transfer_straight - if(EAST) - if(amount >= S.transfer_side) - amount = S.transfer_side - . = ..() - - diff --git a/code/datums/components/punchcooldown.dm b/code/datums/components/punchcooldown.dm deleted file mode 100644 index d42a8fd00dc..00000000000 --- a/code/datums/components/punchcooldown.dm +++ /dev/null @@ -1,29 +0,0 @@ -///Your favourite Jojoke. Used for the gloves of the north star. -/datum/component/wearertargeting/punchcooldown - signals = list(COMSIG_HUMAN_MELEE_UNARMED_ATTACK) - mobtype = /mob/living/carbon - proctype = .proc/reducecooldown - valid_slots = list(SLOT_GLOVES) - ///The warcry this generates - var/warcry = "AT" - -/datum/component/wearertargeting/punchcooldown/Initialize() - . = ..() - if(. == COMPONENT_INCOMPATIBLE) - return - RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/changewarcry) - -///Called on COMSIG_HUMAN_MELEE_UNARMED_ATTACK. Yells the warcry and and reduces punch cooldown. -/datum/component/wearertargeting/punchcooldown/proc/reducecooldown(mob/living/carbon/M, atom/target) - if(M.a_intent == INTENT_HARM && isliving(target)) - M.changeNext_move(CLICK_CD_RAPID) - if(warcry) - M.say(warcry, ignore_spam = TRUE, forced = "north star warcry") - -///Called on COMSIG_ITEM_ATTACK_SELF. Allows you to change the warcry. -/datum/component/wearertargeting/punchcooldown/proc/changewarcry(datum/source, mob/user) - var/input = stripped_input(user,"What do you want your battlecry to be? Max length of 6 characters.", ,"", 7) - if(!QDELETED(src) && !QDELETED(user) && !user.Adjacent(parent)) - return - if(input) - warcry = input diff --git a/code/datums/components/remote_materials.dm b/code/datums/components/remote_materials.dm deleted file mode 100644 index 7d6fdd85a8d..00000000000 --- a/code/datums/components/remote_materials.dm +++ /dev/null @@ -1,114 +0,0 @@ -/* -This component allows machines to connect remotely to a material container -(namely an /obj/machinery/ore_silo) elsewhere. It offers optional graceful -fallback to a local material storage in case remote storage is unavailable, and -handles linking back and forth. -*/ - -/datum/component/remote_materials - // Three possible states: - // 1. silo exists, materials is parented to silo - // 2. silo is null, materials is parented to parent - // 3. silo is null, materials is null - var/obj/machinery/ore_silo/silo - var/datum/component/material_container/mat_container - var/category - var/allow_standalone - var/local_size = INFINITY - -/datum/component/remote_materials/Initialize(category, mapload, allow_standalone = TRUE, force_connect = FALSE) - if (!isatom(parent)) - return COMPONENT_INCOMPATIBLE - - src.category = category - src.allow_standalone = allow_standalone - - RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy) - RegisterSignal(parent, COMSIG_ATOM_MULTITOOL_ACT, .proc/OnMultitool) - - var/turf/T = get_turf(parent) - if (force_connect || (mapload && is_station_level(T.z))) - addtimer(CALLBACK(src, .proc/LateInitialize)) - else if (allow_standalone) - _MakeLocal() - -/datum/component/remote_materials/proc/LateInitialize() - silo = GLOB.ore_silo_default - if (silo) - silo.connected += src - mat_container = silo.GetComponent(/datum/component/material_container) - else - _MakeLocal() - -/datum/component/remote_materials/Destroy() - if (silo) - silo.connected -= src - silo.updateUsrDialog() - silo = null - mat_container = null - else if (mat_container) - // specify explicitly in case the other component is deleted first - var/atom/P = parent - mat_container.retrieve_all(P.drop_location()) - return ..() - -/datum/component/remote_materials/proc/_MakeLocal() - silo = null - mat_container = parent.AddComponent(/datum/component/material_container, - list(/datum/material/iron, /datum/material/glass, /datum/material/silver, /datum/material/gold, /datum/material/diamond, /datum/material/plasma, /datum/material/uranium, /datum/material/bananium, /datum/material/titanium, /datum/material/bluespace, /datum/material/plastic), - local_size, - FALSE, - /obj/item/stack) - -/datum/component/remote_materials/proc/set_local_size(size) - local_size = size - if (!silo && mat_container) - mat_container.max_amount = size - -// called if disconnected by ore silo UI or destruction -/datum/component/remote_materials/proc/disconnect_from(obj/machinery/ore_silo/old_silo) - if (!old_silo || silo != old_silo) - return - silo = null - mat_container = null - if (allow_standalone) - _MakeLocal() - -/datum/component/remote_materials/proc/OnAttackBy(datum/source, obj/item/I, mob/user) - if (silo && istype(I, /obj/item/stack)) - if (silo.remote_attackby(parent, user, I)) - return COMPONENT_NO_AFTERATTACK - -/datum/component/remote_materials/proc/OnMultitool(datum/source, mob/user, obj/item/I) - if(!I.multitool_check_buffer(user, I)) - return COMPONENT_BLOCK_TOOL_ATTACK - var/obj/item/multitool/M = I - if (!QDELETED(M.buffer) && istype(M.buffer, /obj/machinery/ore_silo)) - if (silo == M.buffer) - to_chat(user, "[parent] is already connected to [silo].") - return COMPONENT_BLOCK_TOOL_ATTACK - if (silo) - silo.connected -= src - silo.updateUsrDialog() - else if (mat_container) - mat_container.retrieve_all() - qdel(mat_container) - silo = M.buffer - silo.connected += src - silo.updateUsrDialog() - mat_container = silo.GetComponent(/datum/component/material_container) - to_chat(user, "You connect [parent] to [silo] from the multitool's buffer.") - return COMPONENT_BLOCK_TOOL_ATTACK - -/datum/component/remote_materials/proc/on_hold() - return silo && silo.holds["[get_area(parent)]/[category]"] - -/datum/component/remote_materials/proc/silo_log(obj/machinery/M, action, amount, noun, list/mats) - if (silo) - silo.silo_log(M || parent, action, amount, noun, mats) - -/datum/component/remote_materials/proc/format_amount() - if (mat_container) - return "[mat_container.total_amount] / [mat_container.max_amount == INFINITY ? "Unlimited" : mat_container.max_amount] ([silo ? "remote" : "local"])" - else - return "0 / 0" diff --git a/code/datums/components/rot.dm b/code/datums/components/rot.dm deleted file mode 100644 index 0f92ddf1e33..00000000000 --- a/code/datums/components/rot.dm +++ /dev/null @@ -1,60 +0,0 @@ -/datum/component/rot - var/amount = 1 - -/datum/component/rot/Initialize(new_amount) - if(!isatom(parent)) - return COMPONENT_INCOMPATIBLE - - if(new_amount) - amount = new_amount - - START_PROCESSING(SSprocessing, src) - -/datum/component/rot/process(delta_time) - var/atom/A = parent - - var/turf/open/T = get_turf(A) - if(!istype(T) || T.return_air().return_pressure() > (WARNING_HIGH_PRESSURE - 10)) - return - - var/datum/gas_mixture/stank = new - ADD_GAS(/datum/gas/miasma, stank.gases) - stank.gases[/datum/gas/miasma][MOLES] = amount - stank.temperature = BODYTEMP_NORMAL // otherwise we have gas below 2.7K which will break our lag generator - T.assume_air(stank) - T.air_update_turf() - -/datum/component/rot/corpse - amount = MIASMA_CORPSE_MOLES - -/datum/component/rot/corpse/Initialize() - if(!iscarbon(parent)) - return COMPONENT_INCOMPATIBLE - . = ..() - -/datum/component/rot/corpse/process(delta_time) - var/mob/living/carbon/C = parent - if(C.stat != DEAD) - qdel(src) - return - - // Wait a bit before decaying - if(world.time - C.timeofdeath < 2 MINUTES) - return - - // Properly stored corpses shouldn't create miasma - if(istype(C.loc, /obj/structure/closet/crate/coffin)|| istype(C.loc, /obj/structure/closet/body_bag) || istype(C.loc, /obj/structure/bodycontainer)) - return - - // No decay if formaldehyde in corpse or when the corpse is charred - if(C.reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 15) || HAS_TRAIT(C, TRAIT_HUSK)) - return - - // Also no decay if corpse chilled or not organic/undead - if(C.bodytemperature <= T0C-10 || !(C.mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD))) - return - - ..() - -/datum/component/rot/gibs - amount = MIASMA_GIBS_MOLES diff --git a/code/datums/components/rotation.dm b/code/datums/components/rotation.dm deleted file mode 100644 index d8734226dfa..00000000000 --- a/code/datums/components/rotation.dm +++ /dev/null @@ -1,163 +0,0 @@ -#define ROTATION_ALTCLICK (1<<0) -#define ROTATION_WRENCH (1<<1) -#define ROTATION_VERBS (1<<2) -#define ROTATION_COUNTERCLOCKWISE (1<<3) -#define ROTATION_CLOCKWISE (1<<4) -#define ROTATION_FLIP (1<<5) - -/datum/component/simple_rotation - var/datum/callback/can_user_rotate //Checks if user can rotate - var/datum/callback/can_be_rotated //Check if object can be rotated at all - var/datum/callback/after_rotation //Additional stuff to do after rotation - - var/rotation_flags = NONE - var/default_rotation_direction = ROTATION_CLOCKWISE - -/datum/component/simple_rotation/Initialize(rotation_flags = NONE ,can_user_rotate,can_be_rotated,after_rotation) - if(!ismovable(parent)) - return COMPONENT_INCOMPATIBLE - - //throw if no rotation direction is specificed ? - - src.rotation_flags = rotation_flags - - if(can_user_rotate) - src.can_user_rotate = can_user_rotate - else - src.can_user_rotate = CALLBACK(src,.proc/default_can_user_rotate) - - if(can_be_rotated) - src.can_be_rotated = can_be_rotated - else - src.can_be_rotated = CALLBACK(src,.proc/default_can_be_rotated) - - if(after_rotation) - src.after_rotation = after_rotation - else - src.after_rotation = CALLBACK(src,.proc/default_after_rotation) - - //Try Clockwise,counter,flip in order - if(src.rotation_flags & ROTATION_FLIP) - default_rotation_direction = ROTATION_FLIP - if(src.rotation_flags & ROTATION_COUNTERCLOCKWISE) - default_rotation_direction = ROTATION_COUNTERCLOCKWISE - if(src.rotation_flags & ROTATION_CLOCKWISE) - default_rotation_direction = ROTATION_CLOCKWISE - -/datum/component/simple_rotation/proc/add_signals() - if(rotation_flags & ROTATION_ALTCLICK) - RegisterSignal(parent, COMSIG_CLICK_ALT, .proc/HandRot) - RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/ExamineMessage) - if(rotation_flags & ROTATION_WRENCH) - RegisterSignal(parent, COMSIG_ATOM_WRENCH_ACT, .proc/WrenchRot) - -/datum/component/simple_rotation/proc/add_verbs() - if(rotation_flags & ROTATION_VERBS) - var/atom/movable/AM = parent - if(rotation_flags & ROTATION_FLIP) - add_obj_verb(AM, /atom/movable/proc/simple_rotate_flip) - if(src.rotation_flags & ROTATION_CLOCKWISE) - add_obj_verb(AM, /atom/movable/proc/simple_rotate_clockwise) - if(src.rotation_flags & ROTATION_COUNTERCLOCKWISE) - add_obj_verb(AM, /atom/movable/proc/simple_rotate_counterclockwise) - -/datum/component/simple_rotation/proc/remove_verbs() - if(parent) - var/atom/movable/AM = parent - remove_obj_verb(AM, /atom/movable/proc/simple_rotate_flip) - remove_obj_verb(AM, /atom/movable/proc/simple_rotate_clockwise) - remove_obj_verb(AM, /atom/movable/proc/simple_rotate_counterclockwise) - -/datum/component/simple_rotation/proc/remove_signals() - UnregisterSignal(parent, list(COMSIG_CLICK_ALT, COMSIG_PARENT_EXAMINE, COMSIG_PARENT_ATTACKBY)) - -/datum/component/simple_rotation/RegisterWithParent() - add_verbs() - add_signals() - . = ..() - -/datum/component/simple_rotation/PostTransfer() - //Because of the callbacks which we don't track cleanly we can't transfer this - //item cleanly, better to let the new of the new item create a new rotation datum - //instead (there's no real state worth transferring) - return COMPONENT_NOTRANSFER - -/datum/component/simple_rotation/UnregisterFromParent() - remove_verbs() - remove_signals() - . = ..() - -/datum/component/simple_rotation/Destroy() - QDEL_NULL(can_user_rotate) - QDEL_NULL(can_be_rotated) - QDEL_NULL(after_rotation) - //Signals + verbs removed via UnRegister - . = ..() - -/datum/component/simple_rotation/RemoveComponent() - remove_verbs() - . = ..() - -/datum/component/simple_rotation/proc/ExamineMessage(datum/source, mob/user, list/examine_list) - if(rotation_flags & ROTATION_ALTCLICK) - examine_list += "Alt-click to rotate it clockwise." - -/datum/component/simple_rotation/proc/HandRot(datum/source, mob/user, rotation = default_rotation_direction) - if(!can_be_rotated.Invoke(user, rotation) || !can_user_rotate.Invoke(user, rotation)) - return - BaseRot(user, rotation) - -/datum/component/simple_rotation/proc/WrenchRot(datum/source, obj/item/I, mob/living/user) - if(!can_be_rotated.Invoke(user,default_rotation_direction) || !can_user_rotate.Invoke(user,default_rotation_direction)) - return - BaseRot(user,default_rotation_direction) - return COMPONENT_BLOCK_TOOL_ATTACK - -/datum/component/simple_rotation/proc/BaseRot(mob/user,rotation_type) - var/atom/movable/AM = parent - var/rot_degree - switch(rotation_type) - if(ROTATION_CLOCKWISE) - rot_degree = -90 - if(ROTATION_COUNTERCLOCKWISE) - rot_degree = 90 - if(ROTATION_FLIP) - rot_degree = 180 - AM.setDir(turn(AM.dir,rot_degree)) - after_rotation.Invoke(user,rotation_type) - -/datum/component/simple_rotation/proc/default_can_user_rotate(mob/living/user, rotation_type) - if(!istype(user) || !user.canUseTopic(parent, BE_CLOSE, NO_DEXTERY)) - return FALSE - return TRUE - -/datum/component/simple_rotation/proc/default_can_be_rotated(mob/user, rotation_type) - var/atom/movable/AM = parent - return !AM.anchored - -/datum/component/simple_rotation/proc/default_after_rotation(mob/user, rotation_type) - to_chat(user,"You [rotation_type == ROTATION_FLIP ? "flip" : "rotate"] [parent].") - -/atom/movable/proc/simple_rotate_clockwise() - set name = "Rotate Clockwise" - set category = "Object" - set src in oview(1) - var/datum/component/simple_rotation/rotcomp = GetComponent(/datum/component/simple_rotation) - if(rotcomp) - rotcomp.HandRot(null,usr,ROTATION_CLOCKWISE) - -/atom/movable/proc/simple_rotate_counterclockwise() - set name = "Rotate Counter-Clockwise" - set category = "Object" - set src in oview(1) - var/datum/component/simple_rotation/rotcomp = GetComponent(/datum/component/simple_rotation) - if(rotcomp) - rotcomp.HandRot(null,usr,ROTATION_COUNTERCLOCKWISE) - -/atom/movable/proc/simple_rotate_flip() - set name = "Flip" - set category = "Object" - set src in oview(1) - var/datum/component/simple_rotation/rotcomp = GetComponent(/datum/component/simple_rotation) - if(rotcomp) - rotcomp.HandRot(null,usr,ROTATION_FLIP) diff --git a/code/datums/components/shrapnel.dm b/code/datums/components/shrapnel.dm deleted file mode 100644 index f549fbbb342..00000000000 --- a/code/datums/components/shrapnel.dm +++ /dev/null @@ -1,38 +0,0 @@ -/datum/component/shrapnel - var/projectile_type - var/radius // shoots a projectile for every turf on this radius from the hit target - var/override_projectile_range - -/datum/component/shrapnel/Initialize(projectile_type, radius=1, override_projectile_range) - if(!isgun(parent) && !ismachinery(parent) && !isstructure(parent)) - return COMPONENT_INCOMPATIBLE - - src.projectile_type = projectile_type - src.radius = radius - src.override_projectile_range = override_projectile_range - -/datum/component/shrapnel/RegisterWithParent() - if(ismachinery(parent) || isstructure(parent) || isgun(parent)) // turrets, etc - RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit) - -/datum/component/shrapnel/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_PROJECTILE_ON_HIT)) - -/datum/component/shrapnel/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle) - do_shrapnel(firer, target) - -/datum/component/shrapnel/proc/do_shrapnel(mob/firer, atom/target) - if(radius < 1) - return - var/turf/target_turf = get_turf(target) - for(var/turf/shootat_turf in RANGE_TURFS(radius, target) - RANGE_TURFS(radius-1, target)) - var/obj/projectile/P = new projectile_type(target_turf) - - //Shooting Code: - P.range = radius+1 - if(override_projectile_range) - P.range = override_projectile_range - P.preparePixelProjectile(shootat_turf, target) - P.firer = firer // don't hit ourself that would be really annoying - P.permutated += target // don't hit the target we hit already with the flak - P.fire() diff --git a/code/datums/components/shrink.dm b/code/datums/components/shrink.dm deleted file mode 100644 index e9e5a1c659a..00000000000 --- a/code/datums/components/shrink.dm +++ /dev/null @@ -1,42 +0,0 @@ -/datum/component/shrink - var/olddens - var/oldopac - dupe_mode = COMPONENT_DUPE_HIGHLANDER - -/datum/component/shrink/Initialize(shrink_time) - if(!isatom(parent)) - return COMPONENT_INCOMPATIBLE - var/atom/parent_atom = parent - parent_atom.transform = parent_atom.transform.Scale(0.5,0.5) - olddens = parent_atom.density - oldopac = parent_atom.opacity - parent_atom.density = 0 - parent_atom.opacity = 0 - if(isliving(parent_atom)) - var/mob/living/L = parent_atom - L.add_movespeed_modifier(MOVESPEED_ID_SHRINK_RAY, update=TRUE, priority=100, multiplicative_slowdown=4, movement_type=MOVEMENT_GROUND) - if(iscarbon(L)) - var/mob/living/carbon/C = L - C.unequip_everything() - C.visible_message("[C]'s belongings fall off of [C.p_them()] as they shrink down!", - "Your belongings fall away as everything grows bigger!") - if(ishuman(C)) - var/mob/living/carbon/human/H = C - H.physiology.damage_resistance -= 100//carbons take double damage while shrunk - parent_atom.visible_message("[parent_atom] shrinks down to a tiny size!", - "Everything grows bigger!") - QDEL_IN(src, shrink_time) - - -/datum/component/shrink/Destroy() - var/atom/parent_atom = parent - parent_atom.transform = parent_atom.transform.Scale(2,2) - parent_atom.density = olddens - parent_atom.opacity = oldopac - if(isliving(parent_atom)) - var/mob/living/L = parent_atom - L.remove_movespeed_modifier(MOVESPEED_ID_SHRINK_RAY) - if(ishuman(L)) - var/mob/living/carbon/human/H = L - H.physiology.damage_resistance += 100 - ..() diff --git a/code/datums/components/slippery.dm b/code/datums/components/slippery.dm deleted file mode 100644 index 172f252d5af..00000000000 --- a/code/datums/components/slippery.dm +++ /dev/null @@ -1,19 +0,0 @@ -/datum/component/slippery - var/force_drop_items = FALSE - var/knockdown_time = 0 - var/paralyze_time = 0 - var/lube_flags - var/datum/callback/callback - -/datum/component/slippery/Initialize(_knockdown, _lube_flags = NONE, datum/callback/_callback, _paralyze, _force_drop = FALSE) - knockdown_time = max(_knockdown, 0) - paralyze_time = max(_paralyze, 0) - force_drop_items = _force_drop - lube_flags = _lube_flags - callback = _callback - RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Slip) - -/datum/component/slippery/proc/Slip(datum/source, atom/movable/AM) - var/mob/victim = AM - if(istype(victim) && !victim.is_flying() && victim.slip(knockdown_time, parent, lube_flags, paralyze_time, force_drop_items) && callback) - callback.Invoke(victim) diff --git a/code/datums/components/spawner.dm b/code/datums/components/spawner.dm deleted file mode 100644 index a89000626f0..00000000000 --- a/code/datums/components/spawner.dm +++ /dev/null @@ -1,51 +0,0 @@ -/datum/component/spawner - var/mob_types = list(/mob/living/simple_animal/hostile/carp) - var/spawn_time = 300 //30 seconds default - var/list/spawned_mobs = list() - var/spawn_delay = 0 - var/max_mobs = 5 - var/spawn_text = "emerges from" - var/list/faction = list("mining") - - - -/datum/component/spawner/Initialize(_mob_types, _spawn_time, _faction, _spawn_text, _max_mobs) - if(_spawn_time) - spawn_time=_spawn_time - if(_mob_types) - mob_types=_mob_types - if(_faction) - faction=_faction - if(_spawn_text) - spawn_text=_spawn_text - if(_max_mobs) - max_mobs=_max_mobs - - RegisterSignal(parent, list(COMSIG_PARENT_QDELETING), .proc/stop_spawning) - START_PROCESSING(SSprocessing, src) - -/datum/component/spawner/process(delta_time) - try_spawn_mob() - - -/datum/component/spawner/proc/stop_spawning(force) - STOP_PROCESSING(SSprocessing, src) - for(var/mob/living/simple_animal/L in spawned_mobs) - if(L.nest == src) - L.nest = null - spawned_mobs = null - -/datum/component/spawner/proc/try_spawn_mob() - var/atom/P = parent - if(spawned_mobs.len >= max_mobs) - return 0 - if(spawn_delay > world.time) - return 0 - spawn_delay = world.time + spawn_time - var/chosen_mob_type = pick(mob_types) - var/mob/living/simple_animal/L = new chosen_mob_type(P.loc) - L.flags_1 |= (P.flags_1 & ADMIN_SPAWNED_1) - spawned_mobs += L - L.nest = src - L.faction = src.faction - P.visible_message("[L] [spawn_text] [P].") diff --git a/code/datums/components/spill.dm b/code/datums/components/spill.dm deleted file mode 100644 index 1a9a526ec34..00000000000 --- a/code/datums/components/spill.dm +++ /dev/null @@ -1,57 +0,0 @@ -// This component is for forcing strange things into your pocket that fall out if you fall down -// Yes this exists purely for the spaghetti meme - -/datum/component/spill - can_transfer = TRUE - var/preexisting_item_flags - - var/list/droptext - var/list/dropsound - -// droptext is an arglist for visible_message -// dropsound is a list of potential sounds that gets picked from -/datum/component/spill/Initialize(list/_droptext, list/_dropsound) - if(!isitem(parent)) - return COMPONENT_INCOMPATIBLE - - if(_droptext && !islist(_droptext)) - _droptext = list(_droptext) - droptext = _droptext - - if(_dropsound && !islist(_dropsound)) - _dropsound = list(_dropsound) - dropsound = _dropsound - -/datum/component/spill/PostTransfer() - if(!isitem(parent)) - return COMPONENT_INCOMPATIBLE - -/datum/component/spill/RegisterWithParent() - RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/equip_react) - RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/drop_react) - var/obj/item/master = parent - preexisting_item_flags = master.item_flags - master.item_flags |= ITEM_SLOT_POCKET - -/datum/component/spill/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED)) - var/obj/item/master = parent - if(!(preexisting_item_flags & ITEM_SLOT_POCKET)) - master.item_flags &= ~ITEM_SLOT_POCKET - -/datum/component/spill/proc/equip_react(obj/item/source, mob/equipper, slot) - if(slot == SLOT_L_STORE || slot == SLOT_R_STORE) - RegisterSignal(equipper, COMSIG_LIVING_STATUS_KNOCKDOWN, .proc/knockdown_react, TRUE) - else - UnregisterSignal(equipper, COMSIG_LIVING_STATUS_KNOCKDOWN) - -/datum/component/spill/proc/drop_react(obj/item/source, mob/dropper) - UnregisterSignal(dropper, COMSIG_LIVING_STATUS_KNOCKDOWN) - -/datum/component/spill/proc/knockdown_react(mob/living/fool) - var/obj/item/master = parent - fool.dropItemToGround(master) - if(droptext) - fool.visible_message(arglist(droptext)) - if(dropsound) - playsound(master, pick(dropsound), 30) diff --git a/code/datums/components/spooky.dm b/code/datums/components/spooky.dm deleted file mode 100644 index 138fa930874..00000000000 --- a/code/datums/components/spooky.dm +++ /dev/null @@ -1,60 +0,0 @@ -/datum/component/spooky - var/too_spooky = TRUE //will it spawn a new instrument? - -/datum/component/spooky/Initialize() - RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/spectral_attack) - -/datum/component/spooky/proc/spectral_attack(datum/source, mob/living/carbon/C, mob/user) - if(ishuman(user)) //this weapon wasn't meant for mortals. - var/mob/living/carbon/human/U = user - if(!istype(U.dna.species, /datum/species/skeleton)) - U.adjustStaminaLoss(35) //Extra Damage - U.Jitter(35) - U.stuttering = 20 - if(U.getStaminaLoss() > 95) - to_chat(U, "Your ears weren't meant for this spectral sound.") - spectral_change(U) - return - - if(ishuman(C)) - var/mob/living/carbon/human/H = C - if(istype(H.dna.species, /datum/species/skeleton)) - return //undeads are unaffected by the spook-pocalypse. - if(istype(H.dna.species, /datum/species/zombie)) - H.adjustStaminaLoss(25) - H.Paralyze(15) //zombies can't resist the doot - C.Jitter(35) - C.stuttering = 20 - if((!istype(H.dna.species, /datum/species/skeleton)) && (!istype(H.dna.species, /datum/species/golem)) && (!istype(H.dna.species, /datum/species/android)) && (!istype(H.dna.species, /datum/species/jelly))) - C.adjustStaminaLoss(25) //boneless humanoids don't lose the will to live - to_chat(C, "DOOT") - spectral_change(H) - - else //the sound will spook monkeys. - C.Jitter(15) - C.stuttering = 20 - -/datum/component/spooky/proc/spectral_change(mob/living/carbon/human/H, mob/user) - if((H.getStaminaLoss() > 95) && (!istype(H.dna.species, /datum/species/skeleton)) && (!istype(H.dna.species, /datum/species/golem)) && (!istype(H.dna.species, /datum/species/android)) && (!istype(H.dna.species, /datum/species/jelly))) - H.Paralyze(20) - H.set_species(/datum/species/skeleton) - H.visible_message("[H] has given up on life as a mortal.") - var/T = get_turf(H) - if(too_spooky) - if(prob(30)) - new/obj/item/instrument/saxophone/spectral(T) - else if(prob(30)) - new/obj/item/instrument/trumpet/spectral(T) - else if(prob(30)) - new/obj/item/instrument/trombone/spectral(T) - else - to_chat(H, "The spooky gods forgot to ship your instrument. Better luck next unlife.") - to_chat(H, "You are the spooky skeleton!") - to_chat(H, "A new life and identity has begun. Help your fellow skeletons into bringing out the spooky-pocalypse. You haven't forgotten your past life, and are still beholden to past loyalties.") - change_name(H) //time for a new name! - -/datum/component/spooky/proc/change_name(mob/living/carbon/human/H) - var/t = sanitize_species_name(stripped_input(H, "Enter your new skeleton name", H.real_name, null, MAX_NAME_LEN)) - if(!t) - t = "spooky skeleton" - H.fully_replace_character_name(null, t) diff --git a/code/datums/components/squeak.dm b/code/datums/components/squeak.dm deleted file mode 100644 index f09b428eb05..00000000000 --- a/code/datums/components/squeak.dm +++ /dev/null @@ -1,90 +0,0 @@ -/datum/component/squeak - var/static/list/default_squeak_sounds = list('sound/items/toysqueak1.ogg'=1, 'sound/items/toysqueak2.ogg'=1, 'sound/items/toysqueak3.ogg'=1) - var/list/override_squeak_sounds - - var/squeak_chance = 100 - var/volume = 30 - - // This is so shoes don't squeak every step - var/steps = 0 - var/step_delay = 1 - - // This is to stop squeak spam from inhand usage - var/last_use = 0 - var/use_delay = 20 - -/datum/component/squeak/Initialize(custom_sounds, volume_override, chance_override, step_delay_override, use_delay_override) - if(!isatom(parent)) - return COMPONENT_INCOMPATIBLE - RegisterSignal(parent, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_BLOB_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_PARENT_ATTACKBY), .proc/play_squeak) - if(ismovable(parent)) - RegisterSignal(parent, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_IMPACT), .proc/play_squeak) - RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/play_squeak_crossed) - RegisterSignal(parent, COMSIG_MOVABLE_DISPOSING, .proc/disposing_react) - if(isitem(parent)) - RegisterSignal(parent, list(COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_OBJ, COMSIG_ITEM_HIT_REACT), .proc/play_squeak) - RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/use_squeak) - RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip) - RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop) - if(istype(parent, /obj/item/clothing/shoes)) - RegisterSignal(parent, COMSIG_SHOES_STEP_ACTION, .proc/step_squeak) - - override_squeak_sounds = custom_sounds - if(chance_override) - squeak_chance = chance_override - if(volume_override) - volume = volume_override - if(isnum(step_delay_override)) - step_delay = step_delay_override - if(isnum(use_delay_override)) - use_delay = use_delay_override - -/datum/component/squeak/proc/play_squeak() - if(prob(squeak_chance)) - if(!override_squeak_sounds) - playsound(parent, pickweight(default_squeak_sounds), volume, TRUE, -1) - else - playsound(parent, pickweight(override_squeak_sounds), volume, TRUE, -1) - -/datum/component/squeak/proc/step_squeak() - if(steps > step_delay) - play_squeak() - steps = 0 - else - steps++ - -/datum/component/squeak/proc/play_squeak_crossed(datum/source, atom/movable/AM) - if(isitem(AM)) - var/obj/item/I = AM - if(I.item_flags & ITEM_ABSTRACT) - return - else if(istype(AM, /obj/projectile)) - var/obj/projectile/P = AM - if(P.original != parent) - return - if(istype(AM, /obj/effect/dummy/phased_mob)) //don't squeek if they're in a phased/jaunting container. - return - var/atom/current_parent = parent - if(isturf(current_parent.loc)) - play_squeak() - -/datum/component/squeak/proc/use_squeak() - if(last_use + use_delay < world.time) - last_use = world.time - play_squeak() - -/datum/component/squeak/proc/on_equip(datum/source, mob/equipper, slot) - RegisterSignal(equipper, COMSIG_MOVABLE_DISPOSING, .proc/disposing_react, TRUE) - -/datum/component/squeak/proc/on_drop(datum/source, mob/user) - UnregisterSignal(user, COMSIG_MOVABLE_DISPOSING) - -// Disposal pipes related shit -/datum/component/squeak/proc/disposing_react(datum/source, obj/structure/disposalholder/holder, obj/machinery/disposal/source) - //We don't need to worry about unregistering this signal as it will happen for us automaticaly when the holder is qdeleted - RegisterSignal(holder, COMSIG_ATOM_DIR_CHANGE, .proc/holder_dir_change) - -/datum/component/squeak/proc/holder_dir_change(datum/source, old_dir, new_dir) - //If the dir changes it means we're going through a bend in the pipes, let's pretend we bumped the wall - if(old_dir != new_dir) - play_squeak() diff --git a/code/datums/components/stationloving.dm b/code/datums/components/stationloving.dm deleted file mode 100644 index 65a4d765b88..00000000000 --- a/code/datums/components/stationloving.dm +++ /dev/null @@ -1,90 +0,0 @@ -/datum/component/stationloving - dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS - var/inform_admins = FALSE - var/disallow_soul_imbue = TRUE - var/allow_death = FALSE - -/datum/component/stationloving/Initialize(inform_admins = FALSE, allow_death = FALSE) - if(!ismovable(parent)) - return COMPONENT_INCOMPATIBLE - RegisterSignal(parent, list(COMSIG_MOVABLE_Z_CHANGED), .proc/check_in_bounds) - RegisterSignal(parent, list(COMSIG_MOVABLE_SECLUDED_LOCATION), .proc/relocate) - RegisterSignal(parent, list(COMSIG_PARENT_PREQDELETED), .proc/check_deletion) - RegisterSignal(parent, list(COMSIG_ITEM_IMBUE_SOUL), .proc/check_soul_imbue) - RegisterSignal(parent, list(COMSIG_ITEM_MARK_RETRIEVAL), .proc/check_mark_retrieval) - src.inform_admins = inform_admins - src.allow_death = allow_death - check_in_bounds() // Just in case something is being created outside of station/centcom - -/datum/component/stationloving/InheritComponent(datum/component/stationloving/newc, original, list/arguments) - if (original) - if (istype(newc)) - inform_admins = newc.inform_admins - allow_death = newc.allow_death - else if (LAZYLEN(arguments)) - inform_admins = arguments[1] - -/datum/component/stationloving/proc/relocate() - var/targetturf = find_safe_turf() - if(!targetturf) - if(GLOB.blobstart.len > 0) - targetturf = get_turf(pick(GLOB.blobstart)) - else - CRASH("Unable to find a blobstart landmark") - - var/atom/movable/AM = parent - AM.forceMove(targetturf) - to_chat(get(parent, /mob), "You can't help but feel that you just lost something back there...") - // move the disc, so ghosts remain orbiting it even if it's "destroyed" - return targetturf - -/datum/component/stationloving/proc/check_in_bounds() - if(in_bounds()) - return - else - var/turf/currentturf = get_turf(src) - var/turf/targetturf = relocate() - log_game("[parent] has been moved out of bounds in [loc_name(currentturf)]. Moving it to [loc_name(targetturf)].") - if(inform_admins) - message_admins("[parent] has been moved out of bounds in [ADMIN_VERBOSEJMP(currentturf)]. Moving it to [ADMIN_VERBOSEJMP(targetturf)].") - -/datum/component/stationloving/proc/check_soul_imbue() - return disallow_soul_imbue - -/datum/component/stationloving/proc/check_mark_retrieval() - return COMPONENT_BLOCK_MARK_RETRIEVAL - -/datum/component/stationloving/proc/in_bounds() - var/static/list/allowed_shuttles = typecacheof(list(/area/shuttle/syndicate, /area/shuttle/escape, /area/shuttle/pod_1, /area/shuttle/pod_2, /area/shuttle/pod_3, /area/shuttle/pod_4)) - var/static/list/disallowed_centcom_areas = typecacheof(list(/area/abductor_ship, /area/awaymission/errorroom)) - var/turf/T = get_turf(parent) - if (!T) - return FALSE - var/area/A = T.loc - if (is_station_level(T.z)) - return TRUE - if (is_centcom_level(T.z)) - if (is_type_in_typecache(A, disallowed_centcom_areas)) - return FALSE - return TRUE - if (is_reserved_level(T.z)) - if (is_type_in_typecache(A, allowed_shuttles)) - return TRUE - - return FALSE - -/datum/component/stationloving/proc/check_deletion(datum/source, force) // TRUE = interrupt deletion, FALSE = proceed with deletion - - var/turf/T = get_turf(parent) - - if(inform_admins && force) - message_admins("[parent] has been !!force deleted!! in [ADMIN_VERBOSEJMP(T)].") - log_game("[parent] has been !!force deleted!! in [loc_name(T)].") - - if(!force && !allow_death) - var/turf/targetturf = relocate() - log_game("[parent] has been destroyed in [loc_name(T)]. Moving it to [loc_name(targetturf)].") - if(inform_admins) - message_admins("[parent] has been destroyed in [ADMIN_VERBOSEJMP(T)]. Moving it to [ADMIN_VERBOSEJMP(targetturf)].") - return TRUE - return FALSE diff --git a/code/datums/components/storage/concrete/_concrete.dm b/code/datums/components/storage/concrete/_concrete.dm deleted file mode 100644 index b7f3e774d91..00000000000 --- a/code/datums/components/storage/concrete/_concrete.dm +++ /dev/null @@ -1,201 +0,0 @@ - -// External storage-related logic: -// /mob/proc/ClickOn() in /_onclick/click.dm - clicking items in storages -// /mob/living/Move() in /modules/mob/living/living.dm - hiding storage boxes on mob movement - -/datum/component/storage/concrete - can_transfer = TRUE - var/drop_all_on_deconstruct = TRUE - var/drop_all_on_destroy = FALSE - var/transfer_contents_on_component_transfer = FALSE - var/list/datum/component/storage/slaves = list() - - var/list/_contents_limbo // Where objects go to live mid transfer - var/list/_user_limbo // The last users before the component started moving - -/datum/component/storage/concrete/Initialize() - . = ..() - RegisterSignal(parent, COMSIG_ATOM_CONTENTS_DEL, .proc/on_contents_del) - RegisterSignal(parent, COMSIG_OBJ_DECONSTRUCT, .proc/on_deconstruct) - -/datum/component/storage/concrete/Destroy() - var/atom/real_location = real_location() - for(var/atom/_A in real_location) - _A.mouse_opacity = initial(_A.mouse_opacity) - if(drop_all_on_destroy) - do_quick_empty() - for(var/i in slaves) - var/datum/component/storage/slave = i - slave.change_master(null) - QDEL_LIST(_contents_limbo) - _user_limbo = null - return ..() - -/datum/component/storage/concrete/master() - return src - -/datum/component/storage/concrete/real_location() - return parent - -/datum/component/storage/concrete/PreTransfer() - if(is_using) - _user_limbo = is_using.Copy() - close_all() - if(transfer_contents_on_component_transfer) - _contents_limbo = list() - for(var/atom/movable/AM in parent) - _contents_limbo += AM - AM.moveToNullspace() - -/datum/component/storage/concrete/PostTransfer() - if(!isatom(parent)) - return COMPONENT_INCOMPATIBLE - if(transfer_contents_on_component_transfer) - for(var/i in _contents_limbo) - var/atom/movable/AM = i - AM.forceMove(parent) - _contents_limbo = null - if(_user_limbo) - for(var/i in _user_limbo) - show_to(i) - _user_limbo = null - -/datum/component/storage/concrete/_insert_physical_item(obj/item/I, override = FALSE) - . = TRUE - var/atom/real_location = real_location() - if(I.loc != real_location) - I.forceMove(real_location) - refresh_mob_views() - -/datum/component/storage/concrete/refresh_mob_views() - . = ..() - for(var/i in slaves) - var/datum/component/storage/slave = i - slave.refresh_mob_views() - -/datum/component/storage/concrete/emp_act(datum/source, severity) - if(emp_shielded) - return - var/atom/real_location = real_location() - for(var/i in real_location) - var/atom/A = i - A.emp_act(severity) - -/datum/component/storage/concrete/proc/on_slave_link(datum/component/storage/S) - if(S == src) - return FALSE - slaves += S - return TRUE - -/datum/component/storage/concrete/proc/on_slave_unlink(datum/component/storage/S) - slaves -= S - return FALSE - -/datum/component/storage/concrete/proc/on_contents_del(datum/source, atom/A) - var/atom/real_location = parent - if(A in real_location) - usr = null - remove_from_storage(A, null) - -/datum/component/storage/concrete/proc/on_deconstruct(datum/source, disassembled) - if(drop_all_on_deconstruct) - do_quick_empty() - -/datum/component/storage/concrete/can_see_contents() - . = ..() - for(var/i in slaves) - var/datum/component/storage/slave = i - . |= slave.can_see_contents() - -//Resets screen loc and other vars of something being removed from storage. -/datum/component/storage/concrete/_removal_reset(atom/movable/thing) - thing.layer = initial(thing.layer) - thing.plane = initial(thing.plane) - thing.mouse_opacity = initial(thing.mouse_opacity) - if(thing.maptext) - thing.maptext = "" - -/datum/component/storage/concrete/remove_from_storage(atom/movable/AM, atom/new_location) - //Cache this as it should be reusable down the bottom, will not apply if anyone adds a sleep to dropped - //or moving objects, things that should never happen - var/atom/parent = src.parent - var/list/seeing_mobs = can_see_contents() - for(var/mob/M in seeing_mobs) - M.client.screen -= AM - if(ismob(parent.loc) && isitem(AM)) - var/obj/item/I = AM - var/mob/M = parent.loc - I.dropped(M) - I.item_flags &= ~ITEM_IN_STORAGE - if(new_location) - //Reset the items values - _removal_reset(AM) - AM.forceMove(new_location) - //We don't want to call this if the item is being destroyed - AM.on_exit_storage(src) - else - //Being destroyed, just move to nullspace now (so it's not in contents for the icon update) - AM.moveToNullspace() - refresh_mob_views() - if(isobj(parent)) - var/obj/O = parent - O.update_icon() - return TRUE - -/datum/component/storage/concrete/proc/slave_can_insert_object(datum/component/storage/slave, obj/item/I, stop_messages = FALSE, mob/M) - return TRUE - -/datum/component/storage/concrete/proc/handle_item_insertion_from_slave(datum/component/storage/slave, obj/item/I, prevent_warning = FALSE, M) - . = handle_item_insertion(I, prevent_warning, M, slave) - if(. && !prevent_warning) - slave.mob_item_insertion_feedback(usr, M, I) - -/datum/component/storage/concrete/handle_item_insertion(obj/item/I, prevent_warning = FALSE, mob/M, datum/component/storage/remote) //Remote is null or the slave datum - var/datum/component/storage/concrete/master = master() - var/atom/parent = src.parent - var/moved = FALSE - if(!istype(I)) - return FALSE - if(M) - if(!M.temporarilyRemoveItemFromInventory(I)) - return FALSE - else - moved = TRUE //At this point if the proc fails we need to manually move the object back to the turf/mob/whatever. - if(I.pulledby) - I.pulledby.stop_pulling() - if(silent) - prevent_warning = TRUE - if(!_insert_physical_item(I)) - if(moved) - if(M) - if(!M.put_in_active_hand(I)) - I.forceMove(parent.drop_location()) - else - I.forceMove(parent.drop_location()) - return FALSE - I.on_enter_storage(master) - I.item_flags |= ITEM_IN_STORAGE - refresh_mob_views() - I.mouse_opacity = MOUSE_OPACITY_OPAQUE //So you can click on the area around the item to equip it, instead of having to pixel hunt - if(M) - if(M.client && M.active_storage != src) - M.client.screen -= I - if(M.observers && M.observers.len) - for(var/i in M.observers) - var/mob/dead/observe = i - if(observe.client && observe.active_storage != src) - observe.client.screen -= I - if(!remote) - parent.add_fingerprint(M) - if(!prevent_warning) - mob_item_insertion_feedback(usr, M, I) - update_icon() - return TRUE - -/datum/component/storage/concrete/update_icon() - if(isobj(parent)) - var/obj/O = parent - O.update_icon() - for(var/i in slaves) - var/datum/component/storage/slave = i - slave.update_icon() diff --git a/code/datums/components/storage/concrete/bag_of_holding.dm b/code/datums/components/storage/concrete/bag_of_holding.dm deleted file mode 100644 index 942cf86bbe0..00000000000 --- a/code/datums/components/storage/concrete/bag_of_holding.dm +++ /dev/null @@ -1,27 +0,0 @@ -/datum/component/storage/concrete/bluespace/bag_of_holding/handle_item_insertion(obj/item/W, prevent_warning = FALSE, mob/living/user) - var/atom/A = parent - if(A == W) //don't put yourself into yourself. - return - var/list/obj/item/storage/backpack/holding/matching = typecache_filter_list(W.get_all_contents(), typecacheof(/obj/item/storage/backpack/holding)) - matching -= A - if(istype(W, /obj/item/storage/backpack/holding) || matching.len) - var/safety = alert(user, "Doing this will have extremely dire consequences for the station and its crew. Be sure you know what you're doing.", "Put in [A.name]?", "Abort", "Proceed") - if(safety != "Proceed" || QDELETED(A) || QDELETED(W) || QDELETED(user) || !user.canUseTopic(A, BE_CLOSE, iscarbon(user))) - return - var/turf/loccheck = get_turf(A) - if(is_reebe(loccheck.z)) - user.visible_message("An unseen force knocks [user] to the ground!", "\"I think not!\"") - user.Paralyze(60) - return - to_chat(user, "The Bluespace interfaces of the two devices catastrophically malfunction!") - qdel(W) - playsound(loccheck,'sound/effects/supermatter.ogg', 200, TRUE) - - message_admins("[ADMIN_LOOKUPFLW(user)] detonated a bag of holding at [ADMIN_VERBOSEJMP(loccheck)].") - log_game("[key_name(user)] detonated a bag of holding at [loc_name(loccheck)].") - - user.gib(TRUE, TRUE, TRUE) - new/obj/singularity/boh_tear(loccheck) - qdel(A) - return - . = ..() diff --git a/code/datums/components/storage/concrete/bluespace.dm b/code/datums/components/storage/concrete/bluespace.dm deleted file mode 100644 index 1b0934661e8..00000000000 --- a/code/datums/components/storage/concrete/bluespace.dm +++ /dev/null @@ -1,23 +0,0 @@ -/datum/component/storage/concrete/bluespace - var/dumping_range = 8 - var/dumping_sound = 'sound/items/pshoom.ogg' - var/alt_sound = 'sound/items/pshoom_2.ogg' - -/datum/component/storage/concrete/bluespace/dump_content_at(atom/dest, mob/M) - var/atom/A = parent - if(A.Adjacent(M)) - var/atom/dumping_location = dest.get_dumping_location() - var/turf/bagT = get_turf(parent) - var/turf/destT = get_turf(dumping_location) - if(destT && bagT && bagT.z == destT.z && get_dist(M, dumping_location) < dumping_range) - if(dumping_location.storage_contents_dump_act(src, M)) - if(alt_sound && prob(1)) - playsound(src, alt_sound, 40, TRUE) - else - playsound(src, dumping_sound, 40, TRUE) - M.Beam(dumping_location, icon_state="rped_upgrade", time=5) - return TRUE - to_chat(M, "The [A.name] buzzes.") - playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) - return FALSE - diff --git a/code/datums/components/storage/concrete/implant.dm b/code/datums/components/storage/concrete/implant.dm deleted file mode 100644 index 405b3098fe5..00000000000 --- a/code/datums/components/storage/concrete/implant.dm +++ /dev/null @@ -1,18 +0,0 @@ -/datum/component/storage/concrete/implant - max_w_class = WEIGHT_CLASS_NORMAL - max_combined_w_class = 6 - max_items = 2 - drop_all_on_destroy = TRUE - drop_all_on_deconstruct = TRUE - silent = TRUE - allow_big_nesting = TRUE - -/datum/component/storage/concrete/implant/Initialize() - . = ..() - set_holdable(null, list(/obj/item/disk/nuclear)) - -/datum/component/storage/concrete/implant/InheritComponent(datum/component/storage/concrete/implant/I, original) - if(!istype(I)) - return ..() - max_combined_w_class += I.max_combined_w_class - max_items += I.max_items diff --git a/code/datums/components/storage/concrete/pockets.dm b/code/datums/components/storage/concrete/pockets.dm deleted file mode 100644 index 5a82c95a82f..00000000000 --- a/code/datums/components/storage/concrete/pockets.dm +++ /dev/null @@ -1,96 +0,0 @@ -/datum/component/storage/concrete/pockets - max_items = 2 - max_w_class = WEIGHT_CLASS_SMALL - max_combined_w_class = 50 - rustle_sound = FALSE - -/datum/component/storage/concrete/pockets/handle_item_insertion(obj/item/I, prevent_warning, mob/user) - . = ..() - if(. && silent && !prevent_warning) - if(quickdraw) - to_chat(user, "You discreetly slip [I] into [parent]. Alt-click [parent] to remove it.") - else - to_chat(user, "You discreetly slip [I] into [parent].") - -/datum/component/storage/concrete/pockets - max_w_class = WEIGHT_CLASS_NORMAL - -/datum/component/storage/concrete/pockets/small - max_items = 1 - max_w_class = WEIGHT_CLASS_SMALL - attack_hand_interact = FALSE - -/datum/component/storage/concrete/pockets/tiny - max_items = 1 - max_w_class = WEIGHT_CLASS_TINY - attack_hand_interact = FALSE - -/datum/component/storage/concrete/pockets/small/fedora/Initialize() - . = ..() - var/static/list/exception_cache = typecacheof(list( - /obj/item/katana, /obj/item/toy/katana, /obj/item/nullrod/claymore/katana, - /obj/item/energy_katana, /obj/item/gun/ballistic/automatic/tommygun - )) - exception_hold = exception_cache - -/datum/component/storage/concrete/pockets/small/fedora/detective - attack_hand_interact = TRUE // so the detectives would discover pockets in their hats - -/datum/component/storage/concrete/pockets/shoes - attack_hand_interact = FALSE - quickdraw = TRUE - silent = TRUE - -/datum/component/storage/concrete/pockets/shoes/Initialize() - . = ..() - set_holdable(list( - /obj/item/kitchen/knife, /obj/item/switchblade, /obj/item/pen, - /obj/item/scalpel, /obj/item/reagent_containers/syringe, /obj/item/dnainjector, - /obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/dropper, - /obj/item/implanter, /obj/item/tool/screwdriver, /obj/item/weldingtool/mini, - /obj/item/firing_pin - ), - list(/obj/item/tool/screwdriver/power) - ) - -/datum/component/storage/concrete/pockets/shoes/clown/Initialize() - . = ..() - set_holdable(list( - /obj/item/kitchen/knife, /obj/item/switchblade, /obj/item/pen, - /obj/item/scalpel, /obj/item/reagent_containers/syringe, /obj/item/dnainjector, - /obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/dropper, - /obj/item/implanter, /obj/item/tool/screwdriver, /obj/item/weldingtool/mini, - /obj/item/firing_pin, /obj/item/bikehorn), - list(/obj/item/tool/screwdriver/power) - ) - -/datum/component/storage/concrete/pockets/pocketprotector - max_items = 3 - max_w_class = WEIGHT_CLASS_TINY - var/atom/original_parent - -/datum/component/storage/concrete/pockets/pocketprotector/Initialize() - original_parent = parent - . = ..() - set_holdable(list( //Same items as a PDA - /obj/item/pen, - /obj/item/toy/crayon, - /obj/item/lipstick, - /obj/item/flashlight/pen, - /obj/item/clothing/mask/cigarette) - ) - -/datum/component/storage/concrete/pockets/pocketprotector/real_location() - // if the component is reparented to a jumpsuit, the items still go in the protector - return original_parent - -/datum/component/storage/concrete/pockets/helmet - quickdraw = TRUE - max_combined_w_class = 6 - -/datum/component/storage/concrete/pockets/helmet/Initialize() - . = ..() - set_holdable(list(/obj/item/reagent_containers/food/drinks/bottle/vodka, - /obj/item/reagent_containers/food/drinks/bottle/molotov, - /obj/item/reagent_containers/food/drinks/drinkingglass, - /obj/item/ammo_box/a762)) diff --git a/code/datums/components/storage/concrete/rped.dm b/code/datums/components/storage/concrete/rped.dm deleted file mode 100644 index 455eb985f09..00000000000 --- a/code/datums/components/storage/concrete/rped.dm +++ /dev/null @@ -1,33 +0,0 @@ -/datum/component/storage/concrete/rped - collection_mode = COLLECT_EVERYTHING - allow_quick_gather = TRUE - allow_quick_empty = TRUE - click_gather = TRUE - max_w_class = WEIGHT_CLASS_NORMAL - max_combined_w_class = 100 - max_items = 50 - display_numerical_stacking = TRUE - -/datum/component/storage/concrete/rped/can_be_inserted(obj/item/I, stop_messages, mob/M) - . = ..() - if(!I.get_part_rating()) - if (!stop_messages) - to_chat(M, "[parent] only accepts machine parts!") - return FALSE - -/datum/component/storage/concrete/bluespace/rped - collection_mode = COLLECT_EVERYTHING - allow_quick_gather = TRUE - allow_quick_empty = TRUE - click_gather = TRUE - max_w_class = WEIGHT_CLASS_BULKY // can fit vending refills - max_combined_w_class = 800 - max_items = 400 - display_numerical_stacking = TRUE - -/datum/component/storage/concrete/bluespace/rped/can_be_inserted(obj/item/I, stop_messages, mob/M) - . = ..() - if(!I.get_part_rating()) - if (!stop_messages) - to_chat(M, "[parent] only accepts machine parts!") - return FALSE diff --git a/code/datums/components/storage/concrete/stack.dm b/code/datums/components/storage/concrete/stack.dm deleted file mode 100644 index 1f0c44c6502..00000000000 --- a/code/datums/components/storage/concrete/stack.dm +++ /dev/null @@ -1,67 +0,0 @@ -//Stack-only storage. -/datum/component/storage/concrete/stack - display_numerical_stacking = TRUE - var/max_combined_stack_amount = 300 - max_w_class = WEIGHT_CLASS_NORMAL - max_combined_w_class = WEIGHT_CLASS_NORMAL * 14 - -/datum/component/storage/concrete/stack/proc/total_stack_amount() - . = 0 - var/atom/real_location = real_location() - for(var/i in real_location) - var/obj/item/stack/S = i - if(!istype(S)) - continue - . += S.amount - -/datum/component/storage/concrete/stack/proc/remaining_space() - return max(0, max_combined_stack_amount - total_stack_amount()) - -//emptying procs do not need modification as stacks automatically merge. - -/datum/component/storage/concrete/stack/_insert_physical_item(obj/item/I, override = FALSE) - if(!istype(I, /obj/item/stack)) - if(override) - return ..() - return FALSE - var/atom/real_location = real_location() - var/obj/item/stack/S = I - var/can_insert = min(S.amount, remaining_space()) - if(!can_insert) - return FALSE - for(var/i in real_location) //combine. - if(QDELETED(I)) - return - var/obj/item/stack/_S = i - if(!istype(_S)) - continue - if(_S.merge_type == S.merge_type) - _S.add(can_insert) - S.use(can_insert, TRUE) - return TRUE - return ..(S.change_stack(null, can_insert), override) - -/datum/component/storage/concrete/stack/remove_from_storage(obj/item/I, atom/new_location) - var/atom/real_location = real_location() - var/obj/item/stack/S = I - if(!istype(S)) - return ..() - if(S.amount > S.max_amount) - var/overrun = S.amount - S.max_amount - S.amount = S.max_amount - var/obj/item/stack/temp = new S.type(real_location, overrun) - handle_item_insertion(temp) - return ..(S, new_location) - -/datum/component/storage/concrete/stack/_process_numerical_display() - var/atom/real_location = real_location() - . = list() - for(var/i in real_location) - var/obj/item/stack/I = i - if(!istype(I) || QDELETED(I)) //We're specialized stack storage, just ignore non stacks. - continue - if(!.[I.merge_type]) - .[I.merge_type] = new /datum/numbered_display(I, I.amount) - else - var/datum/numbered_display/ND = .[I.merge_type] - ND.number += I.amount diff --git a/code/datums/components/storage/concrete/wallet.dm b/code/datums/components/storage/concrete/wallet.dm deleted file mode 100644 index 7122474afe3..00000000000 --- a/code/datums/components/storage/concrete/wallet.dm +++ /dev/null @@ -1,18 +0,0 @@ -/datum/component/storage/concrete/wallet/on_alt_click(datum/source, mob/user) - if(!isliving(user) || !user.CanReach(parent)) - return - if(locked) - to_chat(user, "[parent] seems to be locked!") - return - - var/obj/item/storage/wallet/A = parent - if(istype(A) && A.front_id && !issilicon(user) && !(A.item_flags & ITEM_IN_STORAGE)) //if it's a wallet in storage seeing the full inventory is more useful - var/obj/item/I = A.front_id - A.add_fingerprint(user) - remove_from_storage(I, get_turf(user)) - if(!user.put_in_hands(I)) - to_chat(user, "You fumble for [I] and it falls on the floor.") - return - user.visible_message("[user] draws [I] from [parent]!", "You draw [I] from [parent].") - return - ..() diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm deleted file mode 100644 index 300ac6170c7..00000000000 --- a/code/datums/components/storage/storage.dm +++ /dev/null @@ -1,810 +0,0 @@ -#define COLLECT_ONE 0 -#define COLLECT_EVERYTHING 1 -#define COLLECT_SAME 2 - -#define DROP_NOTHING 0 -#define DROP_AT_PARENT 1 -#define DROP_AT_LOCATION 2 - -// External storage-related logic: -// /mob/proc/ClickOn() in /_onclick/click.dm - clicking items in storages -// /mob/living/Move() in /modules/mob/living/living.dm - hiding storage boxes on mob movement - -/datum/component/storage - dupe_mode = COMPONENT_DUPE_UNIQUE - var/datum/component/storage/concrete/master //If not null, all actions act on master and this is just an access point. - - var/list/can_hold //if this is set, only items, and their children, will fit - var/list/cant_hold //if this is set, items, and their children, won't fit - var/list/exception_hold //if set, these items will be the exception to the max size of object that can fit. - - var/can_hold_description - - var/list/mob/is_using //lazy list of mobs looking at the contents of this storage. - - var/locked = FALSE //when locked nothing can see inside or use it. - - var/max_w_class = WEIGHT_CLASS_SMALL //max size of objects that will fit. - var/max_combined_w_class = 14 //max combined sizes of objects that will fit. - var/max_items = 7 //max number of objects that will fit. - - var/emp_shielded = FALSE - - var/silent = FALSE //whether this makes a message when things are put in. - var/click_gather = FALSE //whether this can be clicked on items to pick it up rather than the other way around. - var/rustle_sound = TRUE //play rustle sound on interact. - var/allow_quick_empty = FALSE //allow empty verb which allows dumping on the floor of everything inside quickly. - var/allow_quick_gather = FALSE //allow toggle mob verb which toggles collecting all items from a tile. - - var/collection_mode = COLLECT_EVERYTHING - - var/insert_preposition = "in" //you put things "in" a bag, but "on" a tray. - - var/display_numerical_stacking = FALSE //stack things of the same type and show as a single object with a number. - - var/atom/movable/screen/storage/boxes //storage display object - var/atom/movable/screen/close/closer //close button object - - var/allow_big_nesting = FALSE //allow storage objects of the same or greater size. - - var/attack_hand_interact = TRUE //interact on attack hand. - var/quickdraw = FALSE //altclick interact - - var/datum/action/item_action/storage_gather_mode/modeswitch_action - - //Screen variables: Do not mess with these vars unless you know what you're doing. They're not defines so storage that isn't in the same location can be supported in the future. - var/screen_max_columns = 7 //These two determine maximum screen sizes. - var/screen_max_rows = INFINITY - var/screen_pixel_x = 16 //These two are pixel values for screen loc of boxes and closer - var/screen_pixel_y = 16 - var/screen_start_x = 3 //These two are where the storage starts being rendered, screen_loc wise. - var/screen_start_y = 1 - //End - -/datum/component/storage/Initialize(datum/component/storage/concrete/master) - if(!isatom(parent)) - return COMPONENT_INCOMPATIBLE - if(master) - change_master(master) - boxes = new(null, src) - closer = new(null, src) - orient2hud() - - RegisterSignal(parent, COMSIG_CONTAINS_STORAGE, .proc/on_check) - RegisterSignal(parent, COMSIG_IS_STORAGE_LOCKED, .proc/check_locked) - RegisterSignal(parent, COMSIG_TRY_STORAGE_SHOW, .proc/signal_show_attempt) - RegisterSignal(parent, COMSIG_TRY_STORAGE_INSERT, .proc/signal_insertion_attempt) - RegisterSignal(parent, COMSIG_TRY_STORAGE_CAN_INSERT, .proc/signal_can_insert) - RegisterSignal(parent, COMSIG_TRY_STORAGE_TAKE_TYPE, .proc/signal_take_type) - RegisterSignal(parent, COMSIG_TRY_STORAGE_FILL_TYPE, .proc/signal_fill_type) - RegisterSignal(parent, COMSIG_TRY_STORAGE_SET_LOCKSTATE, .proc/set_locked) - RegisterSignal(parent, COMSIG_TRY_STORAGE_TAKE, .proc/signal_take_obj) - RegisterSignal(parent, COMSIG_TRY_STORAGE_QUICK_EMPTY, .proc/signal_quick_empty) - RegisterSignal(parent, COMSIG_TRY_STORAGE_HIDE_FROM, .proc/signal_hide_attempt) - RegisterSignal(parent, COMSIG_TRY_STORAGE_HIDE_ALL, .proc/close_all) - RegisterSignal(parent, COMSIG_TRY_STORAGE_RETURN_INVENTORY, .proc/signal_return_inv) - - RegisterSignal(parent, COMSIG_TOPIC, .proc/topic_handle) - - RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/attackby) - - RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand) - RegisterSignal(parent, COMSIG_ATOM_ATTACK_PAW, .proc/on_attack_hand) - RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, .proc/emp_act) - RegisterSignal(parent, COMSIG_ATOM_ATTACK_GHOST, .proc/show_to_ghost) - RegisterSignal(parent, COMSIG_ATOM_ENTERED, .proc/refresh_mob_views) - RegisterSignal(parent, COMSIG_ATOM_EXITED, .proc/_remove_and_refresh) - RegisterSignal(parent, COMSIG_ATOM_CANREACH, .proc/canreach_react) - - RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, .proc/preattack_intercept) - RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/attack_self) - RegisterSignal(parent, COMSIG_ITEM_PICKUP, .proc/signal_on_pickup) - - RegisterSignal(parent, COMSIG_MOVABLE_POST_THROW, .proc/close_all) - RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/on_move) - - RegisterSignal(parent, COMSIG_CLICK_ALT, .proc/on_alt_click) - RegisterSignal(parent, COMSIG_MOUSEDROP_ONTO, .proc/mousedrop_onto) - RegisterSignal(parent, COMSIG_MOUSEDROPPED_ONTO, .proc/mousedrop_receive) - - update_actions() - -/datum/component/storage/Destroy() - close_all() - QDEL_NULL(boxes) - QDEL_NULL(closer) - LAZYCLEARLIST(is_using) - return ..() - -/datum/component/storage/PreTransfer() - update_actions() - -/datum/component/storage/proc/set_holdable(can_hold_list, cant_hold_list) - can_hold_description = generate_hold_desc(can_hold_list) - - if (can_hold_list != null) - can_hold = typecacheof(can_hold_list) - - if (cant_hold_list != null) - cant_hold = typecacheof(cant_hold_list) - -/datum/component/storage/proc/generate_hold_desc(can_hold_list) - var/list/desc = list() - - for(var/valid_type in can_hold_list) - var/obj/item/valid_item = valid_type - desc += "\a [initial(valid_item.name)]" - - return "\n\t[desc.Join("\n\t")]" - -/datum/component/storage/proc/update_actions() - QDEL_NULL(modeswitch_action) - if(!isitem(parent) || !allow_quick_gather) - return - var/obj/item/I = parent - modeswitch_action = new(I) - RegisterSignal(modeswitch_action, COMSIG_ACTION_TRIGGER, .proc/action_trigger) - if(I.obj_flags & ITEM_IN_INVENTORY) - var/mob/M = I.loc - if(!istype(M)) - return - modeswitch_action.Grant(M) - -/datum/component/storage/proc/change_master(datum/component/storage/concrete/new_master) - if(new_master == src || (!isnull(new_master) && !istype(new_master))) - return FALSE - if(master) - master.on_slave_unlink(src) - master = new_master - if(master) - master.on_slave_link(src) - return TRUE - -/datum/component/storage/proc/master() - if(master == src) - return //infinite loops yo. - return master - -/datum/component/storage/proc/real_location() - var/datum/component/storage/concrete/master = master() - return master? master.real_location() : null - -/datum/component/storage/proc/canreach_react(datum/source, list/next) - var/datum/component/storage/concrete/master = master() - if(!master) - return - . = COMPONENT_BLOCK_REACH - next += master.parent - for(var/i in master.slaves) - var/datum/component/storage/slave = i - next += slave.parent - -/datum/component/storage/proc/on_move() - var/atom/A = parent - for(var/mob/living/L in can_see_contents()) - if(!L.CanReach(A)) - hide_from(L) - -/datum/component/storage/proc/attack_self(datum/source, mob/M) - if(locked) - to_chat(M, "[parent] seems to be locked!") - return FALSE - if((M.get_active_held_item() == parent) && allow_quick_empty) - quick_empty(M) - -/datum/component/storage/proc/preattack_intercept(datum/source, obj/O, mob/M, params) - if(!isitem(O) || !click_gather || SEND_SIGNAL(O, COMSIG_CONTAINS_STORAGE)) - return FALSE - . = COMPONENT_NO_ATTACK - if(locked) - to_chat(M, "[parent] seems to be locked!") - return FALSE - var/obj/item/I = O - if(collection_mode == COLLECT_ONE) - if(can_be_inserted(I, null, M)) - handle_item_insertion(I, null, M) - return - if(!isturf(I.loc)) - return - var/list/things = I.loc.contents.Copy() - if(collection_mode == COLLECT_SAME) - things = typecache_filter_list(things, typecacheof(I.type)) - var/len = length(things) - if(!len) - to_chat(M, "You failed to pick up anything with [parent]!") - return - var/datum/progressbar/progress = new(M, len, I.loc) - var/list/rejections = list() - while(do_after(M, 10, parent, DO_AFTER_NO_PROGRESS, additional_checks = CALLBACK(src, .proc/handle_mass_pickup, things, I.loc, rejections, progress))) - stoplag(1) - qdel(progress) - to_chat(M, "You put everything you could [insert_preposition] [parent].") - -/datum/component/storage/proc/handle_mass_item_insertion(list/things, datum/component/storage/src_object, mob/user, datum/progressbar/progress) - var/atom/source_real_location = src_object.real_location() - for(var/obj/item/I in things) - things -= I - if(I.loc != source_real_location) - continue - if(user.active_storage != src_object) - if(I.on_found(user)) - break - if(can_be_inserted(I,FALSE,user)) - handle_item_insertion(I, TRUE, user) - if (TICK_CHECK) - progress.update(progress.goal - things.len) - return TRUE - - progress.update(progress.goal - things.len) - return FALSE - -/datum/component/storage/proc/handle_mass_pickup(list/things, atom/thing_loc, list/rejections, datum/progressbar/progress) - var/atom/real_location = real_location() - for(var/obj/item/I in things) - things -= I - if(I.loc != thing_loc) - continue - if(I.type in rejections) // To limit bag spamming: any given type only complains once - continue - if(!can_be_inserted(I, stop_messages = TRUE)) // Note can_be_inserted still makes noise when the answer is no - if(real_location.contents.len >= max_items) - break - rejections += I.type // therefore full bags are still a little spammy - continue - - handle_item_insertion(I, TRUE) //The TRUE stops the "You put the [parent] into [S]" insertion message from being displayed. - - if (TICK_CHECK) - progress.update(progress.goal - things.len) - return TRUE - - progress.update(progress.goal - things.len) - return FALSE - -/datum/component/storage/proc/quick_empty(mob/M) - var/atom/A = parent - if(!M.canUseStorage() || !A.Adjacent(M) || M.incapacitated()) - return - if(locked) - to_chat(M, "[parent] seems to be locked!") - return FALSE - A.add_fingerprint(M) - to_chat(M, "You start dumping out [parent].") - var/turf/T = get_turf(A) - var/list/things = contents() - var/datum/progressbar/progress = new(M, length(things), T) - while(do_after(M, 10, T, DO_AFTER_NO_PROGRESS, additional_checks = CALLBACK(src, .proc/mass_remove_from_storage, T, things, progress))) - stoplag(1) - qdel(progress) - -/datum/component/storage/proc/mass_remove_from_storage(atom/target, list/things, datum/progressbar/progress, trigger_on_found = TRUE) - var/atom/real_location = real_location() - for(var/obj/item/I in things) - things -= I - if(I.loc != real_location) - continue - remove_from_storage(I, target) - I.pixel_x = rand(-10,10) - I.pixel_y = rand(-10,10) - if(trigger_on_found && I.on_found()) - return FALSE - if(TICK_CHECK) - progress.update(progress.goal - length(things)) - return TRUE - progress.update(progress.goal - length(things)) - return FALSE - -/datum/component/storage/proc/do_quick_empty(atom/_target) - if(!_target) - _target = get_turf(parent) - if(usr) - hide_from(usr) - var/list/contents = contents() - var/atom/real_location = real_location() - for(var/obj/item/I in contents) - if(I.loc != real_location) - continue - remove_from_storage(I, _target) - return TRUE - -/datum/component/storage/proc/set_locked(datum/source, new_state) - locked = new_state - if(locked) - close_all() - -/datum/component/storage/proc/_process_numerical_display() - . = list() - var/atom/real_location = real_location() - for(var/obj/item/I in real_location.contents) - if(QDELETED(I)) - continue - if(!.["[I.type]-[I.name]"]) - .["[I.type]-[I.name]"] = new /datum/numbered_display(I, 1) - else - var/datum/numbered_display/ND = .["[I.type]-[I.name]"] - ND.number++ - -//This proc determines the size of the inventory to be displayed. Please touch it only if you know what you're doing. -/datum/component/storage/proc/orient2hud() - var/atom/real_location = real_location() - var/adjusted_contents = real_location.contents.len - - //Numbered contents display - var/list/datum/numbered_display/numbered_contents - if(display_numerical_stacking) - numbered_contents = _process_numerical_display() - adjusted_contents = numbered_contents.len - - var/columns = clamp(max_items, 1, screen_max_columns) - var/rows = clamp(CEILING(adjusted_contents / columns, 1), 1, screen_max_rows) - standard_orient_objs(rows, columns, numbered_contents) - -//This proc draws out the inventory and places the items on it. It uses the standard position. -/datum/component/storage/proc/standard_orient_objs(rows, cols, list/obj/item/numerical_display_contents) - boxes.screen_loc = "LEFT+[screen_start_x]:[screen_pixel_x],BOTTOM+[screen_start_y]:[screen_pixel_y] to LEFT+[screen_start_x+cols-1]:[screen_pixel_x],BOTTOM+[screen_start_y+rows-1]:[screen_pixel_y]" - var/cx = screen_start_x - var/cy = screen_start_y - if(islist(numerical_display_contents)) - for(var/type in numerical_display_contents) - var/datum/numbered_display/ND = numerical_display_contents[type] - ND.sample_object.mouse_opacity = MOUSE_OPACITY_OPAQUE - ND.sample_object.screen_loc = "LEFT+[cx]:[screen_pixel_x],BOTTOM+[cy]:[screen_pixel_y]" - ND.sample_object.maptext = "[(ND.number > 1)? "[ND.number]" : ""]" - ND.sample_object.layer = ABOVE_HUD_LAYER - ND.sample_object.plane = ABOVE_HUD_PLANE - cx++ - if(cx - screen_start_x >= cols) - cx = screen_start_x - cy++ - if(cy - screen_start_y >= rows) - break - else - var/atom/real_location = real_location() - for(var/obj/O in real_location) - if(QDELETED(O)) - continue - O.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip" - O.screen_loc = "LEFT+[cx]:[screen_pixel_x],BOTTOM+[cy]:[screen_pixel_y]" - O.maptext = "" - O.layer = ABOVE_HUD_LAYER - O.plane = ABOVE_HUD_PLANE - cx++ - if(cx - screen_start_x >= cols) - cx = screen_start_x - cy++ - if(cy - screen_start_y >= rows) - break - closer.screen_loc = "LEFT+[screen_start_x + cols]:[screen_pixel_x],BOTTOM+[screen_start_y]:[screen_pixel_y]" - -/datum/component/storage/proc/show_to(mob/M) - if(!M.client) - return FALSE - var/atom/real_location = real_location() - if(M.active_storage != src && (M.stat == CONSCIOUS)) - for(var/obj/item/I in real_location) - if(I.on_found(M)) - return FALSE - if(M.active_storage) - M.active_storage.hide_from(M) - orient2hud() - M.client.screen |= boxes - M.client.screen |= closer - M.client.screen |= real_location.contents - M.active_storage = src - LAZYDISTINCTADD(is_using, M) - return TRUE - -/datum/component/storage/proc/hide_from(mob/M) - if(!M.client) - return TRUE - var/atom/real_location = real_location() - M.client.screen -= boxes - M.client.screen -= closer - M.client.screen -= real_location.contents - if(M.active_storage == src) - M.active_storage = null - LAZYREMOVE(is_using, M) - return TRUE - -/datum/component/storage/proc/close(mob/M) - hide_from(M) - -/datum/component/storage/proc/close_all() - . = FALSE - for(var/mob/M in can_see_contents()) - close(M) - . = TRUE //returns TRUE if any mobs actually got a close(M) call - -/datum/component/storage/proc/emp_act(datum/source, severity) - if(emp_shielded) - return - var/datum/component/storage/concrete/master = master() - master.emp_act(source, severity) - -//This proc draws out the inventory and places the items on it. tx and ty are the upper left tile and mx, my are the bottm right. -//The numbers are calculated from the bottom-left The bottom-left slot being 1,1. -/datum/component/storage/proc/orient_objs(tx, ty, mx, my) - var/atom/real_location = real_location() - var/cx = tx - var/cy = ty - boxes.screen_loc = "LEFT+[tx]:,BOTTOM+[ty] to LEFT+[mx],BOTTOM+[my]" - for(var/obj/O in real_location) - if(QDELETED(O)) - continue - O.screen_loc = "LEFT+[cx],BOTTOM+[cy]" - O.layer = ABOVE_HUD_LAYER - O.plane = ABOVE_HUD_PLANE - cx++ - if(cx > mx) - cx = tx - cy-- - closer.screen_loc = "LEFT+[mx+1],BOTTOM+[my]" - -//Resets something that is being removed from storage. -/datum/component/storage/proc/_removal_reset(atom/movable/thing) - if(!istype(thing)) - return FALSE - var/datum/component/storage/concrete/master = master() - if(!istype(master)) - return FALSE - return master._removal_reset(thing) - -/datum/component/storage/proc/_remove_and_refresh(datum/source, atom/movable/thing) - _removal_reset(thing) - refresh_mob_views() - -//Call this proc to handle the removal of an item from the storage item. The item will be moved to the new_location target, if that is null it's being deleted -/datum/component/storage/proc/remove_from_storage(atom/movable/AM, atom/new_location) - if(!istype(AM)) - return FALSE - var/datum/component/storage/concrete/master = master() - if(!istype(master)) - return FALSE - return master.remove_from_storage(AM, new_location) - -/datum/component/storage/proc/refresh_mob_views() - var/list/seeing = can_see_contents() - for(var/i in seeing) - show_to(i) - return TRUE - -/datum/component/storage/proc/can_see_contents() - var/list/cansee = list() - for(var/mob/M in is_using) - if(M.active_storage == src && M.client) - cansee |= M - else - LAZYREMOVE(is_using, M) - return cansee - -//Tries to dump content -/datum/component/storage/proc/dump_content_at(atom/dest_object, mob/M) - var/atom/A = parent - var/atom/dump_destination = dest_object.get_dumping_location() - if(A.Adjacent(M) && dump_destination && M.Adjacent(dump_destination)) - if(locked) - to_chat(M, "[parent] seems to be locked!") - return FALSE - if(dump_destination.storage_contents_dump_act(src, M)) - playsound(A, "rustle", 50, TRUE, -5) - return TRUE - return FALSE - -//This proc is called when you want to place an item into the storage item. -/datum/component/storage/proc/attackby(datum/source, obj/item/I, mob/M, params) - if(istype(I, /obj/item/hand_labeler)) - var/obj/item/hand_labeler/labeler = I - if(labeler.mode) - return FALSE - . = TRUE //no afterattack - if(iscyborg(M)) - return - if(!can_be_inserted(I, FALSE, M)) - var/atom/real_location = real_location() - if(real_location.contents.len >= max_items) //don't use items on the backpack if they don't fit - return TRUE - return FALSE - handle_item_insertion(I, FALSE, M) - -/datum/component/storage/proc/return_inv(recursive) - var/list/ret = list() - ret |= contents() - if(recursive) - for(var/i in ret.Copy()) - var/atom/A = i - SEND_SIGNAL(A, COMSIG_TRY_STORAGE_RETURN_INVENTORY, ret, TRUE) - return ret - -/datum/component/storage/proc/contents() //ONLY USE IF YOU NEED TO COPY CONTENTS OF REAL LOCATION, COPYING IS NOT AS FAST AS DIRECT ACCESS! - var/atom/real_location = real_location() - return real_location.contents.Copy() - -//Abuses the fact that lists are just references, or something like that. -/datum/component/storage/proc/signal_return_inv(datum/source, list/interface, recursive = TRUE) - if(!islist(interface)) - return FALSE - interface |= return_inv(recursive) - return TRUE - -/datum/component/storage/proc/topic_handle(datum/source, user, href_list) - if(href_list["show_valid_pocket_items"]) - handle_show_valid_items(source, user) - -/datum/component/storage/proc/handle_show_valid_items(datum/source, user) - to_chat(user, "[source] can hold: [can_hold_description]") - -/datum/component/storage/proc/mousedrop_onto(datum/source, atom/over_object, mob/M) - set waitfor = FALSE - . = COMPONENT_NO_MOUSEDROP - if(!ismob(M)) - return - if(!over_object) - return - if(ismecha(M.loc)) // stops inventory actions in a mech - return - if(M.incapacitated() || !M.canUseStorage()) - return - var/atom/A = parent - A.add_fingerprint(M) - // this must come before the screen objects only block, dunno why it wasn't before - if(over_object == M) - user_show_to_mob(M) - if(!istype(over_object, /atom/movable/screen)) - dump_content_at(over_object, M) - return - if(A.loc != M) - return - playsound(A, "rustle", 50, TRUE, -5) - if(istype(over_object, /atom/movable/screen/inventory/hand)) - var/atom/movable/screen/inventory/hand/H = over_object - M.putItemFromInventoryInHandIfPossible(A, H.held_index) - return - A.add_fingerprint(M) - -/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE) - var/atom/A = parent - if(!istype(M)) - return FALSE - A.add_fingerprint(M) - if(locked && !force) - to_chat(M, "[parent] seems to be locked!") - return FALSE - if(force || M.CanReach(parent, view_only = TRUE)) - show_to(M) - -/datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M) - if(isitem(O)) - var/obj/item/I = O - if(iscarbon(M) || isdrone(M)) - var/mob/living/L = M - if(!L.incapacitated() && I == L.get_active_held_item()) - if(!SEND_SIGNAL(I, COMSIG_CONTAINS_STORAGE) && can_be_inserted(I, FALSE)) //If it has storage it should be trying to dump, not insert. - handle_item_insertion(I, FALSE, L) - -//This proc return 1 if the item can be picked up and 0 if it can't. -//Set the stop_messages to stop it from printing messages -/datum/component/storage/proc/can_be_inserted(obj/item/I, stop_messages = FALSE, mob/M) - if(!istype(I) || (I.item_flags & ITEM_ABSTRACT)) - return FALSE //Not an item - if(I == parent) - return FALSE //no paradoxes for you - var/atom/real_location = real_location() - var/atom/host = parent - if(real_location == I.loc) - return FALSE //Means the item is already in the storage item - if(locked) - if(M && !stop_messages) - host.add_fingerprint(M) - to_chat(M, "[host] seems to be locked!") - return FALSE - if(real_location.contents.len >= max_items) - if(!stop_messages) - to_chat(M, "[host] is full, make some space!") - return FALSE //Storage item is full - if(length(can_hold)) - if(!is_type_in_typecache(I, can_hold)) - if(!stop_messages) - to_chat(M, "[host] cannot hold [I]!") - return FALSE - if(is_type_in_typecache(I, cant_hold)) //Check for specific items which this container can't hold. - if(!stop_messages) - to_chat(M, "[host] cannot hold [I]!") - return FALSE - if(I.w_class > max_w_class && !is_type_in_typecache(I, exception_hold)) - if(!stop_messages) - to_chat(M, "[I] is too big for [host]!") - return FALSE - var/sum_w_class = I.w_class - for(var/obj/item/_I in real_location) - sum_w_class += _I.w_class //Adds up the combined w_classes which will be in the storage item if the item is added to it. - if(sum_w_class > max_combined_w_class) - if(!stop_messages) - to_chat(M, "[I] won't fit in [host], make some space!") - return FALSE - if(isitem(host)) - var/obj/item/IP = host - var/datum/component/storage/STR_I = I.GetComponent(/datum/component/storage) - if((I.w_class >= IP.w_class) && STR_I && !allow_big_nesting) - if(!stop_messages) - to_chat(M, "[IP] cannot hold [I] as it's a storage item of the same size!") - return FALSE //To prevent the stacking of same sized storage items. - var/datum/component/storage/concrete/master = master() - if(!istype(master)) - return FALSE - return master.slave_can_insert_object(src, I, stop_messages, M) - -/datum/component/storage/proc/_insert_physical_item(obj/item/I, override = FALSE) - return FALSE - -//This proc handles items being inserted. It does not perform any checks of whether an item can or can't be inserted. That's done by can_be_inserted() -//The prevent_warning parameter will stop the insertion message from being displayed. It is intended for cases where you are inserting multiple items at once, -//such as when picking up all the items on a tile with one click. -/datum/component/storage/proc/handle_item_insertion(obj/item/I, prevent_warning = FALSE, mob/M, datum/component/storage/remote) - var/atom/parent = src.parent - var/datum/component/storage/concrete/master = master() - if(!istype(master)) - return FALSE - if(silent) - prevent_warning = TRUE - if(M) - parent.add_fingerprint(M) - . = master.handle_item_insertion_from_slave(src, I, prevent_warning, M) - -/datum/component/storage/proc/mob_item_insertion_feedback(mob/user, mob/M, obj/item/I, override = FALSE) - if(silent && !override) - return - if(rustle_sound) - playsound(parent, "rustle", 50, TRUE, -5) - for(var/mob/viewing in viewers(user, null)) - if(M == viewing) - to_chat(usr, "You put [I] [insert_preposition]to [parent].") - else if(in_range(M, viewing)) //If someone is standing close enough, they can tell what it is... - viewing.show_message("[M] puts [I] [insert_preposition]to [parent].", 1) - else if(I && I.w_class >= 3) //Otherwise they can only see large or normal items from a distance... - viewing.show_message("[M] puts [I] [insert_preposition]to [parent].", 1) - -/datum/component/storage/proc/update_icon() - if(isobj(parent)) - var/obj/O = parent - O.update_icon() - -/datum/component/storage/proc/signal_insertion_attempt(datum/source, obj/item/I, mob/M, silent = FALSE, force = FALSE) - if((!force && !can_be_inserted(I, TRUE, M)) || (I == parent)) - return FALSE - return handle_item_insertion(I, silent, M) - -/datum/component/storage/proc/signal_can_insert(datum/source, obj/item/I, mob/M, silent = FALSE) - return can_be_inserted(I, silent, M) - -/datum/component/storage/proc/show_to_ghost(datum/source, mob/observer/dead/M) - return user_show_to_mob(M, TRUE) - -/datum/component/storage/proc/signal_show_attempt(datum/source, mob/showto, force = FALSE) - return user_show_to_mob(showto, force) - -/datum/component/storage/proc/on_check() - return TRUE - -/datum/component/storage/proc/check_locked() - return locked - -/datum/component/storage/proc/signal_take_type(datum/source, type, atom/destination, amount = INFINITY, check_adjacent = FALSE, force = FALSE, mob/user, list/inserted) - if(!force) - if(check_adjacent) - if(!user || !user.CanReach(destination) || !user.CanReach(parent)) - return FALSE - var/list/taking = typecache_filter_list(contents(), typecacheof(type)) - if(taking.len > amount) - taking.len = amount - if(inserted) //duplicated code for performance, don't bother checking retval/checking for list every item. - for(var/i in taking) - if(remove_from_storage(i, destination)) - inserted |= i - else - for(var/i in taking) - remove_from_storage(i, destination) - return TRUE - -/datum/component/storage/proc/remaining_space_items() - var/atom/real_location = real_location() - return max(0, max_items - real_location.contents.len) - -/datum/component/storage/proc/signal_fill_type(datum/source, type, amount = 20, force = FALSE) - var/atom/real_location = real_location() - if(!force) - amount = min(remaining_space_items(), amount) - for(var/i in 1 to amount) - handle_item_insertion(new type(real_location), TRUE) - CHECK_TICK - return TRUE - -/datum/component/storage/proc/on_attack_hand(datum/source, mob/user) - var/atom/A = parent - if(!attack_hand_interact) - return - if(user.active_storage == src && A.loc == user) //if you're already looking inside the storage item - user.active_storage.close(user) - close(user) - . = COMPONENT_NO_ATTACK_HAND - return - - if(rustle_sound) - playsound(A, "rustle", 50, TRUE, -5) - - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.l_store == A && !H.get_active_held_item()) //Prevents opening if it's in a pocket. - . = COMPONENT_NO_ATTACK_HAND - H.put_in_hands(A) - H.l_store = null - return - if(H.r_store == A && !H.get_active_held_item()) - . = COMPONENT_NO_ATTACK_HAND - H.put_in_hands(A) - H.r_store = null - return - - if(A.loc == user) - . = COMPONENT_NO_ATTACK_HAND - if(locked) - to_chat(user, "[parent] seems to be locked!") - else - show_to(user) - -/datum/component/storage/proc/signal_on_pickup(datum/source, mob/user) - var/atom/A = parent - update_actions() - for(var/mob/M in range(1, A)) - if(M.active_storage == src) - close(M) - -/datum/component/storage/proc/signal_take_obj(datum/source, atom/movable/AM, new_loc, force = FALSE) - if(!(AM in real_location())) - return FALSE - return remove_from_storage(AM, new_loc) - -/datum/component/storage/proc/signal_quick_empty(datum/source, atom/loctarget) - return do_quick_empty(loctarget) - -/datum/component/storage/proc/signal_hide_attempt(datum/source, mob/target) - return hide_from(target) - -/datum/component/storage/proc/on_alt_click(datum/source, mob/user) - if(!isliving(user) || !user.CanReach(parent)) - return - if(locked) - to_chat(user, "[parent] seems to be locked!") - return - - var/atom/A = parent - if(!quickdraw) - A.add_fingerprint(user) - user_show_to_mob(user) - playsound(A, "rustle", 50, TRUE, -5) - return - - if(!user.incapacitated()) - var/obj/item/I = locate() in real_location() - if(!I) - return - A.add_fingerprint(user) - remove_from_storage(I, get_turf(user)) - if(!user.put_in_hands(I)) - to_chat(user, "You fumble for [I] and it falls on the floor.") - return - user.visible_message("[user] draws [I] from [parent]!", "You draw [I] from [parent].") - return - -/datum/component/storage/proc/action_trigger(datum/signal_source, datum/action/source) - gather_mode_switch(source.owner) - return COMPONENT_ACTION_BLOCK_TRIGGER - -/datum/component/storage/proc/gather_mode_switch(mob/user) - collection_mode = (collection_mode+1)%3 - switch(collection_mode) - if(COLLECT_SAME) - to_chat(user, "[parent] now picks up all items of a single type at once.") - if(COLLECT_EVERYTHING) - to_chat(user, "[parent] now picks up all items in a tile at once.") - if(COLLECT_ONE) - to_chat(user, "[parent] now picks up one item at a time.") diff --git a/code/datums/components/summoning.dm b/code/datums/components/summoning.dm deleted file mode 100644 index adb42e153c8..00000000000 --- a/code/datums/components/summoning.dm +++ /dev/null @@ -1,68 +0,0 @@ -/datum/component/summoning - var/list/mob_types = list() - var/spawn_chance // chance for the mob to spawn on hit in percent - var/max_mobs - var/spawn_delay // delay in spawning between mobs (deciseconds) - var/spawn_text - var/spawn_sound - var/list/faction - - var/last_spawned_time = 0 - var/list/spawned_mobs = list() - -/datum/component/summoning/Initialize(mob_types, spawn_chance=100, max_mobs=3, spawn_delay=100, spawn_text="appears out of nowhere", spawn_sound='sound/magic/summon_magic.ogg', faction) - if(!isitem(parent) && !ishostile(parent) && !isgun(parent) && !ismachinery(parent) && !isstructure(parent)) - return COMPONENT_INCOMPATIBLE - - src.mob_types = mob_types - src.spawn_chance = spawn_chance - src.max_mobs = max_mobs - src.spawn_delay = spawn_delay - src.spawn_text = spawn_text - src.spawn_sound = spawn_sound - src.faction = faction - -/datum/component/summoning/RegisterWithParent() - if(ismachinery(parent) || isstructure(parent) || isgun(parent)) // turrets, etc - RegisterSignal(parent, COMSIG_PROJECTILE_ON_HIT, .proc/projectile_hit) - else if(isitem(parent)) - RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, .proc/item_afterattack) - else if(ishostile(parent)) - RegisterSignal(parent, COMSIG_HOSTILE_ATTACKINGTARGET, .proc/hostile_attackingtarget) - -/datum/component/summoning/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_ITEM_AFTERATTACK, COMSIG_HOSTILE_ATTACKINGTARGET, COMSIG_PROJECTILE_ON_HIT)) - -/datum/component/summoning/proc/item_afterattack(obj/item/source, atom/target, mob/user, proximity_flag, click_parameters) - if(!(clickchain_flags & CLICKCHAIN_HAS_PROXIMITY)) - return - do_spawn_mob(get_turf(target), user) - -/datum/component/summoning/proc/hostile_attackingtarget(mob/living/simple_animal/hostile/attacker, atom/target) - do_spawn_mob(get_turf(target), attacker) - -/datum/component/summoning/proc/projectile_hit(atom/fired_from, atom/movable/firer, atom/target, Angle) - do_spawn_mob(get_turf(target), firer) - -/datum/component/summoning/proc/do_spawn_mob(atom/spawn_location, summoner) - if(spawned_mobs.len >= max_mobs) - return 0 - if(last_spawned_time > world.time) - return 0 - if(!prob(spawn_chance)) - return 0 - last_spawned_time = world.time + spawn_delay - var/chosen_mob_type = pick(mob_types) - var/mob/living/simple_animal/L = new chosen_mob_type(spawn_location) - if(ishostile(L)) - var/mob/living/simple_animal/hostile/H = L - H.friends += summoner // do not attack our summon boy - spawned_mobs += L - if(faction != null) - L.faction = faction - RegisterSignal(L, COMSIG_MOB_DEATH, .proc/on_spawned_death) // so we can remove them from the list, etc (for mobs with corpses) - playsound(spawn_location,spawn_sound, 50, TRUE) - spawn_location.visible_message("[L] [spawn_text].") - -/datum/component/summoning/proc/on_spawned_death(mob/killed, gibbed) - spawned_mobs -= killed diff --git a/code/datums/components/swarming.dm b/code/datums/components/swarming.dm deleted file mode 100644 index 16ddc66280e..00000000000 --- a/code/datums/components/swarming.dm +++ /dev/null @@ -1,55 +0,0 @@ -/datum/component/swarming - var/offset_x = 0 - var/offset_y = 0 - var/is_swarming = FALSE - var/list/swarm_members = list() - -/datum/component/swarming/Initialize(max_x = 24, max_y = 24) - if(!ismovable(parent)) - return COMPONENT_INCOMPATIBLE - offset_x = rand(-max_x, max_x) - offset_y = rand(-max_y, max_y) - - RegisterSignal(parent, COMSIG_MOVABLE_CROSSED, .proc/join_swarm) - RegisterSignal(parent, COMSIG_MOVABLE_UNCROSSED, .proc/leave_swarm) - -/datum/component/swarming/Destroy() - for(var/other in swarm_members) - var/datum/component/swarming/other_swarm = other - other_swarm.swarm_members -= src - if(!other_swarm.swarm_members.len) - other_swarm.unswarm() - swarm_members = null - return ..() - -/datum/component/swarming/proc/join_swarm(datum/source, atom/movable/AM) - var/datum/component/swarming/other_swarm = AM.GetComponent(/datum/component/swarming) - if(!other_swarm) - return - swarm() - swarm_members |= other_swarm - other_swarm.swarm() - other_swarm.swarm_members |= src - -/datum/component/swarming/proc/leave_swarm(datum/source, atom/movable/AM) - var/datum/component/swarming/other_swarm = AM.GetComponent(/datum/component/swarming) - if(!other_swarm || !(other_swarm in swarm_members)) - return - swarm_members -= other_swarm - if(!swarm_members.len) - unswarm() - other_swarm.swarm_members -= src - if(!other_swarm.swarm_members.len) - other_swarm.unswarm() - -/datum/component/swarming/proc/swarm() - var/atom/movable/owner = parent - if(!is_swarming) - is_swarming = TRUE - animate(owner, pixel_x = owner.pixel_x + offset_x, pixel_y = owner.pixel_y + offset_y, time = 2) - -/datum/component/swarming/proc/unswarm() - var/atom/movable/owner = parent - if(is_swarming) - animate(owner, pixel_x = owner.pixel_x - offset_x, pixel_y = owner.pixel_y - offset_y, time = 2) - is_swarming = FALSE diff --git a/code/datums/components/tactical.dm b/code/datums/components/tactical.dm deleted file mode 100644 index 7c742a769b4..00000000000 --- a/code/datums/components/tactical.dm +++ /dev/null @@ -1,41 +0,0 @@ -/datum/component/tactical - var/allowed_slot - -/datum/component/tactical/Initialize(allowed_slot) - if(!isitem(parent)) - return COMPONENT_INCOMPATIBLE - - src.allowed_slot = allowed_slot - -/datum/component/tactical/RegisterWithParent() - RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/modify) - RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/unmodify) - -/datum/component/tactical/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED)) - unmodify() - -/datum/component/fantasy/Destroy() - unmodify() - return ..() - -/datum/component/tactical/proc/modify(obj/item/source, mob/user, slot) - if(allowed_slot && slot != allowed_slot) - unmodify() - return - - var/obj/item/master = parent - var/image/I = image(icon = master.icon, icon_state = master.icon_state, loc = user) - I.copy_overlays(master) - I.override = TRUE - source.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/everyone, "sneaking_mission", I) - I.layer = ABOVE_MOB_LAYER - -/datum/component/tactical/proc/unmodify(obj/item/source, mob/user) - var/obj/item/master = source || parent - if(!user) - if(!ismob(master.loc)) - return - user = master.loc - - user.remove_alt_appearance("sneaking_mission") diff --git a/code/datums/components/tether.dm b/code/datums/components/tether.dm deleted file mode 100644 index faa6182208a..00000000000 --- a/code/datums/components/tether.dm +++ /dev/null @@ -1,37 +0,0 @@ -/datum/component/tether - dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS - var/atom/tether_target - var/max_dist - var/tether_name - -/datum/component/tether/Initialize(atom/tether_target, max_dist = 4, tether_name) - if(!isliving(parent) || !istype(tether_target) || !tether_target.loc) - return COMPONENT_INCOMPATIBLE - src.tether_target = tether_target - src.max_dist = max_dist - if (ispath(tether_name, /atom)) - var/atom/tmp = tether_name - src.tether_name = initial(tmp.name) - else - src.tether_name = tether_name - RegisterSignal(parent, list(COMSIG_MOVABLE_PRE_MOVE), .proc/checkTether) - -/datum/component/tether/proc/checkTether(mob/mover, newloc) - if (get_dist(mover,newloc) > max_dist) - to_chat(mover, "The [tether_name] runs out of slack and prevents you from moving!") - return COMPONENT_MOVABLE_BLOCK_PRE_MOVE - - var/atom/blocker - out: - for(var/turf/T in getline(tether_target,newloc)) - if (T.density) - blocker = T - break out - for(var/a in T) - var/atom/A = a - if(A.density && A != mover && A != tether_target) - blocker = A - break out - if (blocker) - to_chat(mover, "The [tether_name] catches on [blocker] and prevents you from moving!") - return COMPONENT_MOVABLE_BLOCK_PRE_MOVE diff --git a/code/datums/components/thermite.dm b/code/datums/components/thermite.dm deleted file mode 100644 index 5a6dfcd0183..00000000000 --- a/code/datums/components/thermite.dm +++ /dev/null @@ -1,92 +0,0 @@ -/datum/component/thermite - dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS - var/amount - var/burn_require - var/overlay - - var/static/list/blacklist = typecacheof(list( - /turf/open/lava, - /turf/space, - /turf/open/water, - /turf/open/chasm) - ) - - var/static/list/immunelist = typecacheof(list( - /turf/closed/wall/mineral/diamond, - /turf/closed/indestructible, - /turf/open/indestructible) - ) - - var/static/list/resistlist = typecacheof( - /turf/closed/wall/r_wall - ) - -/datum/component/thermite/Initialize(_amount) - if(!istype(parent, /turf) || blacklist[parent.type]) - return COMPONENT_INCOMPATIBLE - - if(immunelist[parent.type]) - amount = 0 //Yeah the overlay can still go on it and be cleaned but you arent burning down a diamond wall - else - amount = _amount - if(resistlist[parent.type]) - burn_require = 50 - else - burn_require = 30 - - var/turf/master = parent - overlay = mutable_appearance('icons/effects/effects.dmi', "thermite") - master.add_overlay(overlay) - - RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react) - RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/attackby_react) - RegisterSignal(parent, COMSIG_ATOM_FIRE_ACT, .proc/flame_react) - -/datum/component/thermite/UnregisterFromParent() - UnregisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT) - UnregisterSignal(parent, COMSIG_PARENT_ATTACKBY) - UnregisterSignal(parent, COMSIG_ATOM_FIRE_ACT) - -/datum/component/thermite/Destroy() - var/turf/master = parent - master.cut_overlay(overlay) - return ..() - -/datum/component/thermite/InheritComponent(datum/component/thermite/newC, i_am_original, list/arguments) - if(!i_am_original) - return - if(newC) - amount += newC.amount - else - amount += arguments[1] - -/datum/component/thermite/proc/thermite_melt(mob/user) - var/turf/master = parent - master.cut_overlay(overlay) - playsound(master, 'sound/items/welder.ogg', 100, TRUE) - var/obj/effect/overlay/thermite/fakefire = new(master) - addtimer(CALLBACK(src, .proc/burn_parent, fakefire, user), min(amount * 0.35 SECONDS, 20 SECONDS)) - UnregisterFromParent() - -/datum/component/thermite/proc/burn_parent(var/datum/fakefire, mob/user) - var/turf/master = parent - if(!QDELETED(fakefire)) - qdel(fakefire) - if(user) - master.add_hiddenprint(user) - if(amount >= burn_require) - master = master.Melt() - master.burn_tile() - qdel(src) - -/datum/component/thermite/proc/clean_react(datum/source, strength) - //Thermite is just some loose powder, you could probably clean it with your hands. << todo? - qdel(src) - -/datum/component/thermite/proc/flame_react(datum/source, exposed_temperature, exposed_volume) - if(exposed_temperature > 1922) // This is roughly the real life requirement to ignite thermite - thermite_melt() - -/datum/component/thermite/proc/attackby_react(datum/source, obj/item/thing, mob/user, params) - if(thing.is_hot()) - thermite_melt(user) diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm deleted file mode 100644 index fb514bb432f..00000000000 --- a/code/datums/components/uplink.dm +++ /dev/null @@ -1,318 +0,0 @@ -GLOBAL_LIST_EMPTY(uplinks) - -#define PEN_ROTATIONS 2 - -/** - * Uplinks - * - * All /obj/item(s) have a hidden_uplink var. By default it's null. Give the item one with 'new(src') (it must be in it's contents). Then add 'uses.' - * Use whatever conditionals you want to check that the user has an uplink, and then call interact() on their uplink. - * You might also want the uplink menu to open if active. Check if the uplink is 'active' and then interact() with it. -**/ -/datum/component/uplink - dupe_mode = COMPONENT_DUPE_UNIQUE - var/name = "syndicate uplink" - var/active = FALSE - var/lockable = TRUE - var/locked = TRUE - var/allow_restricted = TRUE - var/telecrystals - var/selected_cat - var/owner = null - var/datum/game_mode/gamemode - var/datum/uplink_purchase_log/purchase_log - var/list/uplink_items - var/hidden_crystals = 0 - var/unlock_note - var/unlock_code - var/failsafe_code - - var/list/previous_attempts - -/datum/component/uplink/Initialize(_owner, _lockable = TRUE, _enabled = FALSE, datum/game_mode/_gamemode, starting_tc = 20) - if(!isitem(parent)) - return COMPONENT_INCOMPATIBLE - - - RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy) - RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/interact) - if(istype(parent, /obj/item/implant)) - RegisterSignal(parent, COMSIG_IMPLANT_ACTIVATED, .proc/implant_activation) - RegisterSignal(parent, COMSIG_IMPLANT_IMPLANTING, .proc/implanting) - RegisterSignal(parent, COMSIG_IMPLANT_OTHER, .proc/old_implant) - RegisterSignal(parent, COMSIG_IMPLANT_EXISTING_UPLINK, .proc/new_implant) - else if(istype(parent, /obj/item/pda)) - RegisterSignal(parent, COMSIG_PDA_CHANGE_RINGTONE, .proc/new_ringtone) - RegisterSignal(parent, COMSIG_PDA_CHECK_DETONATE, .proc/check_detonate) - else if(istype(parent, /obj/item/radio)) - RegisterSignal(parent, COMSIG_RADIO_NEW_FREQUENCY, .proc/new_frequency) - else if(istype(parent, /obj/item/pen)) - RegisterSignal(parent, COMSIG_PEN_ROTATED, .proc/pen_rotation) - - GLOB.uplinks += src - uplink_items = get_uplink_items(_gamemode, TRUE, allow_restricted) - - if(_owner) - owner = _owner - LAZYINITLIST(GLOB.uplink_purchase_logs_by_key) - if(GLOB.uplink_purchase_logs_by_key[owner]) - purchase_log = GLOB.uplink_purchase_logs_by_key[owner] - else - purchase_log = new(owner, src) - lockable = _lockable - active = _enabled - gamemode = _gamemode - telecrystals = starting_tc - if(!lockable) - active = TRUE - locked = FALSE - - previous_attempts = list() - -/datum/component/uplink/InheritComponent(datum/component/uplink/U) - lockable |= U.lockable - active |= U.active - if(!gamemode) - gamemode = U.gamemode - telecrystals += U.telecrystals - if(purchase_log && U.purchase_log) - purchase_log.MergeWithAndDel(U.purchase_log) - -/datum/component/uplink/Destroy() - GLOB.uplinks -= src - gamemode = null - purchase_log = null - return ..() - -/datum/component/uplink/proc/LoadTC(mob/user, obj/item/stack/telecrystal/TC, silent = FALSE) - if(!silent) - to_chat(user, "You slot [TC] into [parent] and charge its internal uplink.") - var/amt = TC.amount - telecrystals += amt - TC.use(amt) - -/datum/component/uplink/proc/set_gamemode(_gamemode) - gamemode = _gamemode - uplink_items = get_uplink_items(gamemode, TRUE, allow_restricted) - -/datum/component/uplink/proc/OnAttackBy(datum/source, obj/item/I, mob/user) - if(!active) - return //no hitting everyone/everything just to try to slot tcs in! - if(istype(I, /obj/item/stack/telecrystal)) - LoadTC(user, I) - for(var/category in uplink_items) - for(var/item in uplink_items[category]) - var/datum/uplink_item/UI = uplink_items[category][item] - var/path = UI.refund_path || UI.item - var/cost = UI.refund_amount || UI.cost - if(I.type == path && UI.refundable && I.check_uplink_validity()) - telecrystals += cost - if(purchase_log) - purchase_log.total_spent -= cost - to_chat(user, "[I] refunded.") - qdel(I) - return - -/datum/component/uplink/proc/interact(datum/source, mob/user) - if(locked) - return - active = TRUE - if(user) - nano_ui_interact(user) - // an unlocked uplink blocks also opening the PDA or headset menu - return COMPONENT_NO_INTERACT - -/datum/component/uplink/nano_ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state) - active = TRUE - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "uplink", name, 450, 750, master_ui, state) - ui.set_autoupdate(FALSE) // This UI is only ever opened by one person, and never is updated outside of user input. - ui.set_style("syndicate") - ui.open() - -/datum/component/uplink/ui_data(mob/user) - if(!user.mind) - return - var/list/data = list() - data["telecrystals"] = telecrystals - data["lockable"] = lockable - - data["categories"] = list() - for(var/category in uplink_items) - var/list/cat = list( - "name" = category, - "items" = (category == selected_cat ? list() : null)) - if(category == selected_cat) - for(var/item in uplink_items[category]) - var/datum/uplink_item/I = uplink_items[category][item] - if(I.limited_stock == 0) - continue - if(I.restricted_roles.len) - var/is_inaccessible = 1 - for(var/R in I.restricted_roles) - if(R == user.mind.assigned_role) - is_inaccessible = 0 - if(is_inaccessible) - continue - if(I.restricted_species) - if(ishuman(user)) - var/is_inaccessible = TRUE - var/mob/living/carbon/human/H = user - for(var/F in I.restricted_species) - if(F == H.dna.species.id) - is_inaccessible = FALSE - break - if(is_inaccessible) - continue - cat["items"] += list(list( - "name" = I.name, - "cost" = I.cost, - "desc" = I.desc, - )) - data["categories"] += list(cat) - return data - -/datum/component/uplink/ui_act(action, params) - if(!active) - return - - switch(action) - if("buy") - var/item = params["item"] - - var/list/buyable_items = list() - for(var/category in uplink_items) - buyable_items += uplink_items[category] - - if(item in buyable_items) - var/datum/uplink_item/I = buyable_items[item] - MakePurchase(usr, I) - . = TRUE - if("lock") - active = FALSE - locked = TRUE - telecrystals += hidden_crystals - hidden_crystals = 0 - SStgui.close_uis(src) - if("select") - selected_cat = params["category"] - return TRUE - -/datum/component/uplink/proc/MakePurchase(mob/user, datum/uplink_item/U) - if(!istype(U)) - return - if (!user || user.incapacitated()) - return - - if(telecrystals < U.cost || U.limited_stock == 0) - return - telecrystals -= U.cost - - U.purchase(user, src) - - if(U.limited_stock > 0) - U.limited_stock -= 1 - - SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(U.name)]", "[U.cost]")) - return TRUE - -// Implant signal responses - -/datum/component/uplink/proc/implant_activation() - var/obj/item/implant/implant = parent - locked = FALSE - interact(null, implant.imp_in) - -/datum/component/uplink/proc/implanting(datum/source, list/arguments) - var/mob/user = arguments[2] - owner = "[user.key]" - -/datum/component/uplink/proc/old_implant(datum/source, list/arguments, obj/item/implant/new_implant) - // It kinda has to be weird like this until implants are components - return SEND_SIGNAL(new_implant, COMSIG_IMPLANT_EXISTING_UPLINK, src) - -/datum/component/uplink/proc/new_implant(datum/source, datum/component/uplink/uplink) - uplink.telecrystals += telecrystals - return COMPONENT_DELETE_NEW_IMPLANT - -// PDA signal responses - -/datum/component/uplink/proc/new_ringtone(datum/source, mob/living/user, new_ring_text) - var/obj/item/pda/master = parent - if(trim(lowertext(new_ring_text)) != trim(lowertext(unlock_code))) - if(trim(lowertext(new_ring_text)) == trim(lowertext(failsafe_code))) - failsafe() - return COMPONENT_STOP_RINGTONE_CHANGE - return - locked = FALSE - interact(null, user) - to_chat(user, "The PDA softly beeps.") - user << browse(null, "window=pda") - master.mode = 0 - return COMPONENT_STOP_RINGTONE_CHANGE - -/datum/component/uplink/proc/check_detonate() - return COMPONENT_PDA_NO_DETONATE - -// Radio signal responses - -/datum/component/uplink/proc/new_frequency(datum/source, list/arguments) - var/obj/item/radio/master = parent - var/frequency = arguments[1] - if(frequency != unlock_code) - if(frequency == failsafe_code) - failsafe() - return - locked = FALSE - if(ismob(master.loc)) - interact(null, master.loc) - -// Pen signal responses - -/datum/component/uplink/proc/pen_rotation(datum/source, degrees, mob/living/carbon/user) - var/obj/item/pen/master = parent - previous_attempts += degrees - if(length(previous_attempts) > PEN_ROTATIONS) - popleft(previous_attempts) - - if(compare_list(previous_attempts, unlock_code)) - locked = FALSE - previous_attempts.Cut() - master.degrees = 0 - interact(null, user) - to_chat(user, "Your pen makes a clicking noise, before quickly rotating back to 0 degrees!") - - else if(compare_list(previous_attempts, failsafe_code)) - failsafe() - -/datum/component/uplink/proc/setup_unlock_code() - unlock_code = generate_code() - var/obj/item/P = parent - if(istype(parent,/obj/item/pda)) - unlock_note = "Uplink Passcode: [unlock_code] ([P.name])." - else if(istype(parent,/obj/item/radio)) - unlock_note = "Radio Frequency: [format_frequency(unlock_code)] ([P.name])." - else if(istype(parent,/obj/item/pen)) - unlock_note = "Uplink Degrees: [english_list(unlock_code)] ([P.name])." - -/datum/component/uplink/proc/generate_code() - if(istype(parent,/obj/item/pda)) - return "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]" - else if(istype(parent,/obj/item/radio)) - return sanitize_frequency(rand(MIN_FREQ, MAX_FREQ)) - else if(istype(parent,/obj/item/pen)) - var/list/L = list() - for(var/i in 1 to PEN_ROTATIONS) - L += rand(1, 360) - return L - -/datum/component/uplink/proc/failsafe() - if(!parent) - return - var/turf/T = get_turf(parent) - if(!T) - return - explosion(T,1,2,3) - qdel(parent) //Alternatively could brick the uplink. diff --git a/code/datums/components/waddling.dm b/code/datums/components/waddling.dm deleted file mode 100644 index 13a36c9473d..00000000000 --- a/code/datums/components/waddling.dm +++ /dev/null @@ -1,22 +0,0 @@ -/datum/component/waddling - dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS - -/datum/component/waddling/Initialize() - . = ..() - if(!ismovable(parent)) - return COMPONENT_INCOMPATIBLE - if(isliving(parent)) - RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/LivingWaddle) - else - RegisterSignal(parent, list(COMSIG_MOVABLE_MOVED), .proc/Waddle) - -/datum/component/waddling/proc/LivingWaddle() - var/mob/living/L = parent - if(L.incapacitated() || !(L.mobility_flags & MOBILITY_IS_STANDING)) - return - Waddle() - -/datum/component/waddling/proc/Waddle() - animate(parent, pixel_z = 4, time = 0) - animate(pixel_z = 0, transform = turn(matrix(), pick(-12, 0, 12)), time=2) - animate(pixel_z = 0, transform = matrix(), time = 0) diff --git a/code/datums/components/wearertargeting.dm b/code/datums/components/wearertargeting.dm deleted file mode 100644 index 4760757701f..00000000000 --- a/code/datums/components/wearertargeting.dm +++ /dev/null @@ -1,22 +0,0 @@ -// A dummy parent type used for easily making components that target an item's wearer rather than the item itself. - -/datum/component/wearertargeting - var/list/valid_slots = list() - var/list/signals = list() - var/proctype = .proc/pass - var/mobtype = /mob/living - -/datum/component/wearertargeting/Initialize() - if(!isitem(parent)) - return COMPONENT_INCOMPATIBLE - RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip) - RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop) - -/datum/component/wearertargeting/proc/on_equip(datum/source, mob/equipper, slot) - if((slot in valid_slots) && istype(equipper, mobtype)) - RegisterSignal(equipper, signals, proctype, TRUE) - else - UnregisterSignal(equipper, signals) - -/datum/component/wearertargeting/proc/on_drop(datum/source, mob/user) - UnregisterSignal(user, signals) diff --git a/code/datums/components/wet_floor.dm b/code/datums/components/wet_floor.dm deleted file mode 100644 index b5845ffa306..00000000000 --- a/code/datums/components/wet_floor.dm +++ /dev/null @@ -1,207 +0,0 @@ -/datum/component/wet_floor - dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS - can_transfer = TRUE - var/highest_strength = TURF_DRY - var/lube_flags = NONE //why do we have this? - var/list/time_left_list //In deciseconds. - var/static/mutable_appearance/permafrost_overlay = mutable_appearance('icons/effects/water.dmi', "ice_floor") - var/static/mutable_appearance/ice_overlay = mutable_appearance('icons/turf/overlays.dmi', "snowfloor") - var/static/mutable_appearance/water_overlay = mutable_appearance('icons/effects/water.dmi', "wet_floor_static") - var/static/mutable_appearance/generic_turf_overlay = mutable_appearance('icons/effects/water.dmi', "wet_static") - var/current_overlay - var/permanent = FALSE - var/last_process = 0 - -/datum/component/wet_floor/InheritComponent(datum/newcomp, orig, argslist) - if(!newcomp) //We are getting passed the arguments of a would-be new component, but not a new component - add_wet(arglist(argslist)) - else //We are being passed in a full blown component - var/datum/component/wet_floor/WF = newcomp //Lets make an assumption - if(WF.gc()) //See if it's even valid, still. Also does LAZYLEN and stuff for us. - CRASH("Wet floor component tried to inherit another, but the other was able to garbage collect while being inherited! What a waste of time!") - return - for(var/i in WF.time_left_list) - add_wet(text2num(i), WF.time_left_list[i]) - -/datum/component/wet_floor/Initialize(strength, duration_minimum, duration_add, duration_maximum, _permanent = FALSE) - if(!isopenturf(parent)) - return COMPONENT_INCOMPATIBLE - add_wet(strength, duration_minimum, duration_add, duration_maximum) - permanent = _permanent - if(!permanent) - START_PROCESSING(SSwet_floors, src) - addtimer(CALLBACK(src, .proc/gc, TRUE), 1) //GC after initialization. - last_process = world.time - -/datum/component/wet_floor/RegisterWithParent() - RegisterSignal(parent, COMSIG_TURF_IS_WET, .proc/is_wet) - RegisterSignal(parent, COMSIG_TURF_MAKE_DRY, .proc/dry) - -/datum/component/wet_floor/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_TURF_IS_WET, COMSIG_TURF_MAKE_DRY)) - -/datum/component/wet_floor/Destroy() - STOP_PROCESSING(SSwet_floors, src) - var/turf/T = parent - qdel(T.GetComponent(/datum/component/slippery)) - if(istype(T)) //If this is false there is so many things wrong with it. - T.cut_overlay(current_overlay) - else - stack_trace("Warning: Wet floor component wasn't on a turf when being destroyed! This is really bad!") - return ..() - -/datum/component/wet_floor/proc/update_overlay() - var/intended - if(!istype(parent, /turf/open/floor)) - intended = generic_turf_overlay - else - switch(highest_strength) - if(TURF_WET_PERMAFROST) - intended = permafrost_overlay - if(TURF_WET_ICE) - intended = ice_overlay - else - intended = water_overlay - if(current_overlay != intended) - var/turf/T = parent - T.cut_overlay(current_overlay) - T.add_overlay(intended) - current_overlay = intended - -/datum/component/wet_floor/proc/AfterSlip(mob/living/L) - if(highest_strength == TURF_WET_LUBE) - L.confused = max(L.confused, 8) - -/datum/component/wet_floor/proc/update_flags() - var/intensity - lube_flags = NONE - switch(highest_strength) - if(TURF_WET_WATER) - intensity = 60 - lube_flags = NO_SLIP_WHEN_WALKING - if(TURF_WET_LUBE) - intensity = 80 - lube_flags = SLIDE | GALOSHES_DONT_HELP - if(TURF_WET_ICE) - intensity = 120 - lube_flags = SLIDE | GALOSHES_DONT_HELP - if(TURF_WET_PERMAFROST) - intensity = 120 - lube_flags = SLIDE_ICE | GALOSHES_DONT_HELP - if(TURF_WET_SUPERLUBE) - intensity = 120 - lube_flags = SLIDE | GALOSHES_DONT_HELP | SLIP_WHEN_CRAWLING - else - qdel(parent.GetComponent(/datum/component/slippery)) - return - - parent.LoadComponent(/datum/component/slippery, intensity, lube_flags, CALLBACK(src, .proc/AfterSlip)) - -/datum/component/wet_floor/proc/dry(datum/source, strength = TURF_WET_WATER, immediate = FALSE, duration_decrease = INFINITY) - for(var/i in time_left_list) - if(text2num(i) <= strength) - time_left_list[i] = max(0, time_left_list[i] - duration_decrease) - if(immediate) - check() - -/datum/component/wet_floor/proc/max_time_left() - . = 0 - for(var/i in time_left_list) - . = max(., time_left_list[i]) - -/datum/component/wet_floor/process(delta_time) - var/turf/open/T = parent - var/diff = world.time - last_process - var/decrease = 0 - var/t = T.GetTemperature() - switch(t) - if(-INFINITY to T0C) - add_wet(TURF_WET_ICE, max_time_left()) //Water freezes into ice! - if(T0C to T0C + 100) - decrease = ((T.air.temperature - T0C) / SSwet_floors.temperature_coeff) * (diff / SSwet_floors.time_ratio) - if(T0C + 100 to INFINITY) - decrease = INFINITY - decrease = max(0, decrease) - if((is_wet() & TURF_WET_ICE) && t > T0C) //Ice melts into water! - for(var/obj/O in T.contents) - if(O.obj_flags & FROZEN) - O.make_unfrozen() - add_wet(TURF_WET_WATER, max_time_left()) - dry(null, TURF_WET_ICE) - dry(null, ALL, FALSE, decrease) - check() - last_process = world.time - -/datum/component/wet_floor/proc/update_strength() - highest_strength = 0 //Not bitflag. - for(var/i in time_left_list) - highest_strength = max(highest_strength, text2num(i)) - -/datum/component/wet_floor/proc/is_wet() - . = 0 - for(var/i in time_left_list) - . |= text2num(i) - -/datum/component/wet_floor/PreTransfer() - var/turf/O = parent - O.cut_overlay(current_overlay) - //That turf is no longer slippery, we're out of here - //Slippery components don't transfer due to callbacks - qdel(O.GetComponent(/datum/component/slippery)) - -/datum/component/wet_floor/PostTransfer() - if(!isopenturf(parent)) - return COMPONENT_INCOMPATIBLE - var/turf/T = parent - T.add_overlay(current_overlay) - //Make sure to add/update any slippery component on the new turf (update_flags calls LoadComponent) - update_flags() - - //NB it's possible we get deleted after this, due to inherit - -/datum/component/wet_floor/proc/add_wet(type, duration_minimum = 0, duration_add = 0, duration_maximum = MAXIMUM_WET_TIME, _permanent = FALSE) - var/static/list/allowed_types = list(TURF_WET_WATER, TURF_WET_LUBE, TURF_WET_ICE, TURF_WET_PERMAFROST, TURF_WET_SUPERLUBE) - if(duration_minimum <= 0 || !type) - return FALSE - if(type in allowed_types) - return _do_add_wet(type, duration_minimum, duration_add, duration_maximum) - else - . = NONE - for(var/i in allowed_types) - if(!(type & i)) - continue - . |= _do_add_wet(i, duration_minimum, duration_add, duration_maximum) - if(_permanent) - permanent = TRUE - STOP_PROCESSING(SSwet_floors, src) - -/datum/component/wet_floor/proc/_do_add_wet(type, duration_minimum, duration_add, duration_maximum) - var/time = 0 - if(LAZYACCESS(time_left_list, "[type]")) - time = clamp(LAZYACCESS(time_left_list, "[type]") + duration_add, duration_minimum, duration_maximum) - else - time = min(duration_minimum, duration_maximum) - LAZYSET(time_left_list, "[type]", time) - check(TRUE) - return TRUE - -/datum/component/wet_floor/proc/gc(on_init = FALSE) - if(!LAZYLEN(time_left_list)) - if(on_init) - var/turf/T = parent - stack_trace("Warning: Wet floor component gc'd right after initialization! What a waste of time and CPU! Type = [T? T.type : "ERROR - NO PARENT"], Location = [istype(T)? AREACOORD(T) : "ERROR - INVALID PARENT"].") - qdel(src) - return TRUE - return FALSE - -/datum/component/wet_floor/proc/check(force_update = FALSE) - var/changed = FALSE - for(var/i in time_left_list) - if(time_left_list[i] <= 0) - time_left_list -= i - changed = TRUE - if(changed || force_update) - update_strength() - update_overlay() - update_flags() - gc() diff --git a/code/datums/elements/cleaning.dm b/code/datums/elements/cleaning.dm deleted file mode 100644 index 96ade07744b..00000000000 --- a/code/datums/elements/cleaning.dm +++ /dev/null @@ -1,41 +0,0 @@ -/datum/element/cleaning/Attach(datum/target) - . = ..() - if(!ismovable(target)) - return ELEMENT_INCOMPATIBLE - RegisterSignal(target, COMSIG_MOVABLE_MOVED, .proc/Clean) - -/datum/element/cleaning/Detach(datum/target) - . = ..() - UnregisterSignal(target, COMSIG_MOVABLE_MOVED) - -/datum/element/cleaning/proc/Clean(datum/source) - var/atom/movable/AM = source - var/turf/tile = AM.loc - if(!isturf(tile)) - return - - SEND_SIGNAL(tile, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD) - for(var/A in tile) - if(is_cleanable(A)) - qdel(A) - else if(istype(A, /obj/item)) - var/obj/item/I = A - SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD) - if(ismob(I.loc)) - var/mob/M = I.loc - M.regenerate_icons() - else if(ishuman(A)) - var/mob/living/carbon/human/cleaned_human = A - if(!(cleaned_human.mobility_flags & MOBILITY_IS_STANDING)) - if(cleaned_human.head) - SEND_SIGNAL(cleaned_human.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD) - if(cleaned_human.wear_suit) - SEND_SIGNAL(cleaned_human.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD) - else if(cleaned_human.w_uniform) - SEND_SIGNAL(cleaned_human.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD) - if(cleaned_human.shoes) - SEND_SIGNAL(cleaned_human.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD) - SEND_SIGNAL(cleaned_human, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD) - cleaned_human.wash_cream() - cleaned_human.regenerate_icons() - to_chat(cleaned_human, "[AM] cleans your face!") diff --git a/code/datums/elements/digitalcamo.dm b/code/datums/elements/digitalcamo.dm deleted file mode 100644 index b264da40a99..00000000000 --- a/code/datums/elements/digitalcamo.dm +++ /dev/null @@ -1,35 +0,0 @@ -/datum/element/digitalcamo - element_flags = ELEMENT_DETACH - var/list/attached_mobs = list() - -/datum/element/digitalcamo/New() - . = ..() - START_PROCESSING(SSdcs, src) - -/datum/element/digitalcamo/Attach(datum/target) - . = ..() - if(!isliving(target) || target in attached_mobs) - return ELEMENT_INCOMPATIBLE - RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_examine) - RegisterSignal(target, COMSIG_LIVING_CAN_TRACK, .proc/can_track) - var/image/img = image(loc = target) - img.override = TRUE - attached_mobs[target] = img - -/datum/element/digitalcamo/Detach(datum/target) - . = ..() - UnregisterSignal(target, list(COMSIG_PARENT_EXAMINE, COMSIG_LIVING_CAN_TRACK)) - for(var/mob/living/silicon/ai/AI in GLOB.GLOB.player_list) - AI.client.images -= attached_mobs[target] - attached_mobs -= target - -/datum/element/digitalcamo/proc/on_examine(datum/source, mob/M) - to_chat(M, "[source.p_their()] skin seems to be shifting and morphing like is moving around below it.") - -/datum/element/digitalcamo/proc/can_track(datum/source) - return COMPONENT_CANT_TRACK - -/datum/element/digitalcamo/process(delta_time) - for(var/mob/living/silicon/ai/AI in GLOB.GLOB.player_list) - for(var/mob in attached_mobs) - AI.client.images |= attached_mobs[mob] diff --git a/code/datums/elements/earhealing.dm b/code/datums/elements/earhealing.dm deleted file mode 100644 index bfe7a1cc3c7..00000000000 --- a/code/datums/elements/earhealing.dm +++ /dev/null @@ -1,36 +0,0 @@ -/datum/element/earhealing - element_flags = ELEMENT_DETACH - var/list/user_by_item = list() - -/datum/element/earhealing/New() - START_PROCESSING(SSdcs, src) - -/datum/element/earhealing/Attach(datum/target) - . = ..() - if(!isitem(target)) - return ELEMENT_INCOMPATIBLE - - RegisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED), .proc/equippedChanged) - -/datum/element/earhealing/Detach(datum/target) - . = ..() - UnregisterSignal(target, list(COMSIG_ITEM_EQUIPPED, COMSIG_ITEM_DROPPED)) - user_by_item -= target - -/datum/element/earhealing/proc/equippedChanged(datum/source, mob/living/carbon/user, slot) - if(slot == SLOT_EARS && istype(user)) - user_by_item[source] = user - else - user_by_item -= source - -/datum/element/earhealing/process(delta_time) - for(var/i in user_by_item) - var/mob/living/carbon/user = user_by_item[i] - if(HAS_TRAIT(user, TRAIT_DEAF)) - continue - var/obj/item/organ/ears/ears = user.getorganslot(ORGAN_SLOT_EARS) - if(!ears) - continue - ears.deaf = max(ears.deaf - 0.25, (ears.damage < ears.maxHealth ? 0 : 1)) // Do not clear deafness if our ears are too damaged - ears.damage = max(ears.damage - 0.025, 0) - CHECK_TICK diff --git a/code/datums/elements/firestacker.dm b/code/datums/elements/firestacker.dm deleted file mode 100644 index fa24e3c2d6f..00000000000 --- a/code/datums/elements/firestacker.dm +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Can be applied to /atom/movable subtypes to make them apply fire stacks to things they hit - */ -/datum/element/firestacker - element_flags = ELEMENT_DETACH - /// A list in format {atom/movable/owner, number} - /// Used to keep track of movables which want to apply a different number of fire stacks than default - var/list/amount_by_owner = list() - -/datum/element/firestacker/Attach(datum/target, amount) - . = ..() - if(!ismovable(target)) - return ELEMENT_INCOMPATIBLE - RegisterSignal(target, COMSIG_MOVABLE_IMPACT, .proc/impact) - if(isitem(target)) - RegisterSignal(target, COMSIG_ITEM_ATTACK, .proc/item_attack) - RegisterSignal(target, COMSIG_ITEM_ATTACK_SELF, .proc/item_attack_self) - - if(amount) // If amount is not given we default to 1 and don't need to save it here - amount_by_owner[target] = amount - -/datum/element/firestacker/Detach(datum/source, force) - . = ..() - UnregisterSignal(source, list(COMSIG_MOVABLE_IMPACT, COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_SELF)) - amount_by_owner -= source - -/datum/element/firestacker/proc/stack_on(datum/owner, mob/living/target) - target.adjust_fire_stacks(amount_by_owner[owner] || 1) - -/datum/element/firestacker/proc/impact(datum/source, atom/hit_atom, datum/thrownthing/throwingdatum) - if(isliving(hit_atom)) - stack_on(source, hit_atom) - -/datum/element/firestacker/proc/item_attack(datum/source, atom/movable/target, mob/living/user) - if(isliving(target)) - stack_on(source, target) - -/datum/element/firestacker/proc/item_attack_self(datum/source, mob/user) - if(isliving(user)) - stack_on(source, user) diff --git a/code/datums/elements/light_blocking.dm b/code/datums/elements/light_blocking.dm deleted file mode 100644 index 8b4863256ac..00000000000 --- a/code/datums/elements/light_blocking.dm +++ /dev/null @@ -1,44 +0,0 @@ -//! Prerequisites: Opacity Refactor @Zandario - -/** - * Attached to movable atoms with opacity. Listens to them move and updates their old and new turf loc's opacity accordingly. - */ -/datum/element/light_blocking - element_flags = ELEMENT_DETACH - - -/datum/element/light_blocking/Attach(datum/target) - . = ..() - if(!ismovable(target)) - return ELEMENT_INCOMPATIBLE - // RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(on_target_move)) - RegisterSignal(target, COMSIG_MOVABLE_MOVED, .proc/on_target_move) - var/atom/movable/movable_target = target - if(!isturf(movable_target.loc)) - return - for(var/turf/turf_loc as anything in movable_target.locs) - turf_loc.add_opacity_source(target) - - -/datum/element/light_blocking/Detach(datum/target) - . = ..() - UnregisterSignal(target, list(COMSIG_MOVABLE_MOVED)) - var/atom/movable/movable_target = target - if(!isturf(movable_target.loc)) - return - for(var/turf/turf_loc as anything in movable_target.locs) - turf_loc.remove_opacity_source(target) - -///Updates old and new turf loc opacities. -/datum/element/light_blocking/proc/on_target_move(atom/movable/source, atom/old_loc, dir, forced, list/old_locs) - SIGNAL_HANDLER - if(isturf(old_loc)) - if(old_locs) - for(var/turf/old_turf as anything in old_locs) - old_turf.remove_opacity_source(source) - else - var/turf/old_turf = old_loc - old_turf.remove_opacity_source(source) - if(isturf(source.loc)) - for(var/turf/new_turf as anything in source.locs) - new_turf.add_opacity_source(source) diff --git a/code/datums/elements/snail_crawl.dm b/code/datums/elements/snail_crawl.dm deleted file mode 100644 index 7447b7e59c8..00000000000 --- a/code/datums/elements/snail_crawl.dm +++ /dev/null @@ -1,31 +0,0 @@ -/datum/element/snailcrawl - element_flags = ELEMENT_DETACH - -/datum/element/snailcrawl/Attach(datum/target) - . = ..() - if(!ismovable(target)) - return ELEMENT_INCOMPATIBLE - var/P - if(iscarbon(target)) - P = .proc/snail_crawl - else - P = .proc/lubricate - RegisterSignal(target, COMSIG_MOVABLE_MOVED, P) - -/datum/element/snailcrawl/Detach(mob/living/carbon/target) - . = ..() - UnregisterSignal(target, COMSIG_MOVABLE_MOVED) - if(istype(target)) - target.remove_movespeed_modifier(MOVESPEED_ID_SNAIL_CRAWL) - -/datum/element/snailcrawl/proc/snail_crawl(mob/living/carbon/snail) - if(snail.resting && !snail.buckled && lubricate(snail)) - snail.add_movespeed_modifier(MOVESPEED_ID_SNAIL_CRAWL, update=TRUE, priority=100, multiplicative_slowdown=-7, movement_type=MOVEMENT_GROUND) - else - snail.remove_movespeed_modifier(MOVESPEED_ID_SNAIL_CRAWL) - -/datum/element/snailcrawl/proc/lubricate(atom/movable/snail) - var/turf/open/OT = get_turf(snail) - if(istype(OT)) - OT.MakeSlippery(TURF_WET_LUBE, 20) - return TRUE diff --git a/code/datums/elements/update_icon_blocker.dm b/code/datums/elements/update_icon_blocker.dm deleted file mode 100644 index 45206772564..00000000000 --- a/code/datums/elements/update_icon_blocker.dm +++ /dev/null @@ -1,18 +0,0 @@ -/// Prevents calling anything in update_icon() like update_icon_state() or update_overlays() -/datum/element/update_icon_blocker - -/datum/element/update_icon_blocker/Attach(datum/target) - . = ..() - if(!isatom(target)) - return ELEMENT_INCOMPATIBLE - - RegisterSignal(target, COMSIG_ATOM_UPDATE_ICON, .proc/block_update_icon) - -/datum/element/update_icon_blocker/Detach(datum/source, ...) - UnregisterSignal(source, COMSIG_ATOM_UPDATE_ICON) - return ..() - -/datum/element/update_icon_blocker/proc/block_update_icon() - SIGNAL_HANDLER - - return COMSIG_ATOM_NO_UPDATE_ICON_STATE | COMSIG_ATOM_NO_UPDATE_OVERLAYS