diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index cea4d6143cd..37976a9e749 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -4121,7 +4121,7 @@ "bBo" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/quartermaster/office) "bBp" = (/obj/structure/table,/obj/machinery/light{dir = 4},/obj/machinery/recharger,/turf/simulated/floor/plasteel{icon_state = "arrival"; dir = 4},/area/quartermaster/office) "bBq" = (/obj/machinery/atm{pixel_x = -32},/turf/simulated/floor/plasteel{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central/west) -"bBr" = (/obj/item/weapon/hand_labeler,/obj/item/device/assembly/timer,/obj/structure/table,/turf/simulated/floor/wood,/area/bridge/meeting_room) +"bBr" = (/obj/item/device/assembly/timer,/obj/structure/table,/obj/item/stack/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor/wood,/area/bridge/meeting_room) "bBs" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/wood,/area/bridge/meeting_room) "bBt" = (/obj/structure/stool/bed/chair/comfy/black{dir = 4},/turf/simulated/floor/carpet,/area/bridge/meeting_room) "bBu" = (/obj/structure/table/woodentable,/obj/item/device/radio/intercom/command,/turf/simulated/floor/carpet,/area/bridge/meeting_room) @@ -4803,7 +4803,7 @@ "bOu" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plasteel,/area/hallway/primary/central/sw) "bOv" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/obj/item/device/radio/intercom{dir = 4; name = "station intercom (General)"; pixel_x = 28},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/hallway/primary/central/sw) "bOw" = (/obj/machinery/computer/secure_data,/obj/machinery/flasher_button{id = "hopflash"; pixel_x = 6; pixel_y = 36},/obj/machinery/door_control{id = "hopqueue"; name = "Queue Privacy Shutters Control"; pixel_x = -4; pixel_y = 25; req_access_txt = "28"},/obj/machinery/door_control{id = "hop"; name = "Privacy Shutters Control"; pixel_x = 6; pixel_y = 25; req_access_txt = "28"},/obj/machinery/light_switch{pixel_x = -4; pixel_y = 36},/turf/simulated/floor/plasteel{dir = 9; icon_state = "blue"},/area/crew_quarters/heads) -"bOx" = (/obj/structure/table,/obj/machinery/newscaster/security_unit{pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/stack/packageWrap,/obj/item/weapon/hand_labeler,/turf/simulated/floor/plasteel,/area/crew_quarters/heads) +"bOx" = (/obj/structure/table,/obj/machinery/newscaster/security_unit{pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/computer/skills{req_access_txt = "57"},/turf/simulated/floor/plasteel,/area/crew_quarters/heads) "bOy" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/obj/machinery/recharger/wallcharger{pixel_x = 0; pixel_y = 30},/turf/simulated/floor/plasteel,/area/crew_quarters/heads) "bOz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/photocopier,/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plasteel,/area/crew_quarters/heads) "bOA" = (/obj/machinery/light{dir = 4; icon_state = "tube1"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plasteel,/area/crew_quarters/heads) diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index a20efc98a06..0090dd654fd 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -3,15 +3,18 @@ //PUBLIC - call these wherever you want -/mob/proc/throw_alert(category, type, severity, obj/new_master) +/mob/proc/throw_alert(category, type, severity, obj/new_master, override = FALSE) -/* Proc to create or update an alert. Returns the alert if the alert is new or updated, 0 if it was thrown already +/* + Proc to create or update an alert. Returns the alert if the alert is new or updated, 0 if it was thrown already category is a text string. Each mob may only have one alert per category; the previous one will be replaced path is a type path of the actual alert type to throw severity is an optional number that will be placed at the end of the icon_state for this alert For example, high pressure's icon_state is "highpressure" and can be serverity 1 or 2 to get "highpressure1" or "highpressure2" new_master is optional and sets the alert's icon state to "template" in the ui_style icons with the master as an overlay. - Clicks are forwarded to master */ + Clicks are forwarded to master + Override makes it so the alert is not replaced until cleared by a clear_alert with clear_override, and it's used for hallucinations. + */ if(!category) return @@ -19,6 +22,8 @@ var/obj/screen/alert/alert if(alerts[category]) alert = alerts[category] + if(alert.override_alerts) + return 0 if(new_master && new_master != alert.master) WARNING("[src] threw alert [category] with new_master [new_master] while already having that alert with master [alert.master]") clear_alert(category) @@ -33,7 +38,10 @@ else //no need to update return 0 else - alert = new type + alert = new type() + alert.override_alerts = override + if(override) + alert.timeout = null if(new_master) var/old_layer = new_master.layer @@ -63,10 +71,12 @@ return alert // Proc to clear an existing alert. -/mob/proc/clear_alert(category) +/mob/proc/clear_alert(category, clear_override = FALSE) var/obj/screen/alert/alert = alerts[category] if(!alert) return 0 + if(alert.override_alerts && !clear_override) + return 0 alerts -= category if(client && hud_used) @@ -83,6 +93,7 @@ var/timeout = 0 //If set to a number, this alert will clear itself after that many deciseconds var/severity = 0 var/alerttooltipstyle = "" + var/override_alerts = FALSE //If it is overriding other alerts of the same type /obj/screen/alert/MouseEntered(location,control,params) @@ -197,12 +208,12 @@ The box in your backpack has an oxygen tank and gas mask in it." name = "High Pressure" desc = "The air around you is hazardously thick. A fire suit would protect you." icon_state = "highpressure" - + /obj/screen/alert/lightexposure name = "Light Exposure" desc = "You're exposed to light." icon_state = "lightexposure" - + /obj/screen/alert/nolight name = "No Light" desc = "You're not exposed to any light." diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm index 6988d2b16dd..62c3a9a00b0 100644 --- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm +++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm @@ -104,9 +104,7 @@ speed = 0 boost = world.time + 60 - - - +// Cult slaughter demon /mob/living/simple_animal/slaughter/cult //Summoned as part of the cult objective "Bring the Slaughter" name = "harbringer of the slaughter" real_name = "harbringer of the Slaughter" @@ -154,17 +152,18 @@ /mob/living/simple_animal/slaughter/cult/New() ..() spawn(5) - var/list/demon_candidates = get_candidates(ROLE_CULTIST) + var/list/demon_candidates = pollCandidates("Do you want to play as a slaughter demon?", ROLE_DEMON, 1, 100) if(!demon_candidates.len) visible_message("[src] disappears in a flash of red light!") qdel(src) return 0 - var/client/C = pick(demon_candidates) + var/mob/M = pick(demon_candidates) var/mob/living/simple_animal/slaughter/cult/S = src - if(!C) + if(!M || !M.client) visible_message("[src] disappears in a flash of red light!") qdel(src) return 0 + var/client/C = M.client S.key = C.key S.mind.assigned_role = "Harbringer of the Slaughter" @@ -181,7 +180,7 @@ ////////////////////The Powers -//Paradise Port:I added this cuase..SPOOPY DEMON IN YOUR BRAIN +//Paradise Port: I added this because..SPOOPY DEMON IN YOUR BRAIN /datum/action/innate/demon/whisper diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 194d5655eb1..a708e06fe93 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -110,6 +110,7 @@ return add_fingerprint(user) + user.changeNext_move(CLICK_CD_MELEE) if(can_force && (!glass || user.a_intent != I_HELP)) user.visible_message("[user] begins forcing \the [src].", \ @@ -119,7 +120,6 @@ "You force \the [src].") open() else if(glass) - user.changeNext_move(CLICK_CD_MELEE) user.visible_message("[user] bangs on \the [src].", "You bang on \the [src].") playsound(get_turf(src), 'sound/effects/Glassknock.ogg', 10, 1) diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 48e01dba29b..9ac4897c8f3 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -35,6 +35,7 @@ return 0 on = !on + playsound(user, 'sound/weapons/empty.ogg', 100, 1) update_brightness(user) for(var/X in actions) var/datum/action/A = X diff --git a/code/game/objects/items/weapons/RCL.dm b/code/game/objects/items/weapons/RCL.dm new file mode 100644 index 00000000000..524fd38eb80 --- /dev/null +++ b/code/game/objects/items/weapons/RCL.dm @@ -0,0 +1,151 @@ +/obj/item/weapon/twohanded/rcl + name = "rapid cable layer (RCL)" + desc = "A device used to rapidly deploy cables. It has screws on the side which can be removed to slide off the cables." + icon = 'icons/obj/tools.dmi' + icon_state = "rcl-0" + item_state = "rcl-0" + opacity = 0 + force = 5 //Plastic is soft + throwforce = 5 + throw_speed = 1 + throw_range = 7 + w_class = WEIGHT_CLASS_NORMAL + origin_tech = "engineering=4;materials=4" + var/max_amount = 90 + var/active = 0 + var/obj/structure/cable/last = null + var/obj/item/stack/cable_coil/loaded = null + +/obj/item/weapon/twohanded/rcl/attackby(obj/item/weapon/W, mob/user) + if(istype(W, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/C = W + if(!loaded) + if(user.drop_item()) + loaded = W + loaded.forceMove(src) + loaded.max_amount = max_amount //We store a lot. + else + to_chat(user, "[user.get_active_hand()] is stuck to your hand!") + return + else + if(loaded.amount < max_amount) + var/amount = min(loaded.amount + C.amount, max_amount) + C.use(amount - loaded.amount) + loaded.amount = amount + else + return + update_icon() + to_chat(user, "You add the cables to the [src]. It now contains [loaded.amount].") + else if(isscrewdriver(W)) + if(!loaded) + return + to_chat(user, "You loosen the securing screws on the side, allowing you to lower the guiding edge and retrieve the wires.") + while(loaded.amount > 30) //There are only two kinds of situations: "nodiff" (60,90), or "diff" (31-59, 61-89) + var/diff = loaded.amount % 30 + if(diff) + loaded.use(diff) + new /obj/item/stack/cable_coil(user.loc, diff) + else + loaded.use(30) + new /obj/item/stack/cable_coil(user.loc, 30) + loaded.max_amount = initial(loaded.max_amount) + loaded.forceMove(user.loc) + user.put_in_hands(loaded) + loaded = null + update_icon() + else + ..() + +/obj/item/weapon/twohanded/rcl/examine(mob/user) + ..() + if(loaded) + to_chat(user, "It contains [loaded.amount]/[max_amount] cables.") + +/obj/item/weapon/twohanded/rcl/Destroy() + if(loaded) + qdel(loaded) + loaded = null + last = null + active = 0 + return ..() + +/obj/item/weapon/twohanded/rcl/update_icon() + if(!loaded) + icon_state = "rcl-0" + item_state = "rcl-0" + return + switch(loaded.amount) + if(61 to INFINITY) + icon_state = "rcl-30" + item_state = "rcl" + if(31 to 60) + icon_state = "rcl-20" + item_state = "rcl" + if(1 to 30) + icon_state = "rcl-10" + item_state = "rcl" + else + icon_state = "rcl-0" + item_state = "rcl-0" + +/obj/item/weapon/twohanded/rcl/proc/is_empty(mob/user, loud = 1) + update_icon() + if(!loaded || !loaded.amount) + if(loud) + to_chat(user, "The last of the cables unreel from [src].") + if(loaded) + qdel(loaded) + loaded = null + unwield(user) + active = wielded + return 1 + return 0 + +/obj/item/weapon/twohanded/rcl/dropped(mob/wearer) + ..() + active = 0 + last = null + +/obj/item/weapon/twohanded/rcl/attack_self(mob/user) + ..() + active = wielded + if(!active) + last = null + else if(!last) + for(var/obj/structure/cable/C in get_turf(user)) + if(C.d1 == 0 || C.d2 == 0) + last = C + break + +/obj/item/weapon/twohanded/rcl/moved(mob/user, turf/old_loc, direct) + if(active) + trigger(user) + +/obj/item/weapon/twohanded/rcl/proc/trigger(mob/user) + if(is_empty(user, 0)) + to_chat(user, "\The [src] is empty!") + return + if(last) + if(get_dist(last, user) == 1) //hacky, but it works + var/turf/T = get_turf(user) + if(!isturf(T) || T.intact || !T.can_have_cabling()) + last = null + return + if(get_dir(last, user) == last.d2) + //Did we just walk backwards? Well, that's the one direction we CAN'T complete a stub. + last = null + return + loaded.cable_join(last, user) + if(is_empty(user)) + return //If we've run out, display message and exit + else + last = null + last = loaded.place_turf(get_turf(loc), user, turn(user.dir, 180)) + is_empty(user) //If we've run out, display message + +/obj/item/weapon/twohanded/rcl/pre_loaded/New() //Comes preloaded with cable, for testing stuff + ..() + loaded = new() + loaded.max_amount = max_amount + loaded.amount = max_amount + update_icon() \ No newline at end of file diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index e1c42feb07c..6e1ba7eb742 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -58,16 +58,18 @@ qdel(src) else if(iswelder(W) && !anchored) - playsound(loc, W.usesound, 40, 1) - user.visible_message("[user] is slicing apart the [name].", \ - "You are slicing apart the [name]...") - if(do_after(user, 40 * W.toolspeed, target = src)) - if(!loc) - return - playsound(loc, W.usesound, 50, 1) - user.visible_message("[user] slices apart the [name].", \ - "You slice apart the [name]!") - Dismantle(TRUE) + var/obj/item/weapon/weldingtool/WT = W + if(WT.remove_fuel(0, user)) + playsound(loc, W.usesound, 40, 1) + user.visible_message("[user] is slicing apart the [name].", \ + "You are slicing apart the [name]...") + if(do_after(user, 40 * W.toolspeed, target = src)) + if(!loc) + return + playsound(loc, W.usesound, 50, 1) + user.visible_message("[user] slices apart the [name].", \ + "You slice apart the [name]!") + Dismantle(TRUE) else hardness -= W.force/100 ..() diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm index 2cc77fc46b8..dca0d24742c 100644 --- a/code/game/turfs/simulated/walls_reinforced.dm +++ b/code/game/turfs/simulated/walls_reinforced.dm @@ -313,4 +313,3 @@ else smooth = SMOOTH_TRUE icon_state = "" - diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 69b0df22ae3..a5e4190d6ea 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -386,15 +386,25 @@ if(ticker) cameranet.updateVisibility(src) -/turf/attackby(obj/item/C, mob/user, params) - if(can_lay_cable() && istype(C, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/coil = C - for(var/obj/structure/cable/LC in src) - if((LC.d1==0)||(LC.d2==0)) - LC.attackby(C,user) - return - coil.place_turf(src, user) - return 1 +/turf/attackby(obj/item/I, mob/user, params) + if(can_lay_cable()) + if(istype(I, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/C = I + for(var/obj/structure/cable/LC in src) + if(LC.d1 == 0 || LC.d2==0) + LC.attackby(C,user) + return + C.place_turf(src, user) + return 1 + else if(istype(I, /obj/item/weapon/twohanded/rcl)) + var/obj/item/weapon/twohanded/rcl/R = I + if(R.loaded) + for(var/obj/structure/cable/LC in src) + if(LC.d1 == 0 || LC.d2==0) + LC.attackby(R, user) + return + R.loaded.place_turf(src, user) + R.is_empty(user) return 0 diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index 08123d6934e..0e52ba46d3d 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -135,12 +135,24 @@ desc = "A paramedic EVA helmet. Used in the recovery of bodies from space." icon_state = "paramedic-eva-helmet" item_state = "paramedic-eva-helmet" + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/helmet.dmi' + ) + sprite_sheets_obj = list( + "Vox" = 'icons/obj/clothing/species/vox/hats.dmi' + ) /obj/item/clothing/suit/space/eva/paramedic name = "Paramedic EVA suit" icon_state = "paramedic-eva" item_state = "paramedic-eva" desc = "A paramedic EVA suit. Used in the recovery of bodies from space." + sprite_sheets = list( + "Vox" = 'icons/mob/species/vox/suit.dmi' + ) + sprite_sheets_obj = list( + "Vox" = 'icons/obj/clothing/species/vox/suits.dmi' + ) /obj/item/clothing/suit/space/eva name = "EVA suit" @@ -149,12 +161,13 @@ desc = "A lightweight space suit with the basic ability to protect the wearer from the vacuum of space during emergencies." armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20) species_restricted = list("exclude", "Diona", "Wryn") - species_fit = list("Vox") + species_fit = list("Vox", "Vulpkanin") sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/suit.dmi' + "Vox" = 'icons/mob/species/vox/suit.dmi', + "Vulpkanin" = 'icons/mob/species/vulpkanin/suit.dmi' ) sprite_sheets_obj = list( - "Vox" = 'icons/obj/clothing/species/vox/suits.dmi', + "Vox" = 'icons/obj/clothing/species/vox/suits.dmi' ) /obj/item/clothing/head/helmet/space/eva @@ -166,9 +179,10 @@ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 20) flash_protect = 0 species_restricted = list("exclude", "Diona", "Wryn") - species_fit = list("Vox") + species_fit = list("Vox", "Vulpkanin") sprite_sheets = list( - "Vox" = 'icons/mob/species/vox/helmet.dmi' + "Vox" = 'icons/mob/species/vox/helmet.dmi', + "Vulpkanin" = 'icons/mob/species/vulpkanin/helmet.dmi' ) sprite_sheets_obj = list( "Vox" = 'icons/obj/clothing/species/vox/hats.dmi' diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index d0599fa7ebc..2a77dcd8965 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -17,7 +17,19 @@ if(turfs.len) //Pick a turf to spawn at if we can var/turf/T = pick(turfs) - new/obj/effect/spacevine_controller(T) //spawn a controller at turf + var/obj/effect/spacevine_controller/SC = new /obj/effect/spacevine_controller(T, , rand(30,70),rand(5,2)) //spawn a controller at turf + + // Make the event start fun - give the vine a random hostile mutation + if(SC.vines.len) + SV = SC.vines[1] + var/list/mutations = SC.mutations_list.Copy() + while(mutations.len) + var/datum/spacevine_mutation/SM = pick_n_take(mutations) + if(SM.quality == NEGATIVE && !SM.nofun) + SM.add_mutation_to_vinepiece(SV) + break + mutations.Cut() + mutations = null /datum/spacevine_mutation @@ -25,11 +37,22 @@ var/severity = 1 var/hue var/quality + // For stuff that isn't fun as a random-event vine + var/nofun = FALSE /datum/spacevine_mutation/proc/add_mutation_to_vinepiece(obj/effect/spacevine/holder) holder.mutations |= src holder.color = hue +/datum/spacevine_mutation/proc/remove_mutation_from_vinepiece(obj/effect/spacevine/holder) + holder.mutations -= src + var/datum/spacevine_mutation/oldmutation + if(holder.mutations.len) + oldmutation = pick(holder.mutations) + holder.color = oldmutation.hue + else + holder.color = "" + /datum/spacevine_mutation/proc/process_mutation(obj/effect/spacevine/holder) return @@ -136,6 +159,11 @@ /datum/spacevine_mutation/space_covering/on_grow(obj/effect/spacevine/holder) process_mutation(holder) +/datum/spacevine_mutation/space_covering/on_spread(obj/effect/spacevine/holder, turf/target) + if(target.type == /turf/space && !locate(/obj/effect/spacevine) in target) + holder.master.spawn_spacevine_piece(target, holder) + . = TRUE + /datum/spacevine_mutation/space_covering/process_mutation(obj/effect/spacevine/holder) var/turf/T = get_turf(holder) if(is_type_in_typecache(T, coverable_turfs)) @@ -155,7 +183,12 @@ /datum/spacevine_mutation/bluespace/on_spread(obj/effect/spacevine/holder, turf/target) if(holder.energy > 1 && !locate(/obj/effect/spacevine) in target) + // Lose bluespace upon piercing a single tile, and drop it from our own mutations too + // Representing a loss in "high potential" + // also conveniently prevents this from spreading too crazily + remove_mutation_from_vinepiece(holder) holder.master.spawn_spacevine_piece(target, holder) + playsound(holder, 'sound/misc/interference.ogg', 50, 1) . = TRUE /datum/spacevine_mutation/light @@ -190,6 +223,8 @@ hue = "#ff0000" quality = NEGATIVE severity = 2 + // kaboom events aren't fun + nofun = TRUE /datum/spacevine_mutation/explosive/on_explosion(explosion_severity, obj/effect/spacevine/holder) if(explosion_severity < 3) @@ -234,6 +269,15 @@ quality = NEGATIVE /datum/spacevine_mutation/aggressive_spread/on_spread(obj/effect/spacevine/holder, turf/target) + if(istype(target, /turf/simulated/wall/r_wall)) + // Too tough to pierce - should lead to interesting spread patterns + return + // Bust through windows or other stuff blocking the way + if(!target.Enter(holder)) + for(var/atom/movable/AM in target) + if(istype(AM, /obj/effect/spacevine) || !AM.density) + continue + AM.ex_act(severity) target.ex_act(severity) // vine immunity handled at /mob/ex_act . = TRUE @@ -406,8 +450,8 @@ if(!master.vines.len) var/obj/item/seeds/kudzu/KZ = new(loc) KZ.mutations |= mutations - KZ.set_potency(master.mutativeness * 10) - KZ.set_production((master.spread_cap / initial(master.spread_cap)) * 5) + KZ.set_potency(10 ** sqrt(master.mutativeness)) + KZ.set_production(10 - (master.spread_cap / 10)) qdel(master) master = null mutations.Cut() @@ -499,11 +543,19 @@ spawn_spacevine_piece(loc, , muts) processing_objects.Add(src) init_subtypes(/datum/spacevine_mutation/, mutations_list) - if(potency != null) - mutativeness = potency / 10 + if(potency != null && potency > 0) + // 1 mutativeness at 10 potency + // 4 mutativeness at 100 potency + mutativeness = log(10, potency) ** 2 if(production != null) - spread_cap /= production / 5 - spread_multiplier *= production / 5 + // 1 production is crazy powerful + var/spread_value = max(10 - production, 1) + // 40 at 6 production + // 90 at 1 production + spread_cap = spread_value * 10 + // 6 vines/spread at 6 production + // ~2.5 vines/spread at 1 production + spread_multiplier /= spread_value / 5 ..() @@ -618,7 +670,8 @@ for(var/datum/spacevine_mutation/SM in mutations) spread_success |= SM.on_spread(src, stepturf) // If this returns 1, spreading succeeded if(!locate(/obj/effect/spacevine, stepturf)) - if(stepturf.Enter(src)) + // snowflake for space turf, but space turf is super common and a big deal + if(!istype(stepturf, /turf/space) && stepturf.Enter(src)) if(master) master.spawn_spacevine_piece(stepturf, src) spread_success = TRUE diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 4c120db79e0..26d22bc0610 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -11,54 +11,57 @@ Gunshots/explosions/opening doors/less rare audio (done) */ -/mob/living/carbon/ +#define SCREWYHUD_NONE 0 +#define SCREWYHUD_CRIT 1 +#define SCREWYHUD_DEAD 2 +#define SCREWYHUD_HEALTHY 3 + +/mob/living/carbon var/image/halimage var/image/halbody var/obj/halitem - var/hal_screwyhud = 0 //1 - critical, 2 - dead, 3 - oxygen indicator, 4 - toxin indicator + var/hal_screwyhud = SCREWYHUD_NONE var/handling_hal = 0 - var/hal_crit = 0 /mob/living/carbon/proc/handle_hallucinations() if(handling_hal) return //Least obvious - var/list/minor = list("sounds"=20,"bolts_minor"=10,"whispers"=15,"message"=5) + var/list/minor = list("sounds"=25,"bolts_minor"=5,"whispers"=15,"message"=10,"hudscrew"=15) //Something's wrong here - var/list/medium = list("hudscrew"=15,"items"=15,"dangerflash"=15,"bolts"=10,"flood"=10,"husks"=10,"battle"=10) - //AAAAH - var/list/major = list("fake"=10,"death"=5,"xeno"=10,"singulo"=10,"delusion"=10) - - var/grade = 0 - var/current = list() - var/trip_length = 0 + var/list/medium = list("fake_alert"=15,"items"=10,"items_other"=10,"dangerflash"=10,"bolts"=5,"flood"=5,"husks"=10,"battle"=15,"self_delusion"=10) + //AAAAHg + var/list/major = list("fake"=20,"death"=10,"xeno"=10,"singulo"=10,"borer"=10,"delusion"=20,"koolaid"=10) handling_hal = 1 while(hallucination > 20) - sleep(rand(200,500)/(hallucination/25)) - trip_length += 1 - if(prob(min(20,trip_length*2))) - grade = min(3,grade+1) + sleep(rand(200, 500) / (hallucination / 25)) if(prob(20)) continue - current = list() - for(var/a in minor) - current[a] = minor[a] * (grade==0?2:1) - for(var/b in medium) - current[b] = medium[b] * (grade==1?2:1) - for(var/c in major) - current[c] = major[c] * (grade==2?2:1) + var/list/current = list() + switch(rand(100)) + if(1 to 50) + current = minor + if(51 to 85) + current = medium + if(86 to 100) + current = major var/halpick = pickweight(current) hallucinate(halpick) handling_hal = 0 + /obj/effect/hallucination invisibility = INVISIBILITY_OBSERVER var/mob/living/carbon/target = null +/obj/effect/hallucination/proc/wake_and_restore() + target.hal_screwyhud = SCREWYHUD_NONE + target.SetSleeping(0) + /obj/effect/hallucination/simple var/image_icon = 'icons/mob/alien.dmi' var/image_state = "alienh_pounce" @@ -69,28 +72,31 @@ Gunshots/explosions/opening doors/less rare audio (done) var/image_layer = MOB_LAYER var/active = 1 //qdelery -/obj/effect/hallucination/simple/New(loc,var/mob/living/carbon/T) +/obj/effect/hallucination/simple/New(loc, mob/living/carbon/T) + ..() target = T current_image = GetImage() - if(target.client) target.client.images |= current_image - return + if(target.client) + target.client.images |= current_image /obj/effect/hallucination/simple/proc/GetImage() - var/image/I = image(image_icon,loc,image_state,image_layer,dir=src.dir) + var/image/I = image(image_icon, src, image_state, image_layer, dir = dir) I.pixel_x = px I.pixel_y = py if(col_mod) I.color = col_mod return I -/obj/effect/hallucination/simple/proc/Show(var/update=1) +/obj/effect/hallucination/simple/proc/Show(update = 1) if(active) - if(target.client) target.client.images.Remove(current_image) + if(target.client) + target.client.images.Remove(current_image) if(update) current_image = GetImage() - if(target.client) target.client.images |= current_image + if(target.client) + target.client.images |= current_image -/obj/effect/hallucination/simple/update_icon(var/new_state,var/new_icon,var/new_px=0,var/new_py=0) +/obj/effect/hallucination/simple/update_icon(new_state, new_icon, new_px = 0, new_py = 0) image_state = new_state if(new_icon) image_icon = new_icon @@ -105,15 +111,16 @@ Gunshots/explosions/opening doors/less rare audio (done) Show() /obj/effect/hallucination/simple/Destroy() - if(target.client) target.client.images.Remove(current_image) + if(target.client) + target.client.images.Remove(current_image) active = 0 return ..() -#define FAKE_FLOOD_EXPAND_TIME 30 -#define FAKE_FLOOD_MAX_RADIUS 7 +#define FAKE_FLOOD_EXPAND_TIME 20 +#define FAKE_FLOOD_MAX_RADIUS 10 /obj/effect/hallucination/fake_flood - //Plasma/N2O starts flooding from the nearby vent + //Plasma starts flooding from the nearby vent var/list/flood_images = list() var/list/turf/flood_turfs = list() var/image_icon = 'icons/effects/tile_effects.dmi' @@ -121,17 +128,17 @@ Gunshots/explosions/opening doors/less rare audio (done) var/radius = 0 var/next_expand = 0 -/obj/effect/hallucination/fake_flood/New(loc,var/mob/living/carbon/T) +/obj/effect/hallucination/fake_flood/New(loc, mob/living/carbon/T) ..() target = T for(var/obj/machinery/atmospherics/unary/vent_pump/U in orange(7,target)) if(!U.welded) src.loc = U.loc break - image_state = pick("plasma","sleeping_agent") flood_images += image(image_icon,src,image_state,MOB_LAYER) flood_turfs += get_turf(src.loc) - if(target.client) target.client.images |= flood_images + if(target.client) + target.client.images |= flood_images next_expand = world.time + FAKE_FLOOD_EXPAND_TIME processing_objects += src @@ -141,26 +148,30 @@ Gunshots/explosions/opening doors/less rare audio (done) if(radius > FAKE_FLOOD_MAX_RADIUS) qdel(src) Expand() + if((get_turf(target) in flood_turfs) && !target.internal) + target.hallucinate("fake_alert", "tox_in_air") next_expand = world.time + FAKE_FLOOD_EXPAND_TIME - return /obj/effect/hallucination/fake_flood/proc/Expand() - if(!flood_turfs) //for qdel - return - for(var/turf/T in circlerangeturfs(loc,radius)) - if((T in flood_turfs)|| T.blocks_air) - continue - flood_images += image(image_icon,T,image_state,MOB_LAYER) - flood_turfs += T - if(target.client) target.client.images |= flood_images - return + for(var/turf/FT in flood_turfs) + for(var/dir in cardinal) + var/turf/T = get_step(FT, dir) + if((T in flood_turfs) || !FT.CanAtmosPass(T)) + continue + flood_images += image(image_icon,T,image_state,MOB_LAYER) + flood_turfs += T + if(target.client) + target.client.images |= flood_images /obj/effect/hallucination/fake_flood/Destroy() processing_objects -= src qdel(flood_turfs) - if(target.client) target.client.images.Remove(flood_images) + flood_turfs = list() + if(target.client) + target.client.images.Remove(flood_images) target = null qdel(flood_images) + flood_images = list() return ..() /obj/effect/hallucination/simple/xeno @@ -170,15 +181,15 @@ Gunshots/explosions/opening doors/less rare audio (done) /obj/effect/hallucination/simple/xeno/New(loc,var/mob/living/carbon/T) ..() name = "alien hunter ([rand(1, 1000)])" - return /obj/effect/hallucination/simple/xeno/throw_at(atom/target, range, speed) // TODO : Make diagonal trhow into proc/property - if(!target || !src || (flags & NODROP)) return 0 + if(!target || !src || (flags & NODROP)) + return 0 - src.throwing = 1 + throwing = 1 - var/dist_x = abs(target.x - src.x) - var/dist_y = abs(target.y - src.y) + var/dist_x = abs(target.x - x) + var/dist_y = abs(target.y - y) var/dist_travelled = 0 var/dist_since_sleep = 0 @@ -190,15 +201,16 @@ Gunshots/explosions/opening doors/less rare audio (done) tdist_y = dist_x; var/error = tdist_x/2 - tdist_y - while(target && (((((dist_x > dist_y) && ((src.x < target.x) || (src.x > target.x))) || ((dist_x <= dist_y) && ((src.y < target.y) || (src.y > target.y))) || (src.x > target.x)) && dist_travelled < range) || !has_gravity(src))) + while(target && (((((dist_x > dist_y) && ((x < target.x) || (x > target.x))) || ((dist_x <= dist_y) && ((y < target.y) || (y > target.y))) || (x > target.x)) && dist_travelled < range) || !has_gravity(src))) + if(!throwing) + break + if(!istype(loc, /turf)) + break - if(!src.throwing) break - if(!istype(src.loc, /turf)) break - - var/atom/step = get_step(src, get_dir(src,target)) + var/atom/step = get_step(src, get_dir(src, target)) if(!step) break - src.Move(step, get_dir(src, step)) + Move(step, get_dir(src, step)) hit_check() error += (error < 0) ? tdist_x : -tdist_y; dist_travelled++ @@ -208,8 +220,8 @@ Gunshots/explosions/opening doors/less rare audio (done) sleep(1) - src.throwing = 0 - src.throw_impact(get_turf(src)) + throwing = 0 + throw_impact(get_turf(src)) return 1 @@ -224,49 +236,155 @@ Gunshots/explosions/opening doors/less rare audio (done) var/obj/machinery/atmospherics/unary/vent_pump/pump = null var/obj/effect/hallucination/simple/xeno/xeno = null -/obj/effect/hallucination/xeno_attack/New(loc,var/mob/living/carbon/T) +/obj/effect/hallucination/xeno_attack/New(loc, mob/living/carbon/T) target = T for(var/obj/machinery/atmospherics/unary/vent_pump/U in orange(7,target)) if(!U.welded) pump = U break - if(!pump) return 0 + if(!pump) + return 0 xeno = new(pump.loc,target) sleep(10) - if(!xeno) return + if(!xeno) + return xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32) xeno.throw_at(target,7,1) sleep(10) - if(!xeno) return + if(!xeno) + return xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32) xeno.throw_at(pump,7,1) sleep(10) - if(!xeno) return + if(!xeno) + return var/xeno_name = xeno.name to_chat(target, "[xeno_name] begins climbing into the ventilation system...") sleep(10) - if(!xeno) return + if(!xeno) + return qdel(xeno) to_chat(target, "[xeno_name] scrambles into the ventilation ducts!") qdel(src) +/obj/effect/hallucination/simple/clown + image_icon = 'icons/mob/animal.dmi' + image_state = "clown" + +/obj/effect/hallucination/simple/clown/New(loc, mob/living/carbon/T, duration) + ..(loc, T) + name = pick(clown_names) + sleep(duration) + qdel(src) + +/obj/effect/hallucination/simple/clown/scary + image_state = "scary_clown" + +/obj/effect/hallucination/simple/borer + image_icon = 'icons/mob/animal.dmi' + image_state = "brainslug" + +/obj/effect/hallucination/borer + //A borer paralyzes you and crawls in your ear + var/obj/machinery/atmospherics/unary/vent_pump/pump = null + var/obj/effect/hallucination/simple/borer/borer = null + +/obj/effect/hallucination/borer/New(loc, mob/living/carbon/T) + ..() + target = T + for(var/obj/machinery/atmospherics/unary/vent_pump/U in orange(7, target)) + if(!U.welded) + pump = U + break + if(pump) + borer = new(pump.loc,target) + for(var/i=0, i<11, i++) + walk_to(borer, get_step(borer, get_cardinal_dir(borer, T))) + if(borer.Adjacent(T)) + to_chat(T, "You feel a creeping, horrible sense of dread come over you, freezing your limbs and setting your heart racing.") + T.Stun(4) + sleep(50) + qdel(borer) + sleep(rand(60, 90)) + to_chat(T, "Primary [rand(1000,9999)] states: [pick("Hello","Hi","You're my slave now!","Don't try to get rid of me...")]") + break + sleep(4) + if(!qdeleted(borer)) + qdel(borer) + qdel(src) + +/obj/effect/hallucination/simple/bubblegum + name = "Bubblegum" + image_icon = 'icons/mob/lavaland/96x96megafauna.dmi' + image_state = "bubblegum" + px = -32 + +/obj/effect/hallucination/oh_yeah + var/turf/simulated/wall/wall + var/obj/effect/hallucination/simple/bubblegum/bubblegum = null + var/image/fakebroken + var/image/fakerune + +/obj/effect/hallucination/oh_yeah/New(loc, mob/living/carbon/T) + ..() + target = T + for(var/turf/simulated/wall/W in range(7,target)) + wall = W + break + if(wall) + fakebroken = image('icons/turf/floors.dmi', wall, "plating", layer = TURF_LAYER) + var/turf/landing = get_turf(target) + var/turf/landing_image_turf = get_step(landing, SOUTHWEST) //the icon is 3x3 + fakerune = image('icons/effects/96x96.dmi', landing_image_turf, "landing", layer = ABOVE_OPEN_TURF_LAYER) + fakebroken.override = TRUE + if(target.client) + target.client.images |= fakebroken + target.client.images |= fakerune + target.playsound_local(wall,'sound/effects/meteorimpact.ogg', 150, 1) + bubblegum = new(wall, target) + sleep(10) //ominous wait + var/charged = FALSE //only get hit once + while(get_turf(bubblegum) != landing && target) + bubblegum.forceMove(get_step_towards(bubblegum, landing)) + bubblegum.setDir(get_dir(bubblegum, landing)) + target.playsound_local(get_turf(bubblegum), 'sound/effects/meteorimpact.ogg', 150, 1) + shake_camera(target, 2, 1) + if(bubblegum.Adjacent(target) && !charged) + charged = TRUE + target.Weaken(4) + target.staminaloss += 40 + step_away(target, bubblegum) + shake_camera(target, 4, 3) + target.visible_message("[target] jumps backwards, falling on the ground!","[bubblegum] slams into you!") + sleep(2) + sleep(30) + qdel(bubblegum) + qdel(src) + +/obj/effect/hallucination/oh_yeah/Destroy() + if(target.client) + target.client.images.Remove(fakebroken) + target.client.images.Remove(fakerune) + return ..() + /obj/effect/hallucination/singularity_scare //Singularity moving towards you. //todo Hide where it moved with fake space images var/obj/effect/hallucination/simple/singularity/s = null -/obj/effect/hallucination/singularity_scare/New(loc,var/mob/living/carbon/T) +/obj/effect/hallucination/singularity_scare/New(loc, mob/living/carbon/T) target = T - var/turf/start = T.loc - var/screen_border = pick(SOUTH,EAST,WEST,NORTH) + var/turf/start = get_turf(T) + var/screen_border = pick(cardinal) for(var/i = 0,i<11,i++) - start = get_step(start,screen_border) + start = get_step(start, screen_border) s = new(start,target) for(var/i = 0,i<11,i++) sleep(5) - s.loc = get_step(get_turf(s),get_dir(s,target)) + s.loc = get_step(get_turf(s), get_dir(s, target)) s.Show() s.Eat() + addtimer(src, "wake_and_restore", rand(50, 100)) qdel(s) /obj/effect/hallucination/simple/singularity @@ -277,50 +395,98 @@ Gunshots/explosions/opening doors/less rare audio (done) py = -96 /obj/effect/hallucination/simple/singularity/proc/Eat(atom/OldLoc, Dir) - var/target_dist = get_dist(src,target) - if(target_dist<=3) //"Eaten" - target.Sleeping(20) - target.hal_crit = 1 - target.hal_screwyhud = 1 - spawn(rand(50,100)) - target.SetSleeping(0) - target.hal_crit = 0 - target.hal_screwyhud = 0 + var/target_dist = get_dist(src, target) + if(target_dist <= 3) //"Eaten" + target.hal_screwyhud = SCREWYHUD_CRIT + target.SetSleeping(8, no_alert = TRUE) /obj/effect/hallucination/battle -/obj/effect/hallucination/battle/New(loc,var/mob/living/carbon/T) +/obj/effect/hallucination/battle/New(loc, mob/living/carbon/T) target = T var/hits = rand(3,6) switch(rand(1,5)) if(1) //Laser fight for(var/i=0,i...wabbajack...wabbajack...") + target.playsound_local(target,'sound/magic/Staff_Change.ogg', 50, 1, -1) + delusion = A + target.client.images |= A + sleep(duration) qdel(src) -/obj/effect/hallucination/fakeattacker/New(loc,var/mob/living/carbon/T) +/obj/effect/hallucination/self_delusion/Destroy() + if(target.client) + target.client.images.Remove(delusion) + return ..() + +/obj/effect/hallucination/fakeattacker/New(loc, mob/living/carbon/T) + ..() target = T var/mob/living/carbon/human/clone = null var/clone_weapon = null @@ -417,25 +629,25 @@ Gunshots/explosions/opening doors/less rare audio (done) var/health = 100 -/obj/effect/fake_attacker/attackby(var/obj/item/weapon/P as obj, mob/living/user as mob, params) +/obj/effect/fake_attacker/attackby(obj/item/weapon/P, mob/living/user, params) step_away(src,my_target,2) user.changeNext_move(CLICK_CD_MELEE) user.do_attack_animation(src) - my_target << sound(pick('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg')) + my_target.playsound_local(src, P.hitsound, 1) my_target.visible_message("[my_target] flails around wildly.", \ "[my_target] has attacked [src]!") - src.health -= P.force + health -= P.force return -/obj/effect/fake_attacker/Crossed(var/mob/M, somenumber) +/obj/effect/fake_attacker/Crossed(mob/M, somenumber) if(M == my_target) step_away(src,my_target,2) if(prob(30)) for(var/mob/O in oviewers(world.view , my_target)) to_chat(O, "[my_target] stumbles around.") -/obj/effect/fake_attacker/New(loc,var/mob/living/carbon/T) +/obj/effect/fake_attacker/New(loc, mob/living/carbon/T) ..() my_target = T spawn(300) @@ -447,25 +659,25 @@ Gunshots/explosions/opening doors/less rare audio (done) /obj/effect/fake_attacker/proc/updateimage() // qdel(src.currentimage) - if(src.dir == NORTH) + if(dir == NORTH) qdel(src.currentimage) - src.currentimage = new /image(up,src) - else if(src.dir == SOUTH) + currentimage = new /image(up, src) + else if(dir == SOUTH) qdel(src.currentimage) - src.currentimage = new /image(down,src) - else if(src.dir == EAST) + currentimage = new /image(down, src) + else if(dir == EAST) qdel(src.currentimage) - src.currentimage = new /image(right,src) - else if(src.dir == WEST) + currentimage = new /image(right, src) + else if(dir == WEST) qdel(src.currentimage) - src.currentimage = new /image(left,src) + currentimage = new /image(left, src) my_target << currentimage /obj/effect/fake_attacker/proc/attack_loop() while(1) sleep(rand(5,10)) - if(src.health < 0) + if(src.health < 0 || my_target.stat) collapse() continue if(get_dist(src,my_target) > 1) @@ -474,9 +686,8 @@ Gunshots/explosions/opening doors/less rare audio (done) updateimage() else if(prob(15)) - src.do_attack_animation(my_target) if(weapon_name) - my_target << sound(pick('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg')) + my_target.playsound_local(my_target, weap.hitsound, 1) my_target.show_message("[src.name] has attacked [my_target] with [weapon_name]!", 1) my_target.staminaloss += 30 if(prob(20)) @@ -485,7 +696,7 @@ Gunshots/explosions/opening doors/less rare audio (done) if(!locate(/obj/effect/overlay) in my_target.loc) fake_blood(my_target) else - my_target << sound(pick('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg')) + my_target.playsound_local(my_target, pick('sound/weapons/punch1.ogg','sound/weapons/punch2.ogg','sound/weapons/punch3.ogg','sound/weapons/punch4.ogg'), 25, 1, -1) my_target.show_message("[src.name] has punched [my_target]!", 1) my_target.staminaloss += 30 if(prob(33)) @@ -498,8 +709,9 @@ Gunshots/explosions/opening doors/less rare audio (done) /obj/effect/fake_attacker/proc/collapse() collapse = 1 updateimage() + qdel(src) -/obj/effect/fake_attacker/proc/fake_blood(var/mob/target) +/obj/effect/fake_attacker/proc/fake_blood(mob/target) var/obj/effect/overlay/O = new/obj/effect/overlay(target.loc) O.name = "blood" var/image/I = image('icons/effects/blood.dmi',O,"floor[rand(1,7)]",O.dir,1) @@ -527,7 +739,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite /obj/effect/hallucination/bolts var/list/doors = list() -/obj/effect/hallucination/bolts/New(loc,var/mob/living/carbon/T,var/door_number=-1) //-1 for sever 1-2 for subtle +/obj/effect/hallucination/bolts/New(loc, mob/living/carbon/T, door_number = -1) //-1 for sever 1-2 for subtle target = T var/image/I = null var/count = 0 @@ -535,23 +747,26 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite if(count>door_number && door_number>0) break count++ - I = image(A.icon,A,"door_locked",layer=A.layer+0.1) + I = image(A.icon, get_turf(A), "door_locked", layer=A.layer+0.1) doors += I if(target.client) target.client.images |= I - sleep(2) + target.playsound_local(get_turf(A), 'sound/machines/BoltsDown.ogg',30,0,3) + sleep(rand(6,12)) sleep(100) for(var/image/B in doors) if(target.client) target.client.images.Remove(B) + target.playsound_local(get_turf(B), 'sound/machines/BoltsUp.ogg',30,0,3) + sleep(rand(6,12)) qdel(src) /obj/effect/hallucination/whispers /obj/effect/hallucination/whispers/New(loc,var/mob/living/carbon/T) target = T - var/speak_messages = list("I'm watching you...","[target.name]!","Go away!","Kchck-Chkck? Kchchck!","Did you hear that?","What did you do ?","Why?","Give me that!","Honk!","HELP!!") - var/radio_messages = list("Xenos!","Singularity loose!","They are arming the nuke!","They butchered Ian!","H-help!","[pick(teleportlocs)]!!","Where's [target.name]?","Call the shuttle!") + var/speak_messages = list("I'm watching you...","[target.name]!","Get out!","Kchck-Chkck? Kchchck!","Did you hear that?","What did you do ?","Why?","Give me that!","Honk!","HELP!!", "EI NATH!!", "RUN!!", "Kill me!","O bidai nabora se'sma!") + var/radio_messages = list("Xenos!","Singularity loose!","Comms down!","They are arming the nuke!","They butchered Ian!","H-help!","[pick("Cult", "Wizard", "Ling", "Ops", "Revenant", "Murderer", "Harm", "I hear flashing", "Help")] in [pick(teleportlocs)][prob(50)?"!":"!!"]","Where's [target.name]?","Call the shuttle!","AI rogue!!") var/list/mob/living/carbon/people = list() var/list/mob/living/carbon/person = null @@ -565,7 +780,12 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite person = H people += H if(person) //Basic talk + var/image/speech_overlay = image('icons/mob/talk.dmi', person, "h0", layer = ABOVE_MOB_LAYER) target.hear_say(pick(speak_messages),language = pick(person.languages),speaker = person) + if(target.client) + target.client.images |= speech_overlay + sleep(30) + target.client.images.Remove(speech_overlay) else // Radio talk var/list/humans = list() for(var/mob/living/carbon/human/H in living_mob_list) @@ -578,76 +798,93 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite /obj/effect/hallucination/message/New(loc,var/mob/living/carbon/T) target = T - var/chosen = pick("The light burns you!", \ - "You don't feel like yourself.", \ - "Unknown has punched [target]!", \ - "You hear something squeezing through the ducts...", \ - "You hear a distant scream.", \ - "You feel invincible, nothing can hurt you!", \ - "[target] sneezes.", \ - "You feel faint.", \ - "You hear a strange, alien voice in your head...[pick("Hiss","Ssss")]", \ + var/chosen = pick("The light burns you!", + "You don't feel like yourself.", + "Unknown has punched [target]!", + "You hear something squeezing through the ducts...", + "You hear a distant scream.", + "You feel invincible, nothing can hurt you!", + "You feel a tiny prick!", + "[target] sneezes.", + "You feel faint.", + "You hear a strange, alien voice in your head...[pick("Hiss","Ssss")]", "You can see...everything!") to_chat(target, chosen) qdel(src) -/mob/living/carbon/proc/hallucinate(var/hal_type) // Todo -> proc / defines +/mob/living/carbon/proc/hallucinate(hal_type, specific) // specific is used to specify a particular hallucination switch(hal_type) if("xeno") - new /obj/effect/hallucination/xeno_attack(src.loc,src) + new /obj/effect/hallucination/xeno_attack(loc, src) + if("borer") + new /obj/effect/hallucination/borer(loc, src) if("singulo") - new /obj/effect/hallucination/singularity_scare(src.loc,src) + new /obj/effect/hallucination/singularity_scare(loc, src) + if("koolaid") + new /obj/effect/hallucination/oh_yeah(loc, src) if("battle") - new /obj/effect/hallucination/battle(src.loc,src) + new /obj/effect/hallucination/battle(loc, src) if("flood") - new /obj/effect/hallucination/fake_flood(src.loc,src) + new /obj/effect/hallucination/fake_flood(loc, src) if("delusion") - new /obj/effect/hallucination/delusion(src.loc,src) + new /obj/effect/hallucination/delusion(loc, src) + if("self_delusion") + new /obj/effect/hallucination/self_delusion(loc, src) if("fake") - new /obj/effect/hallucination/fakeattacker(src.loc,src) + new /obj/effect/hallucination/fakeattacker(loc, src) if("bolts") - new /obj/effect/hallucination/bolts(src.loc,src) + new /obj/effect/hallucination/bolts(loc, src) if("bolts_minor") - new /obj/effect/hallucination/bolts(src.loc,src,rand(1,2)) + new /obj/effect/hallucination/bolts(loc,src, rand(1,2)) if("whispers") - new /obj/effect/hallucination/whispers(src.loc,src) + new /obj/effect/hallucination/whispers(loc, src) if("message") - new /obj/effect/hallucination/message(src.loc,src) + new /obj/effect/hallucination/message(loc, src) + if("items_other") + new /obj/effect/hallucination/items_other(src.loc,src) if("sounds") //Strange audio // to_chat(src, "Strange Audio") switch(rand(1,18)) if(1) - src << 'sound/machines/airlock.ogg' + playsound_local(null,'sound/machines/airlock.ogg', 15, 1) if(2) if(prob(50)) - src << 'sound/effects/Explosion1.ogg' + playsound_local(null,'sound/effects/Explosion1.ogg', 50, 1) else - src << 'sound/effects/Explosion2.ogg' + playsound_local(null, 'sound/effects/Explosion2.ogg', 50, 1) if(3) - src << 'sound/effects/explosionfar.ogg' + playsound_local(null, 'sound/effects/explosionfar.ogg', 50, 1) if(4) - src << 'sound/effects/Glassbr1.ogg' + playsound_local(null, pick('sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg'), 50, 1) if(5) - src << 'sound/effects/Glassbr2.ogg' + playsound_local(null, 'sound/weapons/ring.ogg', 35) + sleep(15) + playsound_local(null, 'sound/weapons/ring.ogg', 35) + sleep(15) + playsound_local(null, 'sound/weapons/ring.ogg', 35) if(6) - src << 'sound/effects/Glassbr3.ogg' + playsound_local(null, 'sound/magic/Summon_guns.ogg', 50, 1) if(7) - src << 'sound/machines/twobeep.ogg' + playsound_local(null, 'sound/machines/Alarm.ogg', 100, 0) if(8) - src << 'sound/machines/windowdoor.ogg' + playsound_local(null, 'sound/voice/bfreeze.ogg', 35, 0) if(9) //To make it more realistic, I added two gunshots (enough to kill) - src << 'sound/weapons/Gunshot.ogg' + playsound_local(null, 'sound/weapons/Gunshot.ogg', 25, 1) spawn(rand(10,30)) - src << 'sound/weapons/Gunshot.ogg' + playsound_local(null, 'sound/weapons/Gunshot.ogg', 25, 1) + sleep(rand(5,10)) + playsound_local(null, sound(get_sfx("bodyfall"), 25), 25, 1) if(10) - src << 'sound/weapons/smash.ogg' + playsound_local(null, 'sound/effects/pray_chaplain.ogg', 50) if(11) //Same as above, but with tasers. - src << 'sound/weapons/Taser.ogg' + playsound_local(null, 'sound/weapons/Taser.ogg', 25, 1) spawn(rand(10,30)) - src << 'sound/weapons/Taser.ogg' + playsound_local(null, 'sound/weapons/Taser.ogg', 25, 1) + sleep(rand(5,10)) + playsound_local(null, sound(get_sfx("bodyfall"), 25), 25, 1) //Rare audio if(12) //These sounds are (mostly) taken from Hidden: Source @@ -656,40 +893,112 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite 'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\ 'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\ 'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg') - src << pick(creepyasssounds) + playsound_local(null, pick(creepyasssounds), 50, 1) if(13) to_chat(src, "You feel a tiny prick!") if(14) to_chat(src, "

Priority Announcement

") to_chat(src, "

The Emergency Shuttle has docked with the station. You have 3 minutes to board the Emergency Shuttle.

") - src << sound('sound/AI/shuttledock.ogg') + playsound_local(null, 'sound/AI/shuttledock.ogg', 100) if(15) - src << 'sound/items/Welder.ogg' + playsound_local(null, 'sound/items/Welder.ogg', 15, 1) + sleep(105) + playsound_local(null, 'sound/items/Welder2.ogg', 15, 1) + sleep(15) + playsound_local(null, 'sound/items/Ratchet.ogg', 15, 1) if(16) - src << 'sound/items/Screwdriver.ogg' + playsound_local(null, 'sound/items/Screwdriver.ogg', 15, 1) + sleep(rand(10,30)) + for(var/i = rand(1,3), i>0, i--) + playsound_local(null, 'sound/weapons/empty.ogg', 15, 1) + sleep(rand(10,30)) + playsound_local(null, 'sound/machines/airlockforced.ogg', 15, 1) if(17) - src << 'sound/weapons/saberon.ogg' + playsound_local(null, 'sound/weapons/saberon.ogg', 35, 1) if(18) - src << 'sound/weapons/saberoff.ogg' + to_chat(src, "

Biohazard Alert

") + to_chat(src, "

Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.

") + playsound_local(null, 'sound/AI/outbreak5.ogg') + if(19) //Tesla loose! + playsound_local(null, 'sound/magic/lightningbolt.ogg', 35, 1) + sleep(20) + playsound_local(null, 'sound/magic/lightningbolt.ogg', 65, 1) + sleep(20) + playsound_local(null, 'sound/magic/lightningbolt.ogg', 100, 1) + if(20) //AI is doomsdaying! + to_chat(src, "

Anomaly Alert

") + to_chat(src, "

Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.

") + playsound_local(null, 'sound/AI/aimalf.ogg') if("hudscrew") //Screwy HUD -// to_chat(src, "Screwy HUD") - hal_screwyhud = pick(1,2,3,3,4,4) - spawn(rand(100,250)) - hal_screwyhud = 0 + hal_screwyhud = pick(SCREWYHUD_NONE, SCREWYHUD_CRIT, SCREWYHUD_DEAD, SCREWYHUD_HEALTHY) + sleep(rand(100,250)) + hal_screwyhud = SCREWYHUD_NONE + if("fake_alert") + var/alert_type = pick("oxy","not_enough_tox","not_enough_co2","too_much_oxy","too_much_co2","tox_in_air","newlaw","nutrition","charge","weightless","fire","locked","hacked","temp","pressure") + if(specific) + alert_type = specific + switch(alert_type) + if("oxy") + throw_alert("oxy", /obj/screen/alert/oxy, override = TRUE) + if("not_enough_tox") + throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox, override = TRUE) + if("not_enough_co2") + throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2, override = TRUE) + if("too_much_oxy") + throw_alert("too_much_oxy", /obj/screen/alert/too_much_oxy, override = TRUE) + if("too_much_co2") + throw_alert("too_much_co2", /obj/screen/alert/too_much_co2, override = TRUE) + if("tox_in_air") + throw_alert("tox_in_air", /obj/screen/alert/tox_in_air, override = TRUE) + if("nutrition") + if(prob(50)) + throw_alert("nutrition", /obj/screen/alert/fat, override = TRUE) + else + throw_alert("nutrition", /obj/screen/alert/starving, override = TRUE) + if("weightless") + throw_alert("weightless", /obj/screen/alert/weightless, override = TRUE) + if("fire") + throw_alert("fire", /obj/screen/alert/fire, override = TRUE) + if("temp") + if(prob(50)) + throw_alert("temp", /obj/screen/alert/hot, 3, override = TRUE) + else + throw_alert("temp", /obj/screen/alert/cold, 3, override = TRUE) + if("pressure") + if(prob(50)) + throw_alert("pressure", /obj/screen/alert/highpressure, 2, override = TRUE) + else + throw_alert("pressure", /obj/screen/alert/lowpressure, 2, override = TRUE) + //BEEP BOOP I AM A ROBOT + if("newlaw") + throw_alert("newlaw", /obj/screen/alert/newlaw, override = TRUE) + if("locked") + throw_alert("locked", /obj/screen/alert/locked, override = TRUE) + if("hacked") + throw_alert("hacked", /obj/screen/alert/hacked, override = TRUE) + if("charge") + throw_alert("charge",/obj/screen/alert/emptycell, override = TRUE) + sleep(rand(100,200)) + clear_alert(alert_type, clear_override = TRUE) if("items") //Strange items // to_chat(src, "Traitor Items") if(!halitem) halitem = new var/list/slots_free = list(ui_lhand,ui_rhand) - if(l_hand) slots_free -= ui_lhand - if(r_hand) slots_free -= ui_rhand + if(l_hand) + slots_free -= ui_lhand + if(r_hand) + slots_free -= ui_rhand if(istype(src,/mob/living/carbon/human)) var/mob/living/carbon/human/H = src - if(!H.belt) slots_free += ui_belt - if(!H.l_store) slots_free += ui_storage1 - if(!H.r_store) slots_free += ui_storage2 + if(!H.belt) + slots_free += ui_belt + if(!H.l_store) + slots_free += ui_storage1 + if(!H.r_store) + slots_free += ui_storage2 if(slots_free.len) halitem.screen_loc = pick(slots_free) halitem.layer = 50 @@ -726,7 +1035,6 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite qdel(halitem) if("dangerflash") //Flashes of danger -// to_chat(src, "Danger Flash") if(!halimage) var/list/possible_points = list() for(var/turf/simulated/floor/F in view(src,world.view)) @@ -734,31 +1042,38 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite if(possible_points.len) var/turf/simulated/floor/target = pick(possible_points) - switch(rand(1,3)) + switch(rand(1,4)) if(1) -// to_chat(src, "Space") halimage = image('icons/turf/space.dmi',target,"[rand(1,25)]",TURF_LAYER) if(2) -// to_chat(src, "Fire") - halimage = image('icons/effects/fire.dmi',target,"1",TURF_LAYER) + halimage = image('icons/turf/floors/lava.dmi',target,"smooth",TURF_LAYER) if(3) -// to_chat(src, "C4") + halimage = image('icons/turf/floors/Chasms.dmi',target,"smooth",TURF_LAYER) + if(4) halimage = image('icons/obj/assemblies.dmi',target,"plastic-explosive2",OBJ_LAYER+0.01) - if(client) client.images += halimage - spawn(rand(10,50)) //Only seen for a brief moment. - if(client) client.images -= halimage - halimage = null + if(client) + client.images += halimage + sleep(rand(40,60)) //Only seen for a brief moment. + if(client) + client.images -= halimage + halimage = null if("death") - //Fake death - Sleeping(20) - hal_crit = 1 - hal_screwyhud = 1 - spawn(rand(50,100)) - SetSleeping(0) - hal_crit = 0 - hal_screwyhud = 0 + hal_screwyhud = SCREWYHUD_DEAD + SetSleeping(20, no_alert = TRUE) + if(prob(50)) + var/list/dead_people = list() + for(var/mob/dead/observer/G in player_list) + dead_people += G + var/mob/dead/observer/fakemob = pick(dead_people) + if(fakemob) + sleep(rand(30, 60)) + to_chat(src, "[fakemob.name](FOLLOW) [pick("complains", "moans", "whines", "laments", "blubbers", "salts")], \"[pick("rip","welcome [name]","you too?","is the AI malf?",\ + "i[prob(50)?" fucking":""] hate [pick("blood cult", "clock cult", "revenants", "abductors","double agents","viruses","badmins","you")]")]\"") + sleep(rand(50,70)) + hal_screwyhud = SCREWYHUD_NONE + SetSleeping(0) if("husks") if(!halbody) var/list/possible_points = list() @@ -768,17 +1083,19 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite var/turf/simulated/floor/target = pick(possible_points) switch(rand(1,4)) if(1) - var/image/body = image('icons/mob/human.dmi',target,"husk_s",TURF_LAYER) + var/image/body = image('icons/mob/human.dmi', target, "husk_s", TURF_LAYER) var/matrix/M = matrix() M.Turn(90) body.transform = M halbody = body if(2,3) - halbody = image('icons/mob/human.dmi',target,"husk_s",TURF_LAYER) + halbody = image('icons/mob/human.dmi', target, "husk_s", TURF_LAYER) if(4) - halbody = image('icons/mob/alien.dmi',target,"alienother",TURF_LAYER) + halbody = image('icons/mob/alien.dmi', target, "alienother", TURF_LAYER) - if(client) client.images += halbody - spawn(rand(50,80)) //Only seen for a brief moment. - if(client) client.images -= halbody + if(client) + client.images += halbody + spawn(rand(30,50)) //Only seen for a brief moment. + if(client) + client.images -= halbody halbody = null diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 4e0cf476879..54550a0f560 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -528,9 +528,9 @@ H.healths.icon_state = "health7" else switch(H.hal_screwyhud) - if(1) H.healths.icon_state = "health6" - if(2) H.healths.icon_state = "health7" - if(5) H.healths.icon_state = "health0" + if(SCREWYHUD_CRIT) H.healths.icon_state = "health6" + if(SCREWYHUD_DEAD) H.healths.icon_state = "health7" + if(SCREWYHUD_HEALTHY) H.healths.icon_state = "health0" else switch(100 - ((flags & NO_PAIN) ? 0 : H.traumatic_shock) - H.staminaloss) if(100 to INFINITY) H.healths.icon_state = "health0" diff --git a/code/modules/mob/living/carbon/human/status_procs.dm b/code/modules/mob/living/carbon/human/status_procs.dm index 5ca23f89f4f..5f74f202603 100644 --- a/code/modules/mob/living/carbon/human/status_procs.dm +++ b/code/modules/mob/living/carbon/human/status_procs.dm @@ -13,7 +13,7 @@ amount = amount * species.stun_mod ..() -/mob/living/carbon/human/SetSleeping(amount, updating = 1) +/mob/living/carbon/human/SetSleeping(amount, updating = 1, no_alert = FALSE) if(species) amount = amount * species.stun_mod ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index d24471dc7e2..61906d0c967 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -1202,7 +1202,7 @@ var/global/list/damage_icon_parts = list() var/icon/tail_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[tail]_s") if(species.bodyflags & HAS_SKIN_COLOR) tail_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) - if(tail_marking_icon) + if(tail_marking_icon && !tail_marking_style.tails_allowed) tail_s.Blend(tail_marking_icon, ICON_OVERLAY) if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. @@ -1270,7 +1270,7 @@ var/global/list/damage_icon_parts = list() var/icon/tailw_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[tail]w_s") if(species.bodyflags & HAS_SKIN_COLOR) tailw_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) - if(tail_marking_icon) + if(tail_marking_icon && !tail_marking_style.tails_allowed) tailw_s.Blend(tail_marking_icon, ICON_OVERLAY) if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 91661304144..da764cafda3 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -345,7 +345,7 @@ if(..()) handle_dreams() adjustStaminaLoss(-10) - if(prob(10) && health && !hal_crit) + if(prob(10) && health && hal_screwyhud != SCREWYHUD_CRIT) spawn(0) emote("snore") // Keep SSD people asleep diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index e95381d19cf..30fe030bdcb 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -354,19 +354,19 @@ // SLEEPING -/mob/living/Sleeping(amount, updating = 1) - SetSleeping(max(sleeping, amount), updating) +/mob/living/Sleeping(amount, updating = 1, no_alert = FALSE) + SetSleeping(max(sleeping, amount), updating, no_alert) -/mob/living/SetSleeping(amount, updating = 1) +/mob/living/SetSleeping(amount, updating = 1, no_alert = FALSE) sleeping = max(amount, 0) - update_sleeping_effects() + update_sleeping_effects(no_alert) if(updating) update_stat() update_canmove() -/mob/living/AdjustSleeping(amount, bound_lower = 0, bound_upper = INFINITY, updating = 1) +/mob/living/AdjustSleeping(amount, bound_lower = 0, bound_upper = INFINITY, updating = 1, no_alert = FALSE) var/new_value = directional_bounded_sum(sleeping, amount, bound_lower, bound_upper) - SetSleeping(new_value, updating) + SetSleeping(new_value, updating, no_alert) // SLOWED diff --git a/code/modules/mob/living/update_status.dm b/code/modules/mob/living/update_status.dm index 59b7077e79e..257a4bc87c1 100644 --- a/code/modules/mob/living/update_status.dm +++ b/code/modules/mob/living/update_status.dm @@ -30,9 +30,10 @@ else clear_fullscreen("nearsighted") -/mob/living/update_sleeping_effects() +/mob/living/update_sleeping_effects(no_alert = FALSE) if(sleeping) - throw_alert("asleep", /obj/screen/alert/asleep) + if(!no_alert) + throw_alert("asleep", /obj/screen/alert/asleep) else clear_alert("asleep") diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 8b8fafd32b7..52fdbdf0328 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -199,6 +199,10 @@ var/atom/O = mob.loc return O.relaymove(mob, direct) + if(istype(mob.get_active_hand(), /obj/item)) + var/obj/item/I = mob.get_active_hand() + I.moved(mob, n, direct) + if(!mob.Process_Spacemove(direct)) return 0 diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 849511a48e7..176ce72f005 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -114,7 +114,7 @@ By design, d1 is the smallest direction and d2 is the highest // /obj/structure/cable/attackby(obj/item/W, mob/user) - var/turf/T = src.loc + var/turf/T = get_turf(src) if(T.intact) return @@ -149,7 +149,7 @@ By design, d1 is the smallest direction and d2 is the highest if(c.d1 == 12 || c.d2 == 12) c.qdel()*/ ///// Z-Level Stuff - investigate_log("was cut by [key_name(usr, usr.client)] in [user.loc.loc]([T.x], [T.y], [T.z] - JMP)","wires") + investigate_log("was cut by [key_name(usr, usr.client)] in [get_area(user)]([T.x], [T.y], [T.z] - [ADMIN_JMP(T)])","wires") qdel(src) // qdel return @@ -162,6 +162,12 @@ By design, d1 is the smallest direction and d2 is the highest return coil.cable_join(src, user) + else if(istype(W, /obj/item/weapon/twohanded/rcl)) + var/obj/item/weapon/twohanded/rcl/R = W + if(R.loaded) + R.loaded.cable_join(src, user) + R.is_empty(user) + else if(istype(W, /obj/item/device/multitool)) if(powernet && (powernet.avail > 0)) // is it powered? @@ -197,12 +203,12 @@ By design, d1 is the smallest direction and d2 is the highest qdel(src) // qdel if(2.0) if(prob(50)) - new/obj/item/stack/cable_coil(src.loc, src.d1 ? 2 : 1, color) + new/obj/item/stack/cable_coil(get_turf(src), src.d1 ? 2 : 1, color) qdel(src) // qdel if(3.0) if(prob(25)) - new/obj/item/stack/cable_coil(src.loc, src.d1 ? 2 : 1, color) + new/obj/item/stack/cable_coil(get_turf(src), src.d1 ? 2 : 1, color) qdel(src) // qdel return @@ -505,7 +511,7 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list( // General procedures /////////////////////////////////// //you can use wires to heal robotics -/obj/item/stack/cable_coil/attack(mob/M as mob, mob/user as mob) +/obj/item/stack/cable_coil/attack(mob/M, mob/user) if(ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/organ/external/S = H.organs_by_name[user.zone_sel.selecting] @@ -613,11 +619,11 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list( return C // called when cable_coil is clicked on a turf/simulated/floor -/obj/item/stack/cable_coil/proc/place_turf(turf/T, mob/user) +/obj/item/stack/cable_coil/proc/place_turf(turf/T, mob/user, dirnew) if(!isturf(user.loc)) return - if(!T.can_have_cabling()) + if(!isturf(T) || T.intact || !T.can_have_cabling()) to_chat(user, "You can only lay cables on catwalks and plating!") return @@ -629,44 +635,46 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list( to_chat(user, "You can't lay cable at a place that far away!") return - else - var/dirn - + var/dirn = null + if(!dirnew) //If we weren't given a direction, come up with one! (Called as null from catwalk.dm and floor.dm) if(user.loc == T) - dirn = user.dir // if laying on the tile we're on, lay in the direction we're facing + dirn = user.dir //If laying on the tile we're on, lay in the direction we're facing else dirn = get_dir(T, user) + else + dirn = dirnew - for(var/obj/structure/cable/LC in T) - if(LC.d2 == dirn && LC.d1 == 0) - to_chat(user, "There's already a cable at that position!") - return + for(var/obj/structure/cable/LC in T) + if(LC.d2 == dirn && LC.d1 == 0) + to_chat(user, "There's already a cable at that position!") + return - var/obj/structure/cable/C = get_new_cable(T) + var/obj/structure/cable/C = get_new_cable(T) - //set up the new cable - C.d1 = 0 //it's a O-X node cable - C.d2 = dirn - C.add_fingerprint(user) - C.updateicon() + //set up the new cable + C.d1 = 0 //it's a O-X node cable + C.d2 = dirn + C.add_fingerprint(user) + C.updateicon() - //create a new powernet with the cable, if needed it will be merged later - var/datum/powernet/PN = new() - PN.add_cable(C) + //create a new powernet with the cable, if needed it will be merged later + var/datum/powernet/PN = new() + PN.add_cable(C) - C.mergeConnectedNetworks(C.d2) //merge the powernet with adjacents powernets - C.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets + C.mergeConnectedNetworks(C.d2) //merge the powernet with adjacents powernets + C.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets - if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions - C.mergeDiagonalsNetworks(C.d2) + if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions + C.mergeDiagonalsNetworks(C.d2) + use(1) - use(1) + if(C.shock(user, 50)) + if(prob(50)) //fail + new /obj/item/stack/cable_coil(get_turf(C), 1, C.color) + qdel(C) // qdel - if(C.shock(user, 50)) - if(prob(50)) //fail - new/obj/item/stack/cable_coil(C.loc, 1, C.color) - qdel(C) // qdel + return C // called when cable_coil is click on an installed obj/cable // or click on a turf that already contains a "node" cable @@ -675,7 +683,7 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list( if(!isturf(U)) return - var/turf/T = C.loc + var/turf/T = get_turf(C) if(!isturf(T) || T.intact) // sanity checks, also stop use interacting with T-scanner revealed cable return @@ -700,38 +708,7 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list( // cable is pointing at us, we're standing on an open tile // so create a stub pointing at the clicked cable on our tile - var/fdirn = turn(dirn, 180) // the opposite direction - - for(var/obj/structure/cable/LC in U) // check to make sure there's not a cable there already - if(LC.d1 == fdirn || LC.d2 == fdirn) - to_chat(user, "There's already a cable at that position.") - return - - var/obj/structure/cable/NC = new(U) - NC.cableColor(color) - - NC.d1 = 0 - NC.d2 = fdirn - NC.add_fingerprint() - NC.updateicon() - - //create a new powernet with the cable, if needed it will be merged later - var/datum/powernet/newPN = new() - newPN.add_cable(NC) - - NC.mergeConnectedNetworks(NC.d2) //merge the powernet with adjacents powernets - NC.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets - - if(NC.d2 & (NC.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions - NC.mergeDiagonalsNetworks(NC.d2) - - use(1) - - if(NC.shock(user, 50)) - if(prob(50)) //fail - new/obj/item/stack/cable_coil(NC.loc, 1, NC.color) - qdel(NC) // qdel - + place_turf(T, user, turn(dirn, 180)) return // exisiting cable doesn't point at our position, so see if it's a stub @@ -777,7 +754,7 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list( if(C.shock(user, 50)) if(prob(50)) //fail - new/obj/item/stack/cable_coil(C.loc, 2, C.color) + new/obj/item/stack/cable_coil(get_turf(C), 2, C.color) qdel(C) // qdel return diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index ccab76f6e92..5c8d5136324 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -81,13 +81,14 @@ /obj/item/projectile/bullet/pellet name = "pellet" - damage = 15 + damage = 12.5 /obj/item/projectile/bullet/pellet/weak damage = 6 /obj/item/projectile/bullet/pellet/weak/New() - range = rand(8) + range = rand(1, 8) + ..() /obj/item/projectile/bullet/pellet/weak/on_range() var/datum/effect/system/spark_spread/sparks = new /datum/effect/system/spark_spread @@ -99,7 +100,8 @@ damage = 3 /obj/item/projectile/bullet/pellet/overload/New() - range = rand(10) + range = rand(1, 10) + ..() /obj/item/projectile/bullet/pellet/overload/on_hit(atom/target, blocked = 0) ..() diff --git a/code/modules/research/xenoarchaeology/tools/anomaly_suit.dm b/code/modules/research/xenoarchaeology/tools/anomaly_suit.dm index 9e9de74e73e..c3e29fe8638 100644 --- a/code/modules/research/xenoarchaeology/tools/anomaly_suit.dm +++ b/code/modules/research/xenoarchaeology/tools/anomaly_suit.dm @@ -23,6 +23,9 @@ item_state = "cespace_suit" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 100) allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank) + species_fit = null + sprite_sheets = null + sprite_sheets_obj = null /obj/item/clothing/head/helmet/space/eva/anomaly name = "Excavation hood" @@ -30,3 +33,6 @@ icon_state = "cespace_helmet" item_state = "cespace_helmet" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 100) + species_fit = null + sprite_sheets = null + sprite_sheets_obj = null diff --git a/html/changelog.html b/html/changelog.html index 5c7d200cb58..97656cf4d69 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,7 +55,54 @@ -->
+

12 March 2017

+

Crazylemon64 updated:

+ +

Jovaniph updated:

+ +

Markolie updated:

+ +

Twinmold93 updated:

+ +

11 March 2017

+

Developed by XDTM, ported by davipatury updated:

+ +

Flatty Patty updated:

+ +

FlattyPatty updated:

+ +

Fox McCloud updated:

+ +

KasparoVy updated:

+

Markolie updated: