diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 35b70bdb84..d33eaa35da 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -6,7 +6,8 @@ #define PLANE_SPACE -95 #define PLANE_SPACE_PARALLAX -90 -#define GAME_PLANE 0 +#define GAME_PLANE -1 +#define BLACKNESS_PLANE 0 //To keep from conflicts with SEE_BLACKNESS internals #define SPACE_LAYER 1.8 #define ABOVE_SPACE_LAYER 1.9 //#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define diff --git a/code/__DEFINES/server_tools.dm b/code/__DEFINES/server_tools.dm index b86a54959f..2773965d9c 100644 --- a/code/__DEFINES/server_tools.dm +++ b/code/__DEFINES/server_tools.dm @@ -1,4 +1,4 @@ -// /tg/station 13 server tools API v3.1 +// /tg/station 13 server tools API v3.1.0.1 //CONFIGURATION //use this define if you want to do configuration outside of this file @@ -21,6 +21,8 @@ #define SERVER_TOOLS_LOG(message) log_world("SERVICE: [##message]") //Notify current in-game administrators of a string `event` #define SERVER_TOOLS_NOTIFY_ADMINS(event) message_admins(##event) +//The current amount of connected clients +#define SERVER_TOOLS_CLIENT_COUNT GLOB.clients.len #endif //Required hooks: @@ -62,7 +64,7 @@ //IMPLEMENTATION -#define SERVICE_API_VERSION_STRING "3.1.0.0" +#define SERVICE_API_VERSION_STRING "3.1.0.1" #define REBOOT_MODE_NORMAL 0 #define REBOOT_MODE_HARD 1 @@ -78,12 +80,13 @@ #define SERVICE_CMD_GRACEFUL_SHUTDOWN "graceful_shutdown" #define SERVICE_CMD_WORLD_ANNOUNCE "world_announce" #define SERVICE_CMD_LIST_CUSTOM "list_custom_commands" +#define SERVICE_CMD_API_COMPATIBLE "api_compat" +#define SERVICE_CMD_PLAYER_COUNT "client_count" #define SERVICE_CMD_PARAM_KEY "serviceCommsKey" #define SERVICE_CMD_PARAM_COMMAND "command" #define SERVICE_CMD_PARAM_SENDER "sender" #define SERVICE_CMD_PARAM_CUSTOM "custom" -#define SERVICE_CMD_API_COMPATIBLE "api_compat" #define SERVICE_JSON_PARAM_HELPTEXT "help_text" #define SERVICE_JSON_PARAM_ADMINONLY "admin_only" diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 1d36f7d31e..4d1ca2c778 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -313,11 +313,15 @@ inv.hud = src inv_slots[inv.slot_id] = inv inv.update_icon() + + update_locked_slots() /datum/hud/human/update_locked_slots() if(!mymob) return var/mob/living/carbon/human/H = mymob + if(!istype(H) || !H.dna.species) + return var/datum/species/S = H.dna.species for(var/obj/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(inv.slot_id) diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index 49ccb411fc..a9807a599c 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -74,6 +74,10 @@ GLOBAL_PROTECT(config_dir) if(copytext(L, 1, 2) == "#") continue + var/lockthis = copytext(L, 1, 2) == "@" + if(lockthis) + L = copytext(L, 2) + var/pos = findtext(L, " ") var/entry = null var/value = null @@ -96,6 +100,9 @@ GLOBAL_PROTECT(config_dir) log_config("Found [entry] in [filename] when it should have been in [E.resident_file]! Ignoring.") continue + if(lockthis) + E.protection |= CONFIG_ENTRY_LOCKED + var/validated = E.ValidateAndSet(value) if(!validated) log_config("Failed to validate setting \"[value]\" for [entry]") diff --git a/code/datums/action.dm b/code/datums/action.dm index a65294fa40..cf1046ca8f 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -591,3 +591,50 @@ var/mob/M = owner var/datum/language_holder/H = M.get_language_holder() H.open_language_menu(usr) + +/datum/action/innate/dash + name = "Dash" + desc = "Teleport to the targeted location." + icon_icon = 'icons/mob/actions/actions_items.dmi' + button_icon_state = "jetboot" + var/charged = TRUE + var/charge_rate = 250 + var/mob/living/carbon/human/holder + var/obj/item/dashing_item + var/dash_sound = 'sound/magic/blink.ogg' + var/recharge_sound = 'sound/magic/charge.ogg' + var/beam_effect = "blur" + var/phasein = /obj/effect/temp_visual/dir_setting/ninja/phase + var/phaseout = /obj/effect/temp_visual/dir_setting/ninja/phase/out + +/datum/action/innate/dash/Grant(mob/user, obj/dasher) + . = ..() + dashing_item = dasher + holder = user + +/datum/action/innate/dash/IsAvailable() + if(charged) + return TRUE + else + return FALSE + +/datum/action/innate/dash/Activate() + dashing_item.attack_self(holder) //Used to toggle dash behavior in the dashing item + +/datum/action/innate/dash/proc/Teleport(mob/user, atom/target) + var/turf/T = get_turf(target) + if(target in view(user.client.view, get_turf(user))) + var/obj/spot1 = new phaseout(get_turf(user), user.dir) + user.forceMove(T) + playsound(T, dash_sound, 25, 1) + var/obj/spot2 = new phasein(get_turf(user), user.dir) + spot1.Beam(spot2,beam_effect,time=20) + charged = FALSE + holder.update_action_buttons_icon() + addtimer(CALLBACK(src, .proc/charge), charge_rate) + +/datum/action/innate/dash/proc/charge() + charged = TRUE + holder.update_action_buttons_icon() + playsound(dashing_item, recharge_sound, 50, 1) + to_chat(holder, "[dashing_item] is ready for another jaunt.") \ No newline at end of file diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index 25b04b4312..20d218f767 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -384,3 +384,31 @@ if(islist(owner.stun_absorption) && owner.stun_absorption["blooddrunk"]) owner.stun_absorption -= "blooddrunk" +/datum/status_effect/sword_spin + id = "Bastard Sword Spin" + duration = 50 + tick_interval = 8 + alert_type = null + + +/datum/status_effect/sword_spin/on_apply() + owner.visible_message("[owner] begins swinging the sword with inhuman strength!") + var/oldcolor = owner.color + owner.color = "#ff0000" + owner.add_stun_absorption("bloody bastard sword", duration, 2, "doesn't even flinch as the sword's power courses through them!", "You shrug off the stun!", " glowing with a blazing red aura!") + owner.spin(duration,1) + animate(owner, color = oldcolor, time = duration, easing = EASE_IN) + addtimer(CALLBACK(owner, /atom/proc/update_atom_colour), duration) + playsound(owner, 'sound/weapons/fwoosh.wav', 75, 0) + return ..() + + +/datum/status_effect/sword_spin/tick() + playsound(owner, 'sound/weapons/fwoosh.wav', 75, 0) + var/obj/item/slashy + slashy = owner.get_active_held_item() + for(var/mob/living/M in orange(1,owner)) + slashy.attack(M, owner) + +/datum/status_effect/sword_spin/on_remove() + owner.visible_message("[owner]'s inhuman strength dissipates and the sword's runes grow cold!") diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 55f8ece5e6..876cace14d 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -72,6 +72,170 @@ if(is_servant_of_ratvar(C) && C.reagents) C.reagents.add_reagent("heparin", 1) +/obj/item/twohanded/required/cult_bastard + name = "bloody bastard sword" + desc = "An enormous sword used by Nar-Sien cultists to rapidly harvest the souls of non-believers." + w_class = WEIGHT_CLASS_HUGE + block_chance = 50 + throwforce = 20 + force = 35 + armour_penetration = 45 + throw_speed = 1 + throw_range = 3 + sharpness = IS_SHARP + light_color = "#ff0000" + attack_verb = list("cleaved", "slashed", "torn", "hacked", "ripped", "diced", "carved") + icon_state = "cultbastard" + item_state = "cultbastard" + hitsound = 'sound/weapons/bladeslice.ogg' + lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi' + righthand_file = 'icons/mob/inhands/64x64_righthand.dmi' + inhand_x_dimension = 64 + inhand_y_dimension = 64 + actions_types = list() + flags_2 = SLOWS_WHILE_IN_HAND_2 + var/datum/action/innate/dash/cult/jaunt + var/datum/action/innate/cult/spin2win/linked_action + var/spinning = FALSE + var/spin_cooldown = 250 + var/list/shards = list() + var/dash_toggled = TRUE + +/obj/item/twohanded/required/cult_bastard/Initialize() + . = ..() + set_light(4) + jaunt = new(src) + linked_action = new(src) + +/obj/item/twohanded/required/cult_bastard/can_be_pulled(user) + return FALSE + +/obj/item/twohanded/required/cult_bastard/attack_self(mob/user) + dash_toggled = !dash_toggled + if(dash_toggled) + to_chat(loc, "You raise the [src] and prepare to jaunt with it.") + else + to_chat(loc, "You lower the [src] and prepare to swing it normally.") + +/obj/item/twohanded/required/cult_bastard/pickup(mob/living/user) + . = ..() + if(!iscultist(user)) + if(!is_servant_of_ratvar(user)) + to_chat(user, "\"I wouldn't advise that.\"") + to_chat(user, "An overwhelming sense of nausea overpowers you!") + user.Dizzy(80) + user.Knockdown(30) + return + else + to_chat(user, "\"One of Ratvar's toys is trying to play with things [user.p_they()] shouldn't. Cute.\"") + to_chat(user, "A horrible force yanks at your arm!") + user.emote("scream") + user.apply_damage(30, BRUTE, pick("l_arm", "r_arm")) + user.Knockdown(50) + return + jaunt.Grant(user, src) + linked_action.Grant(user, src) + user.update_icons() + +/obj/item/twohanded/required/cult_bastard/dropped(mob/user) + . = ..() + linked_action.Remove(user) + jaunt.Remove(user) + user.update_icons() + +/obj/item/twohanded/required/cult_bastard/IsReflect() + if(spinning) + playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1) + return TRUE + else + ..() + +/obj/item/twohanded/required/cult_bastard/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) + if(prob(final_block_chance)) + if(attack_type == PROJECTILE_ATTACK) + owner.visible_message("[owner] deflects [attack_text] with [src]!") + playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 100, 1) + return TRUE + else + playsound(src, 'sound/weapons/parry.ogg', 75, 1) + owner.visible_message("[owner] parries [attack_text] with [src]!") + return TRUE + return FALSE + +/obj/item/twohanded/required/cult_bastard/afterattack(atom/target, mob/user, proximity, click_parameters) + . = ..() + if(dash_toggled && jaunt.IsAvailable()) + jaunt.Teleport(user, target) + return + if(!proximity) + return + if(ishuman(target)) + var/mob/living/carbon/human/H = target + if(H.stat != CONSCIOUS) + var/obj/item/device/soulstone/SS = new /obj/item/device/soulstone(src) + SS.attack(H, user) + shards += SS + return + if(istype(target, /obj/structure/constructshell) && contents.len) + var/obj/item/device/soulstone/SS = contents[1] + if(istype(SS) && SS.transfer_soul("CONSTRUCT",target,user)) + qdel(SS) + +/datum/action/innate/dash/cult + name = "Rend the Veil" + desc = "Use the sword to shear open the flimsy fabric of this reality and teleport to your target." + icon_icon = 'icons/mob/actions/actions_cult.dmi' + button_icon_state = "phaseshift" + dash_sound = 'sound/magic/enter_blood.ogg' + recharge_sound = 'sound/magic/exit_blood.ogg' + beam_effect = "sendbeam" + phasein = /obj/effect/temp_visual/dir_setting/cult/phase + phaseout = /obj/effect/temp_visual/dir_setting/cult/phase/out + +/datum/action/innate/dash/cult/IsAvailable() + if(iscultist(holder) && charged) + return TRUE + else + return FALSE + + + +/datum/action/innate/cult/spin2win + name = "Geometer's Fury" + desc = "You draw on the power of the sword's ancient runes, spinning it wildly around you as you become immune to most attacks." + background_icon_state = "bg_demon" + button_icon_state = "sintouch" + var/cooldown = 0 + var/mob/living/carbon/human/holder + var/obj/item/twohanded/required/cult_bastard/sword + +/datum/action/innate/cult/spin2win/Grant(mob/user, obj/bastard) + . = ..() + sword = bastard + holder = user + +/datum/action/innate/cult/spin2win/IsAvailable() + if(iscultist(holder) && cooldown <= world.time) + return TRUE + else + return FALSE + +/datum/action/innate/cult/spin2win/Activate() + cooldown = world.time + sword.spin_cooldown + holder.changeNext_move(50) + holder.apply_status_effect(/datum/status_effect/sword_spin) + sword.spinning = TRUE + sword.block_chance = 100 + sword.slowdown += 1.5 + addtimer(CALLBACK(src, .proc/stop_spinning), 50) + holder.update_action_buttons_icon() + +/datum/action/innate/cult/spin2win/proc/stop_spinning() + sword.spinning = FALSE + sword.block_chance = 50 + sword.slowdown -= 1.5 + sleep(sword.spin_cooldown) + holder.update_action_buttons_icon() /obj/item/restraints/legcuffs/bola/cult name = "nar'sien bola" diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index c1ccf9a368..0144872c17 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -100,15 +100,21 @@ if(cooldowntime > world.time) to_chat(user, "The magic in [src] is weak, it will be ready to use again in [DisplayTimeText(cooldowntime - world.time)].") return - var/choice = alert(user,"You study the schematics etched into the forge...",,"Shielded Robe","Flagellant's Robe","Nar-Sien Hardsuit") + var/choice = alert(user,"You study the schematics etched into the forge...",,"Shielded Robe","Flagellant's Robe","Bastard Sword") var/pickedtype switch(choice) if("Shielded Robe") pickedtype = /obj/item/clothing/suit/hooded/cultrobes/cult_shield if("Flagellant's Robe") pickedtype = /obj/item/clothing/suit/hooded/cultrobes/berserker - if("Nar-Sien Hardsuit") - pickedtype = /obj/item/clothing/suit/space/hardsuit/cult + if("Bastard Sword") + if((world.time - SSticker.round_start_time) >= 12000) + pickedtype = /obj/item/twohanded/required/cult_bastard + else + cooldowntime = 12000 - (world.time - SSticker.round_start_time) + to_chat(user, "The forge fires are not yet hot enough for this weapon, give it another [DisplayTimeText(cooldowntime - world.time)].") + cooldowntime = 0 + return if(src && !QDELETED(src) && anchored && pickedtype && Adjacent(user) && !user.incapacitated() && iscultist(user) && cooldowntime <= world.time) cooldowntime = world.time + 2400 var/obj/item/N = new pickedtype(get_turf(src)) diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index df57ded774..149c2ae912 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -199,7 +199,6 @@ SSticker.mode.cult -= A.mind SSticker.mode.update_cult_icons_removed(A.mind) qdel(T) - user.drop_item() qdel(src) else to_chat(user, "Creation failed!: The soul stone is empty! Go kill someone!") diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index e9a622365a..e55c728121 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -73,6 +73,7 @@ MASS SPECTROMETER origin_tech = "magnets=1;biotech=1" var/mode = 1 var/scanmode = 0 + var/advanced = FALSE /obj/item/device/healthanalyzer/attack_self(mob/user) if(!scanmode) @@ -97,7 +98,7 @@ MASS SPECTROMETER user.visible_message("[user] has analyzed [M]'s vitals.") if(scanmode == 0) - healthscan(user, M, mode) + healthscan(user, M, mode, advanced) else if(scanmode == 1) chemscan(user, M) @@ -105,7 +106,7 @@ MASS SPECTROMETER // Used by the PDA medical scanner too -/proc/healthscan(mob/living/user, mob/living/M, mode = 1) +/proc/healthscan(mob/living/user, mob/living/M, mode = 1, advanced = FALSE) if(user.incapacitated() || user.eye_blind) return //Damage specifics @@ -115,8 +116,8 @@ MASS SPECTROMETER var/brute_loss = M.getBruteLoss() var/mob_status = (M.stat == DEAD ? "Deceased" : "[round(M.health/M.maxHealth,0.01)*100] % healthy") - if(M.status_flags & FAKEDEATH) - mob_status = "Deceased" + if(M.status_flags & FAKEDEATH && !advanced) + mob_status = "Deceased" oxy_loss = max(rand(1, 40), oxy_loss, (300 - (tox_loss + fire_loss + brute_loss))) // Random oxygen loss if(ishuman(M)) @@ -141,19 +142,77 @@ MASS SPECTROMETER if(oxy_loss > 10) to_chat(user, "\t[oxy_loss > 50 ? "Severe" : "Minor"] oxygen deprivation detected.") if(tox_loss > 10) - to_chat(user, "\t[tox_loss > 50 ? "Critical" : "Dangerous"] amount of toxins detected.") + to_chat(user, "\t[tox_loss > 50 ? "Severe" : "Minor"] amount of toxin damage detected.") if(M.getStaminaLoss()) to_chat(user, "\tSubject appears to be suffering from fatigue.") + if(advanced) + to_chat(user, "\tFatigue Level: [M.getStaminaLoss()]%.") if (M.getCloneLoss()) to_chat(user, "\tSubject appears to have [M.getCloneLoss() > 30 ? "severe" : "minor"] cellular damage.") - if (M.reagents && M.reagents.get_reagent_amount("epinephrine")) - to_chat(user, "\tBloodstream analysis located [M.reagents.get_reagent_amount("epinephrine")] units of rejuvenation chemicals.") + if(advanced) + to_chat(user, "\tCellular Damage Level: [M.getCloneLoss()].") if (M.getBrainLoss() >= 100 || !M.getorgan(/obj/item/organ/brain)) to_chat(user, "\tSubject brain function is non-existent.") else if (M.getBrainLoss() >= 60) to_chat(user, "\tSevere brain damage detected. Subject likely to have mental retardation.") else if (M.getBrainLoss() >= 10) to_chat(user, "\tBrain damage detected. Subject may have had a concussion.") + if(advanced) + to_chat(user, "\tBrain Activity Level: [100 - M.getBrainLoss()]%.") + if (M.radiation) + to_chat(user, "\tSubject is irradiated.") + if(advanced) + to_chat(user, "\tRadiation Level: [M.radiation]%.") + + if(advanced && M.hallucinating()) + to_chat(user, "\tSubject is hallucinating.") + + //Eyes and ears + if(advanced) + if(iscarbon(M)) + var/mob/living/carbon/C = M + var/obj/item/organ/ears/ears = C.getorganslot("ears") + to_chat(user, "\t==EAR STATUS==") + if(istype(ears)) + var/healthy = TRUE + if(C.disabilities & DEAF) + healthy = FALSE + to_chat(user, "\tSubject is genetically deaf.") + else + if(ears.ear_damage) + to_chat(user, "\tSubject has [ears.ear_damage > UNHEALING_EAR_DAMAGE? "permanent ": "temporary "]hearing damage.") + healthy = FALSE + if(ears.deaf) + to_chat(user, "\tSubject is [ears.ear_damage > UNHEALING_EAR_DAMAGE ? "permanently ": "temporarily "] deaf.") + healthy = FALSE + if(healthy) + to_chat(user, "\tHealthy.") + else + to_chat(user, "\tSubject does not have ears.") + var/obj/item/organ/eyes/eyes = C.getorganslot("eye_sight") + to_chat(user, "\t==EYE STATUS==") + if(istype(eyes)) + var/healthy = TRUE + if(C.disabilities & BLIND) + to_chat(user, "\tSubject is blind.") + healthy = FALSE + if(C.disabilities & NEARSIGHT) + to_chat(user, "\tSubject is nearsighted.") + healthy = FALSE + if(eyes.eye_damage > 30) + to_chat(user, "\tSubject has severe eye damage.") + healthy = FALSE + else if(eyes.eye_damage > 20) + to_chat(user, "\tSubject has significant eye damage.") + healthy = FALSE + else if(eyes.eye_damage) + to_chat(user, "\tSubject has minor eye damage.") + healthy = FALSE + if(healthy) + to_chat(user, "\tHealthy.") + else + to_chat(user, "\tSubject does not have eyes.") + if(ishuman(M)) var/mob/living/carbon/human/H = M @@ -177,7 +236,7 @@ MASS SPECTROMETER to_chat(user, "Body temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F)") // Time of death - if(M.tod && (M.stat == DEAD || (M.status_flags & FAKEDEATH))) + if(M.tod && (M.stat == DEAD || ((M.status_flags & FAKEDEATH) && !advanced))) to_chat(user, "Time of Death: [M.tod]") var/tdelta = round(world.time - M.timeofdeath) if(tdelta < (DEFIB_TIME_LIMIT * 10)) @@ -251,6 +310,12 @@ MASS SPECTROMETER if(0) to_chat(usr, "The scanner no longer shows limb damage.") +/obj/item/device/healthanalyzer/advanced + name = "advanced health analyzer" + icon_state = "health_adv" + desc = "A hand-held body scanner able to distinguish vital signs of the subject with high accuracy." + origin_tech = "magnets=3;biotech=3" + advanced = TRUE /obj/item/device/analyzer desc = "A hand-held environmental scanner which reports current gas levels." diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index 1badef90cf..634fbee9d2 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -335,8 +335,8 @@ /obj/item/nullrod/carp name = "carp-sie plushie" desc = "An adorable stuffed toy that resembles the god of all carp. The teeth look pretty sharp. Activate it to receive the blessing of Carp-Sie." - icon = 'icons/obj/toy.dmi' - icon_state = "carpplushie" + icon = 'icons/obj/plushes.dmi' + icon_state = "carpplush" item_state = "carp_plushie" lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' righthand_file = 'icons/mob/inhands/items_righthand.dmi' diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm index dc6993cdbe..28856e17d8 100644 --- a/code/game/objects/items/storage/book.dm +++ b/code/game/objects/items/storage/book.dm @@ -156,6 +156,24 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible", var/unholy2clean = A.reagents.get_reagent_amount("unholywater") A.reagents.del_reagent("unholywater") A.reagents.add_reagent("holywater",unholy2clean) + if(istype(A, /obj/item/twohanded/required/cult_bastard)) + var/obj/item/twohanded/required/cult_bastard/sword = A + to_chat(user, "You begin to exorcise [sword].") + playsound(src,'sound/hallucinations/veryfar_noise.ogg',40,1) + if(do_after(user, 40, target = sword)) + playsound(src,'sound/effects/pray_chaplain.ogg',60,1) + for(var/obj/item/device/soulstone/SS in sword.shards) + SS.usability = TRUE + for(var/mob/living/simple_animal/shade/EX in SS) + SSticker.mode.remove_cultist(EX.mind, 1, 0) + EX.icon_state = "ghost1" + EX.name = "Purified [EX.name]" + SS.release_shades(user) + qdel(SS) + new /obj/item/nullrod/claymore(get_turf(sword)) + user.visible_message("[user] has purified the [sword]!!") + qdel(sword) + /obj/item/storage/book/bible/booze desc = "To be applied to the head repeatedly." diff --git a/code/game/objects/structures/beds_chairs/bed.dm b/code/game/objects/structures/beds_chairs/bed.dm index 935b62f46a..5c36c5a6ba 100644 --- a/code/game/objects/structures/beds_chairs/bed.dm +++ b/code/game/objects/structures/beds_chairs/bed.dm @@ -21,6 +21,10 @@ var/buildstacktype = /obj/item/stack/sheet/metal var/buildstackamount = 2 +/obj/structure/bed/examine(mob/user) + ..() + to_chat(user, "It's held together by a couple of bolts.") + /obj/structure/bed/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) if(buildstacktype) diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index aed1679322..9d6985c620 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -1,6 +1,6 @@ /obj/structure/chair name = "chair" - desc = "You sit in this. Either by will or force.\nDrag your sprite to sit in the chair. Alt-click to rotate it clockwise." + desc = "You sit in this. Either by will or force." icon = 'icons/obj/chairs.dmi' icon_state = "chair" anchored = TRUE @@ -14,6 +14,14 @@ var/item_chair = /obj/item/chair // if null it can't be picked up layer = OBJ_LAYER +/obj/structure/chair/examine(mob/user) + ..() + to_chat(user, "It's held together by a couple of bolts.") + if(!has_buckled_mobs()) + to_chat(user, "Drag your sprite to sit in it. Alt-click to rotate.") + else + to_chat(user, "Alt-click to rotate.") + /obj/structure/chair/Initialize() . = ..() if(!anchored) //why would you put these on the shuttle? @@ -140,7 +148,7 @@ /obj/structure/chair/comfy name = "comfy chair" - desc = "It looks comfy.\nAlt-click to rotate it clockwise." + desc = "It looks comfy." icon_state = "comfychair" color = rgb(255,255,255) resistance_flags = FLAMMABLE diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index c7b63be32b..3d77be1bb5 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -76,8 +76,12 @@ /obj/structure/closet/examine(mob/user) ..() + if(welded) + to_chat(user, "It's welded shut.") if(anchored) - to_chat(user, "It is anchored to the ground.") + to_chat(user, "It is bolted to the ground.") + if(opened) + to_chat(user, "The parts are welded together.") else if(secure && !opened) to_chat(user, "Alt-click to [locked ? "unlock" : "lock"].") @@ -453,4 +457,4 @@ /obj/structure/closet/return_temperature() - return \ No newline at end of file + return diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index a2a055f464..ee9ecfc908 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -1,93 +1,94 @@ -/obj/structure/closet/secure_closet/medical1 - name = "medicine closet" - desc = "Filled to the brim with medical junk." - icon_state = "med" +/obj/structure/closet/secure_closet/medical1 + name = "medicine closet" + desc = "Filled to the brim with medical junk." + icon_state = "med" req_access = list(ACCESS_MEDICAL) - -/obj/structure/closet/secure_closet/medical1/PopulateContents() - ..() - new /obj/item/reagent_containers/glass/beaker(src) - new /obj/item/reagent_containers/glass/beaker(src) - new /obj/item/reagent_containers/dropper(src) - new /obj/item/reagent_containers/dropper(src) - new /obj/item/storage/belt/medical(src) - new /obj/item/storage/box/syringes(src) - new /obj/item/reagent_containers/glass/bottle/toxin(src) - new /obj/item/reagent_containers/glass/bottle/morphine(src) - new /obj/item/reagent_containers/glass/bottle/morphine(src) - for(var/i in 1 to 3) - new /obj/item/reagent_containers/glass/bottle/epinephrine(src) - for(var/i in 1 to 3) - new /obj/item/reagent_containers/glass/bottle/charcoal(src) - new /obj/item/storage/box/rxglasses(src) - -/obj/structure/closet/secure_closet/medical2 - name = "anesthetic closet" - desc = "Used to knock people out." + +/obj/structure/closet/secure_closet/medical1/PopulateContents() + ..() + new /obj/item/reagent_containers/glass/beaker(src) + new /obj/item/reagent_containers/glass/beaker(src) + new /obj/item/reagent_containers/dropper(src) + new /obj/item/reagent_containers/dropper(src) + new /obj/item/storage/belt/medical(src) + new /obj/item/storage/box/syringes(src) + new /obj/item/reagent_containers/glass/bottle/toxin(src) + new /obj/item/reagent_containers/glass/bottle/morphine(src) + new /obj/item/reagent_containers/glass/bottle/morphine(src) + for(var/i in 1 to 3) + new /obj/item/reagent_containers/glass/bottle/epinephrine(src) + for(var/i in 1 to 3) + new /obj/item/reagent_containers/glass/bottle/charcoal(src) + new /obj/item/storage/box/rxglasses(src) + +/obj/structure/closet/secure_closet/medical2 + name = "anesthetic closet" + desc = "Used to knock people out." req_access = list(ACCESS_SURGERY) - -/obj/structure/closet/secure_closet/medical2/PopulateContents() - ..() - for(var/i in 1 to 3) - new /obj/item/tank/internals/anesthetic(src) - for(var/i in 1 to 3) - new /obj/item/clothing/mask/breath/medical(src) - -/obj/structure/closet/secure_closet/medical3 - name = "medical doctor's locker" + +/obj/structure/closet/secure_closet/medical2/PopulateContents() + ..() + for(var/i in 1 to 3) + new /obj/item/tank/internals/anesthetic(src) + for(var/i in 1 to 3) + new /obj/item/clothing/mask/breath/medical(src) + +/obj/structure/closet/secure_closet/medical3 + name = "medical doctor's locker" req_access = list(ACCESS_SURGERY) - icon_state = "med_secure" - -/obj/structure/closet/secure_closet/medical3/PopulateContents() - ..() - new /obj/item/device/radio/headset/headset_med(src) - new /obj/item/defibrillator/loaded(src) - new /obj/item/clothing/gloves/color/latex/nitrile(src) - new /obj/item/storage/belt/medical(src) - new /obj/item/clothing/glasses/hud/health(src) - return - -/obj/structure/closet/secure_closet/CMO - name = "\proper chief medical officer's locker" + icon_state = "med_secure" + +/obj/structure/closet/secure_closet/medical3/PopulateContents() + ..() + new /obj/item/device/radio/headset/headset_med(src) + new /obj/item/defibrillator/loaded(src) + new /obj/item/clothing/gloves/color/latex/nitrile(src) + new /obj/item/storage/belt/medical(src) + new /obj/item/clothing/glasses/hud/health(src) + return + +/obj/structure/closet/secure_closet/CMO + name = "\proper chief medical officer's locker" req_access = list(ACCESS_CMO) - icon_state = "cmo" - -/obj/structure/closet/secure_closet/CMO/PopulateContents() - ..() - new /obj/item/clothing/neck/cloak/cmo(src) - new /obj/item/storage/backpack/duffelbag/med(src) - new /obj/item/clothing/suit/bio_suit/cmo(src) - new /obj/item/clothing/head/bio_hood/cmo(src) - new /obj/item/clothing/suit/toggle/labcoat/cmo(src) - new /obj/item/clothing/under/rank/chief_medical_officer(src) - new /obj/item/clothing/shoes/sneakers/brown (src) - new /obj/item/cartridge/cmo(src) - new /obj/item/device/radio/headset/heads/cmo(src) - new /obj/item/device/megaphone/command(src) - new /obj/item/defibrillator/compact/loaded(src) - new /obj/item/clothing/gloves/color/latex/nitrile(src) - new /obj/item/storage/belt/medical(src) - new /obj/item/device/assembly/flash/handheld(src) - new /obj/item/reagent_containers/hypospray/CMO(src) - new /obj/item/device/autosurgeon/cmo(src) - new /obj/item/door_remote/chief_medical_officer(src) - -/obj/structure/closet/secure_closet/animal - name = "animal control" + icon_state = "cmo" + +/obj/structure/closet/secure_closet/CMO/PopulateContents() + ..() + new /obj/item/clothing/neck/cloak/cmo(src) + new /obj/item/storage/backpack/duffelbag/med(src) + new /obj/item/clothing/suit/bio_suit/cmo(src) + new /obj/item/clothing/head/bio_hood/cmo(src) + new /obj/item/clothing/suit/toggle/labcoat/cmo(src) + new /obj/item/clothing/under/rank/chief_medical_officer(src) + new /obj/item/clothing/shoes/sneakers/brown (src) + new /obj/item/cartridge/cmo(src) + new /obj/item/device/radio/headset/heads/cmo(src) + new /obj/item/device/megaphone/command(src) + new /obj/item/defibrillator/compact/loaded(src) + new /obj/item/clothing/gloves/color/latex/nitrile(src) + new /obj/item/storage/belt/medical(src) + new /obj/item/device/healthanalyzer/advanced(src) + new /obj/item/device/assembly/flash/handheld(src) + new /obj/item/reagent_containers/hypospray/CMO(src) + new /obj/item/device/autosurgeon/cmo(src) + new /obj/item/door_remote/chief_medical_officer(src) + +/obj/structure/closet/secure_closet/animal + name = "animal control" req_access = list(ACCESS_SURGERY) - -/obj/structure/closet/secure_closet/animal/PopulateContents() - ..() - new /obj/item/device/assembly/signaler(src) - for(var/i in 1 to 3) - new /obj/item/device/electropack(src) - -/obj/structure/closet/secure_closet/chemical - name = "chemical closet" - desc = "Store dangerous chemicals in here." - icon_door = "chemical" - -/obj/structure/closet/secure_closet/chemical/PopulateContents() - ..() - new /obj/item/storage/box/pillbottles(src) - new /obj/item/storage/box/pillbottles(src) + +/obj/structure/closet/secure_closet/animal/PopulateContents() + ..() + new /obj/item/device/assembly/signaler(src) + for(var/i in 1 to 3) + new /obj/item/device/electropack(src) + +/obj/structure/closet/secure_closet/chemical + name = "chemical closet" + desc = "Store dangerous chemicals in here." + icon_door = "chemical" + +/obj/structure/closet/secure_closet/chemical/PopulateContents() + ..() + new /obj/item/storage/box/pillbottles(src) + new /obj/item/storage/box/pillbottles(src) diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 914be24cfd..1683ac00e6 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -1,5 +1,5 @@ /obj/structure/grille - desc = "A flimsy lattice of metal rods, with screws to secure it to the floor." + desc = "A flimsy framework of metal rods." name = "grille" icon = 'icons/obj/structures.dmi' icon_state = "grille" @@ -17,6 +17,13 @@ var/grille_type = null var/broken_type = /obj/structure/grille/broken +/obj/structure/grille/examine(mob/user) + ..() + if(anchored) + to_chat(user, "It's secured in place with screws. The rods look like they could be cut through.") + if(!anchored) + to_chat(user, "The anchoring screws are unscrewed. The rods look like they could be cut through.") + /obj/structure/grille/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) switch(the_rcd.mode) if(RCD_DECONSTRUCT) diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index d578b307db..c0dcd866d8 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -16,6 +16,13 @@ smooth = SMOOTH_MORE // flags_1 = CONDUCT_1 +/obj/structure/lattice/examine(mob/user) + ..() + deconstruction_hints(user) + +/obj/structure/lattice/proc/deconstruction_hints(mob/user) + to_chat(user, "The rods look like they could be cut. There's space for more rods or a tile.") + /obj/structure/lattice/Initialize(mapload) . = ..() for(var/obj/structure/lattice/LAT in loc) @@ -79,6 +86,9 @@ smooth = SMOOTH_TRUE canSmoothWith = null +/obj/structure/lattice/catwalk/deconstruction_hints(mob/user) + to_chat(user, "The supporting rods look like they could be cut.") + /obj/structure/lattice/catwalk/ratvar_act() new /obj/structure/lattice/catwalk/clockwork(loc) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 116ced183f..c54661066a 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -34,6 +34,13 @@ smooth = SMOOTH_TRUE canSmoothWith = list(/obj/structure/table, /obj/structure/table/reinforced) +/obj/structure/table/examine(mob/user) + ..() + deconstruction_hints(user) + +/obj/structure/table/proc/deconstruction_hints(mob/user) + to_chat(user, "The top is screwed on, but the main bolts are also visible.") + /obj/structure/table/Initialize() . = ..() for(var/obj/structure/table/T in src.loc) @@ -285,7 +292,7 @@ */ /obj/structure/table/reinforced name = "reinforced table" - desc = "A reinforced version of the four legged table, much harder to simply deconstruct." + desc = "A reinforced version of the four legged table." icon = 'icons/obj/smooth_structures/reinforced_table.dmi' icon_state = "r_table" deconstruction_ready = 0 @@ -295,6 +302,12 @@ integrity_failure = 50 armor = list(melee = 10, bullet = 30, laser = 30, energy = 100, bomb = 20, bio = 0, rad = 0, fire = 80, acid = 70) +/obj/structure/table/reinforced/deconstruction_hints(mob/user) + if(deconstruction_ready) + to_chat(user, "The top cover has been welded loose and the main frame's bolts are exposed.") + else + to_chat(user, "The top cover is firmly welded on.") + /obj/structure/table/reinforced/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/weldingtool)) var/obj/item/weldingtool/WT = W @@ -405,6 +418,10 @@ pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density. max_integrity = 20 +/obj/structure/rack/examine(mob/user) + ..() + to_chat(user, "It's held together by a couple of bolts.") + /obj/structure/rack/CanPass(atom/movable/mover, turf/target) if(src.density == 0) //Because broken racks -Agouri |TODO: SPRITE!| return 1 diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index 02206646d2..97634f7629 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -161,10 +161,10 @@ broken = 0 burnt = 0 if(user && !silent) - to_chat(user, "You remove the broken plating.") + to_chat(user, "You remove the broken plating.") else if(user && !silent) - to_chat(user, "You remove the floor tile.") + to_chat(user, "You remove the floor tile.") if(floor_tile && make_tile) new floor_tile(src) return make_plating() diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm index a24642c735..428c965197 100644 --- a/code/game/turfs/simulated/floor/fancy_floor.dm +++ b/code/game/turfs/simulated/floor/fancy_floor.dm @@ -8,10 +8,15 @@ */ /turf/open/floor/wood + desc = "Stylish dark wood." icon_state = "wood" floor_tile = /obj/item/stack/tile/wood broken_states = list("wood-broken", "wood-broken2", "wood-broken3", "wood-broken4", "wood-broken5", "wood-broken6", "wood-broken7") +/turf/open/floor/wood/examine(mob/user) + ..() + to_chat(user, "There's a few screws and a small crack visible.") + /turf/open/floor/wood/attackby(obj/item/C, mob/user, params) if(..()) return @@ -42,16 +47,16 @@ broken = 0 burnt = 0 if(user && !silent) - to_chat(user, "You remove the broken planks.") + to_chat(user, "You remove the broken planks.") else if(make_tile) if(user && !silent) - to_chat(user, "You unscrew the planks.") + to_chat(user, "You unscrew the planks.") if(floor_tile) new floor_tile(src) else if(user && !silent) - to_chat(user, "You forcefully pry off the planks, destroying them in the process.") + to_chat(user, "You forcefully pry off the planks, destroying them in the process.") return make_plating() /turf/open/floor/wood/cold @@ -78,7 +83,7 @@ if(istype(C, /obj/item/shovel) && params) new ore_type(src) new ore_type(src) //Make some sand if you shovel grass - user.visible_message("[user] digs up [src].", "You [src.turfverb] [src].") + user.visible_message("[user] digs up [src].", "You [src.turfverb] [src].") playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) make_plating() if(..()) @@ -143,6 +148,10 @@ canSmoothWith = list(/turf/open/floor/carpet) flags_1 = NONE +/turf/open/floor/carpet/examine(mob/user) + ..() + to_chat(user, "There's a small crack on the edge of it.") + /turf/open/floor/carpet/Initialize() . = ..() update_icon() diff --git a/code/game/turfs/simulated/floor/light_floor.dm b/code/game/turfs/simulated/floor/light_floor.dm index 247382d03c..0dd3673f6a 100644 --- a/code/game/turfs/simulated/floor/light_floor.dm +++ b/code/game/turfs/simulated/floor/light_floor.dm @@ -12,6 +12,10 @@ var/can_modify_colour = TRUE +/turf/open/floor/light/examine(mob/user) + ..() + to_chat(user, "There's a small crack on the edge of it.") + /turf/open/floor/light/Initialize() . = ..() update_icon() diff --git a/code/game/turfs/simulated/floor/plasteel_floor.dm b/code/game/turfs/simulated/floor/plasteel_floor.dm index 63c883f88c..b194127de8 100644 --- a/code/game/turfs/simulated/floor/plasteel_floor.dm +++ b/code/game/turfs/simulated/floor/plasteel_floor.dm @@ -4,6 +4,10 @@ broken_states = list("damaged1", "damaged2", "damaged3", "damaged4", "damaged5") burnt_states = list("floorscorched1", "floorscorched2") +/turf/open/floor/plasteel/examine(mob/user) + ..() + to_chat(user, "There's a small crack on the edge of it.") + /turf/open/floor/plasteel/update_icon() if(!..()) return 0 diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm index 8ad6657784..3e16da8b9f 100644 --- a/code/game/turfs/simulated/floor/plating.dm +++ b/code/game/turfs/simulated/floor/plating.dm @@ -12,6 +12,13 @@ icon_state = "plating" intact = FALSE +/turf/open/floor/plating/examine(mob/user) + ..() + if(broken || burnt) + to_chat(user, "It looks like the dents could be welded smooth.") + return + to_chat(user, "There are few attachment holes for a new tile or reinforcement rods.") + /turf/open/floor/plating/Initialize() if (!broken_states) broken_states = list("platingdmg1", "platingdmg2", "platingdmg3") diff --git a/code/game/turfs/simulated/floor/plating/asteroid.dm b/code/game/turfs/simulated/floor/plating/asteroid.dm index 2649a3a14d..848a7e8219 100644 --- a/code/game/turfs/simulated/floor/plating/asteroid.dm +++ b/code/game/turfs/simulated/floor/plating/asteroid.dm @@ -193,7 +193,7 @@ var/list/L = list(45) if(IsOdd(dir2angle(dir))) // We're going at an angle and we want thick angled tunnels. - L += -45 + L -= 45 // Expand the edges of our tunnel for(var/edge_angle in L) diff --git a/code/game/turfs/simulated/floor/reinf_floor.dm b/code/game/turfs/simulated/floor/reinf_floor.dm index 04c97aa7d5..74354e78c7 100644 --- a/code/game/turfs/simulated/floor/reinf_floor.dm +++ b/code/game/turfs/simulated/floor/reinf_floor.dm @@ -1,11 +1,16 @@ /turf/open/floor/engine name = "reinforced floor" + desc = "Extremely sturdy." icon_state = "engine" thermal_conductivity = 0.025 heat_capacity = INFINITY floor_tile = /obj/item/stack/rods +/turf/open/floor/engine/examine(mob/user) + ..() + to_chat(user, "The reinforcement rods are wrenched firmly in place.") + /turf/open/floor/engine/airless initial_gas_mix = "TEMP=2.7" diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index ae5f5c2fbb..33f02bc759 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -25,6 +25,21 @@ var/list/allowed_books = list(/obj/item/book, /obj/item/spellbook, /obj/item/storage/book) //Things allowed in the bookcase +/obj/structure/bookcase/examine(mob/user) + ..() + if(!anchored) + to_chat(user, "The bolts on the bottom are unsecured.") + if(anchored) + to_chat(user, "It's secured in place with bolts.") + switch(state) + if(0) + to_chat(user, "There's a small crack visible on the back panel.") + if(1) + to_chat(user, "There's space inside for a wooden shelf.") + if(2) + to_chat(user, "There's a small crack visible on the shelf.") + + /obj/structure/bookcase/Initialize(mapload) . = ..() if(!mapload) diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm index cc98fd827e..831fde141e 100644 --- a/code/modules/mob/dead/new_player/preferences_setup.dm +++ b/code/modules/mob/dead/new_player/preferences_setup.dm @@ -59,6 +59,7 @@ if(previewJob && !nude) mannequin.job = previewJob.title previewJob.equip(mannequin, TRUE) + mannequin.compile_overlays() CHECK_TICK preview_icon = icon('icons/effects/effects.dmi', "nothing") preview_icon.Scale(48+32, 16+32) diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index fd7b8a8db3..aa15e28e66 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -44,7 +44,7 @@ //Update the body's icon so it doesnt appear debrained anymore C.update_hair() -/obj/item/organ/brain/Remove(mob/living/carbon/C, special = 0,no_id_transfer = FALSE) +/obj/item/organ/brain/Remove(mob/living/carbon/C, special = 0, no_id_transfer = FALSE) ..() if((!gc_destroyed || (owner && !owner.gc_destroyed)) && !no_id_transfer) transfer_identity(C) diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 6068ef2d66..d90db23679 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -250,6 +250,9 @@ if(health >= 0 && !(status_flags & FAKEDEATH)) if(lying) + if(buckled) + to_chat(M, "You need to unbuckle [src] first to do that!") + return M.visible_message("[M] shakes [src] trying to get [p_them()] up!", \ "You shake [src] trying to get [p_them()] up!") else if(check_zone(M.zone_selected) == "head") diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 70a5f5225c..63b84b9cf3 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -4,6 +4,7 @@ voice_name = "Unknown" icon = 'icons/mob/human.dmi' icon_state = "caucasian_m" + appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE /mob/living/carbon/human/Initialize() verbs += /mob/living/proc/mob_sleep diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm index ef044e462b..84bf5bdf80 100644 --- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm @@ -37,7 +37,7 @@ if(H.nutrition > NUTRITION_LEVEL_FULL) H.nutrition = NUTRITION_LEVEL_FULL if(light_amount > 0.2) //if there's enough light, heal - H.heal_overall_damage(0.05,0) + H.heal_overall_damage(0.75,0) H.adjustOxyLoss(-0.5) if(H.nutrition < NUTRITION_LEVEL_STARVING + 55) diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm index de61ef7220..4347a8331c 100644 --- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm @@ -1,3 +1,5 @@ +#define HEART_RESPAWN_THRESHHOLD 40 + /datum/species/shadow // Humans cursed to stay in the darkness, lest their life forces drain. They regain health in shadow and die in light. name = "???" @@ -32,19 +34,14 @@ no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform, slot_s_store) species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR,NOHUNGER,NO_DNA_COPY,NOTRANSSTING) mutanteyes = /obj/item/organ/eyes/night_vision/nightmare - var/obj/effect/proc_holder/spell/targeted/shadowwalk/shadowwalk + mutant_organs = list(/obj/item/organ/heart/nightmare) + mutant_brain = /obj/item/organ/brain/nightmare - var/info_text = "You are a Nightmare. The ability shadow walk allows unlimited, unrestricted movement in the dark using. \ - Your light eater will destroy any light producing objects you attack, as well as destroy any lights a living creature may be holding. You will automatically dodge gunfire and melee attacks when on a dark tile." + var/info_text = "You are a Nightmare. The ability shadow walk allows unlimited, unrestricted movement in the dark while activated. \ + Your light eater will destroy any light producing objects you attack, as well as destroy any lights a living creature may be holding. You will automatically dodge gunfire and melee attacks when on a dark tile. If killed, you will eventually revive if left in darkness." /datum/species/shadow/nightmare/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..() - var/obj/effect/proc_holder/spell/targeted/shadowwalk/SW = new - C.AddSpell(SW) - shadowwalk = SW - var/obj/item/light_eater/blade = new - C.put_in_hands(blade) - to_chat(C, "[info_text]") C.real_name = "[pick(GLOB.nightmare_names)]" @@ -53,11 +50,6 @@ C.mind.name = C.real_name C.dna.real_name = C.real_name -/datum/species/shadow/nightmare/on_species_loss(mob/living/carbon/C) - . = ..() - if(shadowwalk) - C.RemoveSpell(shadowwalk) - /datum/species/shadow/nightmare/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H) var/turf/T = H.loc if(istype(T)) @@ -68,6 +60,93 @@ return -1 return 0 + + +//Organs + +/obj/item/organ/brain/nightmare + name = "tumorous mass" + desc = "A fleshy growth that was dug out of the skull of a Nightmare." + icon_state = "brain-x-d" + var/obj/effect/proc_holder/spell/targeted/shadowwalk/shadowwalk + +/obj/item/organ/brain/nightmare/Insert(mob/living/carbon/M, special = 0) + ..() + if(M.dna.species.id != "nightmare") + M.set_species(/datum/species/shadow/nightmare) + visible_message("[M] thrashes as [src] takes root in their body!") + var/obj/effect/proc_holder/spell/targeted/shadowwalk/SW = new + M.AddSpell(SW) + shadowwalk = SW + + +/obj/item/organ/brain/nightmare/Remove(mob/living/carbon/M, special = 0) + if(shadowwalk) + M.RemoveSpell(shadowwalk) + ..() + + +/obj/item/organ/heart/nightmare + name = "heart of darkness" + desc = "An alien organ that twists and writhes when exposed to light." + icon = 'icons/obj/surgery.dmi' + icon_state = "demon_heart-on" + color = "#1C1C1C" + var/respawn_progress = 0 + var/obj/item/light_eater/blade + + +/obj/item/organ/heart/nightmare/attack(mob/M, mob/living/carbon/user, obj/target) + if(M != user) + return ..() + user.visible_message("[user] raises [src] to their mouth and tears into it with their teeth!", \ + "[src] feels unnaturally cold in your hands. You raise [src] your mouth and devour it!") + playsound(user, 'sound/magic/demon_consume.ogg', 50, 1) + + + user.visible_message("Blood erupts from [user]'s arm as it reforms into a weapon!", \ + "Icy blood pumps through your veins as your arm reforms itself!") + user.temporarilyRemoveItemFromInventory(src, TRUE) + Insert(user) + +/obj/item/organ/heart/nightmare/Insert(mob/living/carbon/M, special = 0) + ..() + blade = new/obj/item/light_eater + M.put_in_hands(blade) + START_PROCESSING(SSobj, src) + +/obj/item/organ/heart/nightmare/Remove(mob/living/carbon/M, special = 0) + STOP_PROCESSING(SSobj, src) + respawn_progress = 0 + if(blade) + QDEL_NULL(blade) + M.visible_message("\The [blade] disintegrates!") + ..() + +/obj/item/organ/heart/nightmare/Stop() + return 0 + +/obj/item/organ/heart/nightmare/update_icon() + return //always beating visually + +/obj/item/organ/heart/nightmare/process() + if(QDELETED(owner) || owner.stat != DEAD) + respawn_progress = 0 + return + var/turf/T = get_turf(owner) + if(istype(T)) + var/light_amount = T.get_lumcount() + if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD) + respawn_progress++ + playsound(owner,'sound/effects/singlebeat.ogg',40,1) + if(respawn_progress >= HEART_RESPAWN_THRESHHOLD) + owner.revive(full_heal = TRUE) + owner.visible_message("[owner] staggers to their feet!") + playsound(owner, 'sound/hallucinations/far_noise.ogg', 50, 1) + respawn_progress = 0 + +//Weapon + /obj/item/light_eater name = "light eater" icon_state = "arm_blade" @@ -113,3 +192,5 @@ visible_message("[O] is disintegrated by [src]!") O.burn() playsound(src, 'sound/items/welder.ogg', 50, 1) + +#undef HEART_RESPAWN_THRESHHOLD \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm index 4ce8570c2b..016a3635ef 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -37,6 +37,7 @@ C.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW if(regen_cooldown < world.time) C.heal_overall_damage(4,4) + C.adjustToxLoss(-4) if(prob(4)) playsound(C, pick(spooks), 50, TRUE, 10) if(C.InCritical()) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm b/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm index 259ca4327d..325b971171 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm @@ -86,7 +86,7 @@ if(istype(head, /obj/item/clothing/mask)) used_head_icon = 'icons/mob/mask.dmi' var/mutable_appearance/head_overlay = head.build_worn_icon(state = head.icon_state, default_layer = DRONE_HEAD_LAYER, default_icon_file = used_head_icon) - head_overlay.pixel_y += -15 + head_overlay.pixel_y -= 15 drone_overlays[DRONE_HEAD_LAYER] = head_overlay diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm index dda0b3abad..04282d12fd 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm @@ -62,6 +62,9 @@ return TRUE + if(isobj(the_target) && is_type_in_typecache(the_target, wanted_objects)) + return TRUE + return FALSE /mob/living/simple_animal/hostile/asteroid/gutlunch/Destroy() diff --git a/code/modules/ninja/suit/gloves.dm b/code/modules/ninja/suit/gloves.dm index 62b8cee415..8eaaa40097 100644 --- a/code/modules/ninja/suit/gloves.dm +++ b/code/modules/ninja/suit/gloves.dm @@ -63,7 +63,7 @@ if(isnum(.)) //Numerical values of drained handle their feedback here, Alpha values handle it themselves (Research hacking) if(.) - to_chat(H, "Gained [.] energy from \the [A].") + to_chat(H, "Gained [DisplayPower(.)] of energy from [A].") else to_chat(H, "\The [A] has run dry of power, you must find another source!") else diff --git a/code/modules/power/singularity/particle_accelerator/particle.dm b/code/modules/power/singularity/particle_accelerator/particle.dm index 4519835c1f..f04c61426b 100644 --- a/code/modules/power/singularity/particle_accelerator/particle.dm +++ b/code/modules/power/singularity/particle_accelerator/particle.dm @@ -1,62 +1,65 @@ -/obj/effect/accelerated_particle - name = "Accelerated Particles" - desc = "Small things moving very fast." - icon = 'icons/obj/machines/particle_accelerator.dmi' - icon_state = "particle" +/obj/effect/accelerated_particle + name = "Accelerated Particles" + desc = "Small things moving very fast." + icon = 'icons/obj/machines/particle_accelerator.dmi' + icon_state = "particle" anchored = TRUE density = FALSE - var/movement_range = 10 - var/energy = 10 - var/speed = 1 - -/obj/effect/accelerated_particle/weak - movement_range = 8 - energy = 5 - -/obj/effect/accelerated_particle/strong - movement_range = 15 - energy = 15 - -/obj/effect/accelerated_particle/powerful - movement_range = 20 - energy = 50 - - -/obj/effect/accelerated_particle/New(loc) - ..() - - addtimer(CALLBACK(src, .proc/move), 1) - - + var/movement_range = 10 + var/energy = 10 + var/speed = 1 + +/obj/effect/accelerated_particle/weak + movement_range = 8 + energy = 5 + +/obj/effect/accelerated_particle/strong + movement_range = 15 + energy = 15 + +/obj/effect/accelerated_particle/powerful + movement_range = 20 + energy = 50 + + +/obj/effect/accelerated_particle/New(loc) + ..() + + addtimer(CALLBACK(src, .proc/move), 1) + + /obj/effect/accelerated_particle/Collide(atom/A) - if(A) - if(isliving(A)) - toxmob(A) - else if(istype(A, /obj/machinery/the_singularitygen)) - var/obj/machinery/the_singularitygen/S = A - S.energy += energy - else if(istype(A, /obj/singularity)) - var/obj/singularity/S = A - S.energy += energy - - -/obj/effect/accelerated_particle/Crossed(atom/A) - if(isliving(A)) - toxmob(A) - - -/obj/effect/accelerated_particle/ex_act(severity, target) - qdel(src) - -/obj/effect/accelerated_particle/proc/toxmob(mob/living/M) - M.rad_act(energy*6) - -/obj/effect/accelerated_particle/proc/move() - if(!step(src,dir)) - forceMove(get_step(src,dir)) - movement_range-- - if(movement_range == 0) - qdel(src) - else - sleep(speed) - move() + if(A) + if(isliving(A)) + toxmob(A) + else if(istype(A, /obj/machinery/the_singularitygen)) + var/obj/machinery/the_singularitygen/S = A + S.energy += energy + else if(istype(A, /obj/singularity)) + var/obj/singularity/S = A + S.energy += energy + else if(istype(A, /obj/structure/blob)) + var/obj/structure/blob/B = A + B.take_damage(energy*0.6) + movement_range = 0 + +/obj/effect/accelerated_particle/Crossed(atom/A) + if(isliving(A)) + toxmob(A) + + +/obj/effect/accelerated_particle/ex_act(severity, target) + qdel(src) + +/obj/effect/accelerated_particle/proc/toxmob(mob/living/M) + M.rad_act(energy*6) + +/obj/effect/accelerated_particle/proc/move() + if(!step(src,dir)) + forceMove(get_step(src,dir)) + movement_range-- + if(movement_range == 0) + qdel(src) + else + sleep(speed) + move() diff --git a/code/modules/projectiles/guns/misc/blastcannon.dm b/code/modules/projectiles/guns/misc/blastcannon.dm index 603f8843ca..5ee2ecec05 100644 --- a/code/modules/projectiles/guns/misc/blastcannon.dm +++ b/code/modules/projectiles/guns/misc/blastcannon.dm @@ -12,21 +12,17 @@ randomspread = FALSE var/obj/item/device/transfer_valve/bomb - var/datum/gas_mixture/air1 - var/datum/gas_mixture/air2 /obj/item/gun/blastcannon/New() if(!pin) pin = new - . = ..() + return ..() /obj/item/gun/blastcannon/Destroy() if(bomb) qdel(bomb) bomb = null - air1 = null - air2 = null - . = ..() + return ..() /obj/item/gun/blastcannon/attack_self(mob/user) if(bomb) @@ -35,7 +31,7 @@ user.visible_message("[user] detaches the [bomb] from the [src]") bomb = null update_icon() - . = ..(user) + return ..() /obj/item/gun/blastcannon/update_icon() if(bomb) @@ -46,7 +42,6 @@ icon_state = initial(icon_state) name = initial(name) desc = initial(desc) - . = ..() /obj/item/gun/blastcannon/attackby(obj/O, mob/user) if(istype(O, /obj/item/device/transfer_valve)) @@ -59,20 +54,17 @@ return FALSE user.visible_message("[user] attaches the [O] to the [src]!") bomb = O - O.loc = src + O.forceMove(src) update_icon() return TRUE - . = ..() + return ..() /obj/item/gun/blastcannon/proc/calculate_bomb() if(!istype(bomb)||!istype(bomb.tank_one)||!istype(bomb.tank_two)) return 0 - air1 = bomb.tank_one.air_contents - air2 = bomb.tank_two.air_contents - var/datum/gas_mixture/temp - temp.volume = air1.volume + air2.volume - temp.merge(air1) - temp.merge(air2) + var/datum/gas_mixture/temp = new(60) //directional buff. + temp.merge(bomb.tank_one.air_contents.remove_ratio(1)) + temp.merge(bomb.tank_two.air_contents.remove_ratio(2)) for(var/i in 1 to 6) temp.react() var/pressure = temp.return_pressure() @@ -82,7 +74,7 @@ return (pressure/TANK_FRAGMENT_SCALE) /obj/item/gun/blastcannon/afterattack(atom/target, mob/user, flag, params) - if((!bomb) || (target == user) || (target.loc == user) || (!target) || (target.loc == user.loc) || (target.loc in range(user, 2)) || (target in range(user, 2))) + if((!bomb) || (!target) || (get_dist(get_turf(target), get_turf(user)) <= 2)) return ..() var/power = calculate_bomb() qdel(bomb) @@ -90,13 +82,17 @@ var/heavy = power * 0.2 var/medium = power * 0.5 var/light = power - user.visible_message("[user] opens \the [bomb] on \his [src.name] and fires a blast wave at \the [target]!","You open \the [bomb] on your [src.name] and fire a blast wave at \the [target]!") + user.visible_message("[user] opens \the [bomb] on \his [name] and fires a blast wave at \the [target]!","You open \the [bomb] on your [name] and fire a blast wave at \the [target]!") playsound(user, "explosion", 100, 1) var/turf/starting = get_turf(user) + var/turf/targturf = get_turf(target) var/area/A = get_area(user) - var/log_str = "Blast wave fired at [ADMIN_COORDJMP(starting)] ([A.name]) by [user.name]([user.ckey]) with power [heavy]/[medium]/[light]." + var/log_str = "Blast wave fired from [ADMIN_COORDJMP(starting)] ([A.name]) at [ADMIN_COORDJMP(targturf)] ([target.name]) by [user.name]([user.ckey]) with power [heavy]/[medium]/[light]." message_admins(log_str) log_game(log_str) + var/obj/item/projectile/blastwave/BW = new(loc, heavy, medium, light) + BW.preparePixelProjectile(target, get_turf(target), user, params, 0) + BW.fire() /obj/item/projectile/blastwave name = "blast wave" @@ -109,6 +105,12 @@ var/lightr = 0 range = 150 +/obj/item/projectile/blastwave/Initialize(mapload, _h, _m, _l) + heavyr = _h + mediumr = _m + lightr = _l + return ..() + /obj/item/projectile/blastwave/Range() ..() if(heavyr) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 3aba80fe64..937326a60b 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -90,8 +90,6 @@ new impact_effect_type(target_loca, target, src) return 0 var/mob/living/L = target - if(L.buckled && ismob(L.buckled)) - L = L.buckled if(blocked != 100) // not completely blocked if(damage && L.blood_volume && damage_type == BRUTE) var/splatter_dir = dir @@ -178,6 +176,8 @@ var/mob/living/picked_mob = pick(mobs_list) if(!prehit(picked_mob)) return FALSE + if(ismob(picked_mob.buckled)) + picked_mob = picked_mob.buckled picked_mob.bullet_act(src, def_zone) qdel(src) return TRUE diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 6f4ae50243..8395ef4d83 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -10,7 +10,7 @@ /obj/item/projectile/bullet/pellet/Range() ..() - damage += -0.75 + damage -= 0.75 if(damage < 0) qdel(src) @@ -66,7 +66,7 @@ /obj/item/projectile/bullet/c38 name = ".38 bullet" damage = 15 - knockdown = 30 + knockdown = 60 stamina = 50 // 10mm (Stechkin) diff --git a/code/modules/server_tools/st_interface.dm b/code/modules/server_tools/st_interface.dm index 12fb5a85c2..10b7f920e8 100644 --- a/code/modules/server_tools/st_interface.dm +++ b/code/modules/server_tools/st_interface.dm @@ -89,6 +89,8 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) return "No message set!" SERVER_TOOLS_WORLD_ANNOUNCE(msg) return "SUCCESS" + if(SERVICE_CMD_PLAYER_COUNT) + return "[SERVER_TOOLS_CLIENT_COUNT]" if(SERVICE_CMD_LIST_CUSTOM) return json_encode(ListServiceCustomCommands(FALSE)) else diff --git a/code/modules/spells/spell_types/shadow_walk.dm b/code/modules/spells/spell_types/shadow_walk.dm index 45ea521098..9f9b4ac223 100644 --- a/code/modules/spells/spell_types/shadow_walk.dm +++ b/code/modules/spells/spell_types/shadow_walk.dm @@ -25,8 +25,9 @@ if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD) playsound(get_turf(user), 'sound/magic/ethereal_enter.ogg', 50, 1, -1) visible_message("[user] melts into the shadows!") - user.AdjustStun(-20, 0) - user.AdjustKnockdown(-20, 0) + user.SetStun(0, FALSE) + user.SetKnockdown(0, FALSE) + user.setStaminaLoss(0, 0) var/obj/effect/dummy/shadow/S2 = new(get_turf(user.loc)) user.forceMove(S2) S2.jaunter = user diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 4b939bf4f1..3b83dd8e62 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -44,9 +44,11 @@ see_in_dark = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE actions_types = list(/datum/action/item_action/organ_action/use) + sight_flags = SEE_BLACKNESS var/night_vision = TRUE /obj/item/organ/eyes/night_vision/ui_action_click() + sight_flags = initial(sight_flags) switch(lighting_alpha) if (LIGHTING_PLANE_ALPHA_VISIBLE) lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE @@ -56,6 +58,7 @@ lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE else lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE + sight_flags &= ~SEE_BLACKNESS owner.update_sight() /obj/item/organ/eyes/night_vision/alien diff --git a/config/config.txt b/config/config.txt index d5d2725714..72f168dcce 100644 --- a/config/config.txt +++ b/config/config.txt @@ -1,3 +1,11 @@ +# You can use the @ character at the beginning of a config option to lock it from being edited in-game +# Example usage: +# @SERVERNAME tgstation +# Which sets the SERVERNAME, and disallows admins from being able to change it using View Variables. +# @LOG_TWITTER 0 +# Which explicitly disables LOG_TWITTER, as well as locking it. +# There are various options which are hard-locked for security reasons. + ## Server name: This appears at the top of the screen in-game and in the BYOND hub. Uncomment and replace 'tgstation' with the name of your choice. # SERVERNAME tgstation diff --git a/html/changelogs/AutoChangeLog-pr-3041.yml b/html/changelogs/AutoChangeLog-pr-3041.yml new file mode 100644 index 0000000000..872bbc4b99 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3041.yml @@ -0,0 +1,5 @@ +author: "Robustin" +delete-after: True +changes: + - rscadd: "Blood cultists can now create a unique bastard sword at their forge" + - rscdel: "Blood cultists can no longer obtain a hardsuit from the forge" diff --git a/html/changelogs/AutoChangeLog-pr-3104.yml b/html/changelogs/AutoChangeLog-pr-3104.yml new file mode 100644 index 0000000000..e6f9d22374 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3104.yml @@ -0,0 +1,4 @@ +author: "More Robust Than You" +delete-after: True +changes: + - balance: "Blobs now take damage from particle accelerators" diff --git a/html/changelogs/AutoChangeLog-pr-3105.yml b/html/changelogs/AutoChangeLog-pr-3105.yml new file mode 100644 index 0000000000..b48644c148 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3105.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - balance: "The detectives gun has been restored from a system change that nerfed knockdown in general. We need to have a serious discussion about anti revolver hate in this community." diff --git a/html/changelogs/AutoChangeLog-pr-3108.yml b/html/changelogs/AutoChangeLog-pr-3108.yml new file mode 100644 index 0000000000..f1e03db19a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3108.yml @@ -0,0 +1,4 @@ +author: "XDTM" +delete-after: True +changes: + - rscadd: "The CMO now has an advanced health analyzer in his closet! It can give more precise readings on the non-standard damage types." diff --git a/html/changelogs/AutoChangeLog-pr-3110.yml b/html/changelogs/AutoChangeLog-pr-3110.yml new file mode 100644 index 0000000000..7d06447f99 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3110.yml @@ -0,0 +1,4 @@ +author: "Kor" +delete-after: True +changes: + - rscadd: "Nightmares now have mutant hearts and brains, with their own special properties when consumed or implanted in mobs. Experiment!" diff --git a/html/changelogs/AutoChangeLog-pr-3114.yml b/html/changelogs/AutoChangeLog-pr-3114.yml new file mode 100644 index 0000000000..abe6380887 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3114.yml @@ -0,0 +1,4 @@ +author: "Daniel0Mclovin" +delete-after: True +changes: + - tweak: "Modify health regeneration from 0.05 to 0.75" diff --git a/html/changelogs/AutoChangeLog-pr-3115.yml b/html/changelogs/AutoChangeLog-pr-3115.yml new file mode 100644 index 0000000000..c3a194f971 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3115.yml @@ -0,0 +1,4 @@ +author: "Naksu" +delete-after: True +changes: + - bugfix: "Gutlunches will now once again look for gibs to eat." diff --git a/html/changelogs/AutoChangeLog-pr-3127.yml b/html/changelogs/AutoChangeLog-pr-3127.yml new file mode 100644 index 0000000000..050e9cb4d7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3127.yml @@ -0,0 +1,4 @@ +author: "Raeschen" +delete-after: True +changes: + - rscadd: "FTL Milky Way added to music" diff --git a/html/changelogs/AutoChangeLog-pr-3133.yml b/html/changelogs/AutoChangeLog-pr-3133.yml new file mode 100644 index 0000000000..ac49ae1821 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3133.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - spellcheck: "Beds, chairs, closets, grilles, lattices, catwalks, tables, racks, floors, plating and bookcases now show hints about constructing/deconstructing them." diff --git a/html/changelogs/AutoChangeLog-pr-3134.yml b/html/changelogs/AutoChangeLog-pr-3134.yml new file mode 100644 index 0000000000..5b8bcf21b6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3134.yml @@ -0,0 +1,4 @@ +author: "ShizCalev" +delete-after: True +changes: + - bugfix: "You now have to unbuckle a player PRIOR to shaking them up off a bed or resin nest." diff --git a/icons/mob/inhands/64x64_lefthand.dmi b/icons/mob/inhands/64x64_lefthand.dmi index a9a952733a..1b450ab3e0 100644 Binary files a/icons/mob/inhands/64x64_lefthand.dmi and b/icons/mob/inhands/64x64_lefthand.dmi differ diff --git a/icons/mob/inhands/64x64_righthand.dmi b/icons/mob/inhands/64x64_righthand.dmi index bff96a991b..bbeddf9152 100644 Binary files a/icons/mob/inhands/64x64_righthand.dmi and b/icons/mob/inhands/64x64_righthand.dmi differ diff --git a/icons/obj/abductor.dmi b/icons/obj/abductor.dmi index 21ab5cf9f5..64a877c2a1 100644 Binary files a/icons/obj/abductor.dmi and b/icons/obj/abductor.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index 79f0a207d4..71ce7d6df5 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi index 94c0c03835..b5ac65c2a8 100644 Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ diff --git a/sound/music/milkyway.ogg b/sound/music/milkyway.ogg new file mode 100644 index 0000000000..59d9ba63f4 Binary files /dev/null and b/sound/music/milkyway.ogg differ diff --git a/sound/weapons/fwoosh.wav b/sound/weapons/fwoosh.wav new file mode 100644 index 0000000000..1723c4e9b8 Binary files /dev/null and b/sound/weapons/fwoosh.wav differ diff --git a/sound/weapons/parry.ogg b/sound/weapons/parry.ogg new file mode 100644 index 0000000000..1f86716337 Binary files /dev/null and b/sound/weapons/parry.ogg differ diff --git a/strings/round_start_sounds.txt b/strings/round_start_sounds.txt index 01323a6120..177f612ee1 100644 --- a/strings/round_start_sounds.txt +++ b/strings/round_start_sounds.txt @@ -20,3 +20,4 @@ sound/music/oceanman.ogg sound/music/indeep.ogg sound/music/goodbyemoonmen.ogg sound/music/flytothemoon_otomatone.ogg +sound/music/milkyway.ogg \ No newline at end of file