diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index ffc637b21bc..8fb5232099e 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -36,8 +36,6 @@ #define isprojectile(A) (istype(A, /obj/item/projectile)) -#define is_cleanable(A) (istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/rune)) //if something is cleanable - #define is_pen(W) (istype(W, /obj/item/pen)) #define is_pda(W) (istype(W, /obj/item/pda)) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 067da4146ec..286f1d04aad 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -89,6 +89,8 @@ #define HIGH_LANDMARK_LAYER 9.2 #define AREA_LAYER 10 #define MASSIVE_OBJ_LAYER 11 + +#define POINT_PLANE 14 #define POINT_LAYER 12 #define CHAT_LAYER 12.0001 // Do not insert layers between these two values diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 03a9b25044c..acb44796abc 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -31,6 +31,10 @@ var/moving_diagonally = 0 //0: not doing a diagonal move. 1 and 2: doing the first/second step of the diagonal move var/list/client_mobs_in_contents + /// Icon state for thought bubbles. Normally set by mobs. + var/thought_bubble_image = "thought_bubble" + + /atom/movable/attempt_init(loc, ...) var/turf/T = get_turf(src) if(T && SSatoms.initialized != INITIALIZATION_INSSATOMS && GLOB.space_manager.is_zlevel_dirty(T.z)) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index af6d3598d75..02f3c47f824 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -130,6 +130,8 @@ To draw a rune, use a ritual dagger. visible_message("[src] suddenly appears!") alpha = initial(alpha) +/obj/effect/rune/is_cleanable() + return TRUE /* There are a few different procs each rune runs through when a cultist activates it. diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm index 4636e9cd449..9521f1d4c92 100644 --- a/code/game/gamemodes/nuclear/pinpointer.dm +++ b/code/game/gamemodes/nuclear/pinpointer.dm @@ -108,7 +108,7 @@ if(!the_s_bomb) the_s_bomb = locate() -/obj/item/pinpointer/proc/point_at(atom/target) +/obj/item/pinpointer/proc/pinpoint_at(atom/target) if(!target) icon_state = icon_null return @@ -132,15 +132,15 @@ /obj/item/pinpointer/proc/workdisk() scandisk() - point_at(the_disk) + pinpoint_at(the_disk) /obj/item/pinpointer/proc/workbomb() if(!syndicate) scanbomb() - point_at(the_bomb) + pinpoint_at(the_bomb) else scanbomb() - point_at(the_s_bomb) + pinpoint_at(the_s_bomb) /obj/item/pinpointer/examine(mob/user) . = ..() @@ -163,13 +163,13 @@ if(SETTING_DISK) workdisk() if(SETTING_LOCATION) - point_at(location) + pinpoint_at(location) if(SETTING_OBJECT) - point_at(target) + pinpoint_at(target) /obj/item/pinpointer/advpinpointer/workdisk() //since mode works diffrently for advpinpointer scandisk() - point_at(the_disk) + pinpoint_at(the_disk) /obj/item/pinpointer/advpinpointer/AltClick(mob/user) . = ..() @@ -280,7 +280,7 @@ visible_message("Shuttle Locator mode actived.") //Lets the mob holding it know that the mode has changed return //Get outta here scandisk() - point_at(the_disk) + pinpoint_at(the_disk) /obj/item/pinpointer/nukeop/workbomb() if(GLOB.bomb_set) //If the bomb is set, lead to the shuttle @@ -290,7 +290,7 @@ visible_message("Shuttle Locator mode actived.") //Lets the mob holding it know that the mode has changed return //Get outta here scanbomb() - point_at(the_s_bomb) + pinpoint_at(the_s_bomb) /obj/item/pinpointer/nukeop/proc/worklocation() if(!GLOB.bomb_set) @@ -307,7 +307,7 @@ if(loc.z != home.z) //If you are on a different z-level from the shuttle icon_state = icon_null else - point_at(home) + pinpoint_at(home) /obj/item/pinpointer/operative name = "operative pinpointer" @@ -340,7 +340,7 @@ /obj/item/pinpointer/operative/proc/workop() if(mode == MODE_OPERATIVE) scan_for_ops() - point_at(nearest_op, FALSE) + pinpoint_at(nearest_op, FALSE) else return FALSE @@ -375,7 +375,7 @@ /obj/item/pinpointer/ninja/proc/workninja() scan_for_ninja() - point_at(nearest_ninja, FALSE) + pinpoint_at(nearest_ninja, FALSE) /obj/item/pinpointer/ninja/examine(mob/user) . = ..() @@ -413,9 +413,9 @@ /obj/item/pinpointer/crew/process() if(mode == MODE_CREW && target_set) - point_at(target) + pinpoint_at(target) -/obj/item/pinpointer/crew/point_at(atom/target) +/obj/item/pinpointer/crew/pinpoint_at(atom/target) if(!target || !trackable(target)) icon_state = icon_null return @@ -490,9 +490,9 @@ /obj/item/pinpointer/thief/process() switch(setting) if(SETTING_LOCATION) - point_at(location) + pinpoint_at(location) if(SETTING_OBJECT) - point_at(target) + pinpoint_at(target) /obj/item/pinpointer/thief/cycle(mob/user) @@ -699,14 +699,14 @@ /obj/item/pinpointer/tendril/process() if(mode == MODE_TENDRIL) find_tendril() - point_at(target, FALSE) + pinpoint_at(target, FALSE) else icon_state = icon_off /obj/item/pinpointer/tendril/proc/find_tendril() if(mode == MODE_TENDRIL) scan_for_tendrils() - point_at(target) + pinpoint_at(target) else return FALSE diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index f7c010f6ccf..ab9d10c954a 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -53,6 +53,9 @@ /obj/effect/decal/cleanable/proc/can_bloodcrawl_in() return FALSE +/obj/effect/decal/cleanable/is_cleanable() + return TRUE + /obj/effect/decal/cleanable/Initialize(mapload) . = ..() if(loc && isturf(loc)) diff --git a/code/game/objects/effects/effects.dm b/code/game/objects/effects/effects.dm index 12027879d0b..0bbace48d63 100644 --- a/code/game/objects/effects/effects.dm +++ b/code/game/objects/effects/effects.dm @@ -6,7 +6,7 @@ icon = 'icons/effects/effects.dmi' resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF move_resist = INFINITY - anchored = 1 + anchored = TRUE can_be_hit = FALSE /obj/effect/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) @@ -22,6 +22,9 @@ /obj/effect/acid_act() return +/obj/effect/proc/is_cleanable() //Called when you want to clean something, and usualy delete it after + return FALSE + /obj/effect/mech_melee_attack(obj/mecha/M) return 0 @@ -55,6 +58,7 @@ density = FALSE icon = null icon_state = null + armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) // Most of these overrides procs below are overkill, but better safe than sorry. /obj/effect/abstract/swarmer_act() @@ -81,6 +85,15 @@ /obj/effect/abstract/ex_act(severity) return +/obj/effect/abstract/blob_act() + return + +/obj/effect/abstract/acid_act() + return + +/obj/effect/abstract/fire_act() + return + /obj/effect/decal plane = FLOOR_PLANE resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 6dbd6d6b8e9..e8ba25e2089 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -1,12 +1,3 @@ -/obj/effect/temp_visual/point - name = "arrow" - desc = "It's an arrow hanging in mid-air. There may be a wizard about." - icon = 'icons/mob/screen_gen.dmi' - icon_state = "arrow" - layer = POINT_LAYER - duration = 20 - randomdir = FALSE - /obj/effect/temp_visual/dir_setting/bloodsplatter icon = 'icons/effects/blood.dmi' duration = 5 diff --git a/code/game/objects/items/weapons/mop.dm b/code/game/objects/items/weapons/mop.dm index d9085eb6764..5593fe302d7 100644 --- a/code/game/objects/items/weapons/mop.dm +++ b/code/game/objects/items/weapons/mop.dm @@ -39,7 +39,7 @@ if(reagents.has_reagent("water", 1) || reagents.has_reagent("cleaner", 1) || reagents.has_reagent("holywater", 1)) A.clean_blood() for(var/obj/effect/O in A) - if(is_cleanable(O)) + if(O.is_cleanable()) qdel(O) reagents.reaction(A, REAGENT_TOUCH, 10) //10 is the multiplier for the reaction effect. probably needed to wet the floor properly. reagents.remove_any(1) //reaction() doesn't use up the reagents diff --git a/code/game/objects/items/weapons/soap.dm b/code/game/objects/items/weapons/soap.dm index cbea25203e7..c3ad7d3664f 100644 --- a/code/game/objects/items/weapons/soap.dm +++ b/code/game/objects/items/weapons/soap.dm @@ -49,7 +49,7 @@ /obj/item/soap/proc/clean_turf(turf/simulated/T) T.clean_blood() for(var/obj/effect/O in T) - if(is_cleanable(O)) + if(O.is_cleanable()) qdel(O) /obj/item/soap/attack(mob/target as mob, mob/user as mob) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 59b4cc47a1a..82934cd6bf5 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -453,7 +453,7 @@ var/turf/tile = loc loc.clean_blood() for(var/obj/effect/E in tile) - if(is_cleanable(E)) + if(E.is_cleanable()) qdel(E) /obj/machinery/shower/process() diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 36d26121c7c..954485ae7e0 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -3637,7 +3637,7 @@ N.mode = 3 //MODE_ADV, not defined here N.setting = 2 //SETTING_OBJECT, not defined here N.target = H - N.point_at(N.target) + N.pinpoint_at(N.target) N.modelocked = TRUE if(!locate(/obj/item/implant/dust, hunter_mob)) var/obj/item/implant/dust/D = new /obj/item/implant/dust(hunter_mob) diff --git a/code/modules/antagonists/traitor/contractor/items/contractor_pinpointer.dm b/code/modules/antagonists/traitor/contractor/items/contractor_pinpointer.dm index cff025b7ea6..1d7f33f564f 100644 --- a/code/modules/antagonists/traitor/contractor/items/contractor_pinpointer.dm +++ b/code/modules/antagonists/traitor/contractor/items/contractor_pinpointer.dm @@ -13,7 +13,7 @@ /// The first person to have used the item. If this is set already, no one else can use it. var/mob/owner = null -/obj/item/pinpointer/crew/contractor/point_at(atom/target) +/obj/item/pinpointer/crew/contractor/pinpoint_at(atom/target) if(target && trackable(target)) // Calc dir var/turf/T = get_turf(target) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index baed069f0d6..9776af07f1f 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -675,19 +675,23 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, ignore_lying = FALSE) return TRUE -//this is a mob verb instead of atom for performance reasons -//see /mob/verb/examinate() in mob.dm for more info -//overriden here and in /mob/living for different point span classes and sanity checks -/mob/dead/observer/run_pointed(atom/A as mob|obj|turf) + +/** + * This is a mob verb instead of atom for performance reasons. + * See /mob/verb/examinate() in mob.dm for more info. + * Overriden here and in /mob/living for different point span classes and sanity checks. + */ +/mob/dead/observer/run_pointed(atom/target) if(!..()) return FALSE var/follow_link if(invisibility) // Only show the button if the ghost is not visible to the living - follow_link = " ([ghost_follow_link(A, src)])" - usr.visible_message("[src] points to [A][follow_link].") - add_deadchat_logs(src, "point to [key_name(A)] [COORD(A)]") + follow_link = " ([ghost_follow_link(target, src)])" + usr.visible_message(span_deadsay("[src] points to [target][follow_link].")) + add_deadchat_logs(src, "point to [key_name(target)] [COORD(target)]") return TRUE + /mob/dead/observer/proc/incarnate_ghost() if(!client) return diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm index 93bbd8aced4..e5915dbedb0 100644 --- a/code/modules/mob/living/carbon/brain/brain_item.dm +++ b/code/modules/mob/living/carbon/brain/brain_item.dm @@ -83,6 +83,7 @@ if(ishuman(owner)) owner.update_hair() + owner.thought_bubble_image = initial(owner.thought_bubble_image) . = ..() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index fb88fc03a2d..c1e17c8380a 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -309,24 +309,43 @@ return FALSE return ..() -/mob/living/run_pointed(atom/A) + +/mob/living/run_pointed(atom/target) if(!..()) return FALSE + var/obj/item/hand_item = get_active_hand() - if(istype(hand_item, /obj/item/gun) && A != hand_item) - if(a_intent == INTENT_HELP || !ismob(A)) - visible_message("[src.declent_ru(NOMINATIVE)] указыва[pluralize_ru(src.gender,"ет","ют")] [hand_item.declent_ru(INSTRUMENTAL)] на [A.declent_ru(ACCUSATIVE)]") - add_emote_logs(src, "point [hand_item] to [key_name(A)] [COORD(A)]") + var/pointed_object = "[target.declent_ru(ACCUSATIVE)]" + + if(target.loc in src) + var/atom/inside = target.loc + pointed_object += " внутри [inside.declent_ru(GENITIVE)]" + + if(istype(hand_item, /obj/item/gun) && target != hand_item) + if(a_intent == INTENT_HELP || !ismob(target)) + visible_message("[declent_ru(NOMINATIVE)] указыва[pluralize_ru(gender,"ет","ют")] [hand_item.declent_ru(INSTRUMENTAL)] на [pointed_object].") return TRUE - A.visible_message("[src.declent_ru(NOMINATIVE)] указыва[pluralize_ru(src.gender,"ет","ют")] [hand_item.declent_ru(INSTRUMENTAL)] на [A.declent_ru(ACCUSATIVE)]!", - "[src.declent_ru(NOMINATIVE)] указыва[pluralize_ru(src.gender,"ет","ют")] [hand_item.declent_ru(INSTRUMENTAL)] на [pluralize_ru(A.gender,"тебя","вас")]!") - A << 'sound/weapons/targeton.ogg' - add_emote_logs(src, "point [hand_item] HARM to [key_name(A)] [COORD(A)]") + + target.visible_message( + span_danger("[declent_ru(NOMINATIVE)] указыва[pluralize_ru(src.gender,"ет","ют")] [hand_item.declent_ru(INSTRUMENTAL)] на [pointed_object]!"), + span_userdanger("[declent_ru(NOMINATIVE)] указыва[pluralize_ru(src.gender,"ет","ют")] [hand_item.declent_ru(INSTRUMENTAL)] на [pluralize_ru(target.gender,"тебя","вас")]!"), + ) + SEND_SOUND(target, sound('sound/weapons/targeton.ogg')) + add_emote_logs(src, "point [hand_item] HARM to [key_name(target)] [COORD(target)]") return TRUE - visible_message("[src.declent_ru(NOMINATIVE)] указыва[pluralize_ru(src.gender,"ет","ют")] на [A.declent_ru(ACCUSATIVE)]") - add_emote_logs(src, "point to [key_name(A)] [COORD(A)]") + + if(istype(hand_item, /obj/item/toy/russian_revolver/trick_revolver) && target != hand_item) + var/obj/item/toy/russian_revolver/trick_revolver/trick = hand_item + visible_message(span_danger("[declent_ru(NOMINATIVE)] указыва[pluralize_ru(src.gender,"ет","ют")] [trick.declent_ru(INSTRUMENTAL)] на... и [trick.declent_ru(NOMINATIVE)] срабатывает у [genderize_ru(gender, "него","неё","него","них")] в руке!")) + trick.shoot_gun(src) + add_emote_logs(src, "point to [key_name(target)] [COORD(target)]") + return TRUE + + visible_message("[declent_ru(NOMINATIVE)] указыва[pluralize_ru(gender,"ет","ют")] на [pointed_object].") + add_emote_logs(src, "point to [key_name(target)] [COORD(target)]") return TRUE + /mob/living/verb/succumb() set hidden = 1 if(InCritical()) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 44d51f2b8ee..8f9b5c359fa 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1341,13 +1341,14 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( if(stat != DEAD && isturf(tile)) var/floor_only = TRUE for(var/A in tile) - if(istype(A, /obj/effect)) - if(is_cleanable(A)) - var/obj/effect/decal/cleanable/blood/B = A + if(iseffect(A)) + var/obj/effect/check = A + if(check.is_cleanable()) + var/obj/effect/decal/cleanable/blood/B = check if(istype(B) && B.off_floor) floor_only = FALSE else - qdel(A) + qdel(B) else if(istype(A, /obj/item)) var/obj/item/cleaned_item = A cleaned_item.clean_blood() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 56e76c161fc..f6f4367f38d 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -314,40 +314,6 @@ var/list/result = A.examine(src) to_chat(src, "