diff --git a/baystation12.dme b/baystation12.dme index 34471cc192f..a5526a8f53e 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1249,6 +1249,7 @@ #include "code\modules\surgery\eye.dm" #include "code\modules\surgery\face.dm" #include "code\modules\surgery\generic.dm" +#include "code\modules\surgery\headreattach.dm" #include "code\modules\surgery\implant.dm" #include "code\modules\surgery\other.dm" #include "code\modules\surgery\ribcage.dm" diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index b5b6cf74233..c9dfd7cf403 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -62,6 +62,9 @@ var/automute_on = 0 //enables automuting/spam prevention var/jobs_have_minimal_access = 0 //determines whether jobs use minimal access or expanded access. + var/cult_ghostwriter = 1 //Allows ghosts to write in blood in cult rounds... + var/cult_ghostwriter_req_cultists = 10 //...so long as this many cultists are active. + var/disable_player_mice = 0 var/uneducated_mice = 0 //Set to 1 to prevent newly-spawned mice from understanding human speech @@ -455,10 +458,15 @@ else //probably windows, if not this should work anyway config.python_path = "python" + if("allow_cult_ghostwriter") + config.cult_ghostwriter = 1 + + if("req_cult_ghostwriter") + config.cult_ghostwriter_req_cultists = value + else diary << "Unknown setting in configuration: '[name]'" - else if(type == "game_options") if(!value) diary << "Unknown value for setting [name] in [filename]." diff --git a/code/game/gamemodes/blob/blobs/shield.dm b/code/game/gamemodes/blob/blobs/shield.dm index 4c77520846a..0e1b6c07eb4 100644 --- a/code/game/gamemodes/blob/blobs/shield.dm +++ b/code/game/gamemodes/blob/blobs/shield.dm @@ -6,7 +6,7 @@ density = 1 opacity = 0 anchored = 1 - health = 100 + health = 60 brute_resist = 1 fire_resist = 2 diff --git a/code/game/gamemodes/events/holidays/Christmas.dm b/code/game/gamemodes/events/holidays/Christmas.dm index 2ee79e7c65b..72d42318e60 100644 --- a/code/game/gamemodes/events/holidays/Christmas.dm +++ b/code/game/gamemodes/events/holidays/Christmas.dm @@ -4,8 +4,8 @@ for(var/turf/simulated/floor/T in orange(1,xmas)) for(var/i=1,i<=rand(1,5),i++) new /obj/item/weapon/a_gift(T) - for(var/mob/living/simple_animal/corgi/Ian/Ian in mob_list) - Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian)) + //for(var/mob/living/simple_animal/corgi/Ian/Ian in mob_list) + // Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian)) /proc/ChristmasEvent() for(var/obj/structure/flora/tree/pine/xmas in world) diff --git a/code/game/gamemodes/events/power_failure.dm b/code/game/gamemodes/events/power_failure.dm index c8848cd3ee8..dbebc649f53 100644 --- a/code/game/gamemodes/events/power_failure.dm +++ b/code/game/gamemodes/events/power_failure.dm @@ -61,7 +61,7 @@ if(C.cell && C.z == 1) C.cell.charge = C.cell.maxcharge for(var/obj/machinery/power/smes/S in world) - if(S.z != 1) + if(istype(get_area(S), /area/turret_protected) || S.z != 1) continue S.charge = S.last_charge S.output = S.last_output diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index 24a3df847a5..a58e8b553ff 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -82,6 +82,10 @@ var/bomb_set flick("nuclearbombc", src) return + if (istype(O, /obj/item/weapon/wirecutters) || istype(O, /obj/item/device/multitool)) + if (src.opened == 1) + nukehack_win(user) + return if (src.extended) if (istype(O, /obj/item/weapon/disk/nuclear)) diff --git a/code/game/machinery/bots/cleanbot.dm b/code/game/machinery/bots/cleanbot.dm index 88b785b5c0d..e0a74e97223 100644 --- a/code/game/machinery/bots/cleanbot.dm +++ b/code/game/machinery/bots/cleanbot.dm @@ -194,7 +194,7 @@ text("[src.oddbutton ? "Yes" : "No" if(!src.target || src.target == null) for (var/obj/effect/decal/cleanable/D in view(7,src)) for(var/T in src.target_types) - if(!(D in cleanbottargets) && (D.type == T || D.parent_type == T) && D != src.oldtarget) + if(!(D in cleanbottargets) && istype(D,T) && D != src.oldtarget) src.oldtarget = D src.target = D return @@ -293,17 +293,12 @@ text("[src.oddbutton ? "Yes" : "No" /obj/machinery/bot/cleanbot/proc/get_targets() src.target_types = new/list() - target_types += /obj/effect/decal/cleanable/blood/oil + target_types += /obj/effect/decal/cleanable/blood target_types += /obj/effect/decal/cleanable/vomit - target_types += /obj/effect/decal/cleanable/blood/robot target_types += /obj/effect/decal/cleanable/crayon target_types += /obj/effect/decal/cleanable/liquid_fuel target_types += /obj/effect/decal/cleanable/mucus - - if(src.blood) - target_types += /obj/effect/decal/cleanable/blood/ - target_types += /obj/effect/decal/cleanable/blood/gibs/ - target_types += /obj/effect/decal/cleanable/dirt + target_types += /obj/effect/decal/cleanable/dirt /obj/machinery/bot/cleanbot/proc/clean(var/obj/effect/decal/cleanable/target) src.anchored = 1 diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index d7bb61c0be4..62e7376c4d4 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -52,6 +52,8 @@ var/const/WIRE_SHOCK = 3 var/const/WIRE_SHOOTINV = 4 + var/check_accounts = 0 // 1 = requires PIN and checks accounts. 0 = You slide an ID, it vends, SPACE COMMUNISM! + /obj/machinery/vending/New() ..() spawn(4) @@ -164,46 +166,51 @@ if (istype(I, /obj/item/weapon/card/id)) var/obj/item/weapon/card/id/C = I visible_message("[usr] swipes a card through [src].") - if(vendor_account) - var/attempt_pin = input("Enter pin code", "Vendor transaction") as num - var/datum/money_account/D = attempt_account_access(C.associated_account_number, attempt_pin, 2) - if(D) - var/transaction_amount = currently_vending.price - if(transaction_amount <= D.money) + if(check_accounts) + if(vendor_account) + var/attempt_pin = input("Enter pin code", "Vendor transaction") as num + var/datum/money_account/D = attempt_account_access(C.associated_account_number, attempt_pin, 2) + if(D) + var/transaction_amount = currently_vending.price + if(transaction_amount <= D.money) + + //transfer the money + D.money -= transaction_amount + vendor_account.money += transaction_amount - //transfer the money - D.money -= transaction_amount - vendor_account.money += transaction_amount - - //create entries in the two account transaction logs - var/datum/transaction/T = new() - T.target_name = "[vendor_account.owner_name] (via [src.name])" - T.purpose = "Purchase of [currently_vending.product_name]" - if(transaction_amount > 0) - T.amount = "([transaction_amount])" - else + //create entries in the two account transaction logs + var/datum/transaction/T = new() + T.target_name = "[vendor_account.owner_name] (via [src.name])" + T.purpose = "Purchase of [currently_vending.product_name]" + if(transaction_amount > 0) + T.amount = "([transaction_amount])" + else + T.amount = "[transaction_amount]" + T.source_terminal = src.name + T.date = current_date_string + T.time = worldtime2text() + D.transaction_log.Add(T) + // + T = new() + T.target_name = D.owner_name + T.purpose = "Purchase of [currently_vending.product_name]" T.amount = "[transaction_amount]" - T.source_terminal = src.name - T.date = current_date_string - T.time = worldtime2text() - D.transaction_log.Add(T) - // - T = new() - T.target_name = D.owner_name - T.purpose = "Purchase of [currently_vending.product_name]" - T.amount = "[transaction_amount]" - T.source_terminal = src.name - T.date = current_date_string - T.time = worldtime2text() - vendor_account.transaction_log.Add(T) + T.source_terminal = src.name + T.date = current_date_string + T.time = worldtime2text() + vendor_account.transaction_log.Add(T) - // Vend the item - src.vend(src.currently_vending, usr) - currently_vending = null + // Vend the item + src.vend(src.currently_vending, usr) + currently_vending = null + else + usr << "\icon[src]You don't have that much money!" else - usr << "\icon[src]You don't have that much money!" + usr << "\icon[src]Unable to access account. Check security settings and try again." else - usr << "\icon[src]Unable to access account. Check security settings and try again." + //Just Vend it. + src.vend(src.currently_vending, usr) + currently_vending = null else usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call CentComm Support." diff --git a/code/game/objects/effects/decals/Cleanable/aliens.dm b/code/game/objects/effects/decals/Cleanable/aliens.dm index 00044afb58e..957369f3bf6 100644 --- a/code/game/objects/effects/decals/Cleanable/aliens.dm +++ b/code/game/objects/effects/decals/Cleanable/aliens.dm @@ -1,53 +1,30 @@ -// Note: BYOND is object oriented. There is no reason for this to be copy/pasted blood code. - /obj/effect/decal/cleanable/blood/xeno name = "xeno blood" desc = "It's green and acidic. It looks like... blood?" icon = 'icons/effects/blood.dmi' - icon_state = "xfloor1" basecolor = "#05EE05" - random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7") -/obj/effect/decal/cleanable/blood/xeno/proc/streak(var/list/directions) - spawn (0) - var/direction = pick(directions) - for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++) - sleep(3) - if (i > 0) - var/obj/effect/decal/cleanable/blood/xeno/b = new /obj/effect/decal/cleanable/blood/xeno/xsplatter(src.loc) - for(var/datum/disease/D in src.viruses) - var/datum/disease/ND = D.Copy(1) - b.viruses += ND - ND.holder = b - if (step_to(src, get_step(src, direction), 0)) - break - -/obj/effect/decal/cleanable/blood/xeno/xsplatter - random_icon_states = list("xgibbl1", "xgibbl2", "xgibbl3", "xgibbl4", "xgibbl5") - -/obj/effect/decal/cleanable/blood/xeno/xgibs +/obj/effect/decal/cleanable/blood/gibs/xeno name = "xeno gibs" desc = "Gnarly..." - gender = PLURAL - icon = 'icons/effects/blood.dmi' icon_state = "xgib1" random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6") + basecolor = "#05EE05" -/obj/effect/decal/cleanable/blood/xeno/xgibs/up +/obj/effect/decal/cleanable/blood/gibs/xeno/up random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6","xgibup1","xgibup1","xgibup1") -/obj/effect/decal/cleanable/blood/xeno/xgibs/down +/obj/effect/decal/cleanable/blood/gibs/xeno/down random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6","xgibdown1","xgibdown1","xgibdown1") -/obj/effect/decal/cleanable/blood/xeno/xgibs/body +/obj/effect/decal/cleanable/blood/gibs/xeno/body random_icon_states = list("xgibhead", "xgibtorso") -/obj/effect/decal/cleanable/blood/xeno/xgibs/limb +/obj/effect/decal/cleanable/blood/gibs/xeno/limb random_icon_states = list("xgibleg", "xgibarm") -/obj/effect/decal/cleanable/blood/xeno/xgibs/core +/obj/effect/decal/cleanable/blood/gibs/xeno/core random_icon_states = list("xgibmid1", "xgibmid2", "xgibmid3") /obj/effect/decal/cleanable/blood/xtracks - icon_state = "xtracks" - random_icon_states = null \ No newline at end of file + basecolor = "#05EE05" \ No newline at end of file diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index c73291bc214..f971cb45c66 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -25,7 +25,7 @@ var/global/list/image/splatter_cache=list() /obj/effect/decal/cleanable/blood/New() ..() - color = basecolor + update_icon() if(istype(src, /obj/effect/decal/cleanable/blood/gibs)) return if(istype(src, /obj/effect/decal/cleanable/blood/tracks)) @@ -116,13 +116,16 @@ var/global/list/image/splatter_cache=list() /obj/effect/decal/cleanable/blood/writing/New() ..() - for(var/obj/effect/decal/cleanable/blood/writing/W in loc) - random_icon_states.Remove(W.icon_state) - icon_state = pick(random_icon_states) + if(random_icon_states.len) + for(var/obj/effect/decal/cleanable/blood/writing/W in loc) + random_icon_states.Remove(W.icon_state) + icon_state = pick(random_icon_states) + else + icon_state = "writing1" /obj/effect/decal/cleanable/blood/writing/examine() ..() - usr << "It reads: \"[message]\"" + usr << "It reads: \"[message]\"" /obj/effect/decal/cleanable/blood/gibs name = "gibs" @@ -135,6 +138,12 @@ var/global/list/image/splatter_cache=list() icon_state = "gibbl5" random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6") +/obj/effect/decal/cleanable/blood/gibs/update_icon() + color = "#FFFFFF" + //overlays.Cut() + //..() + //overlays += image(icon, src, "[icon_state]_flesh") + /obj/effect/decal/cleanable/blood/gibs/up random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1") @@ -159,6 +168,7 @@ var/global/list/image/splatter_cache=list() if (i > 0) var/obj/effect/decal/cleanable/blood/b = new /obj/effect/decal/cleanable/blood/splatter(src.loc) b.basecolor = src.basecolor + b.update_icon() for(var/datum/disease/D in src.viruses) var/datum/disease/ND = D.Copy(1) b.viruses += ND diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm index 67c82a8f440..0b257a3e111 100644 --- a/code/game/objects/effects/decals/Cleanable/misc.dm +++ b/code/game/objects/effects/decals/Cleanable/misc.dm @@ -16,6 +16,13 @@ icon_state = "ash" anchored = 1 +/obj/effect/decal/cleanable/ash/attack_hand(mob/user as mob) + user << "[src] sifts through your fingers." + var/turf/simulated/floor/F = get_turf(src) + if (istype(F)) + F.dirt += 4 + del(src) + /obj/effect/decal/cleanable/greenglow New() diff --git a/code/game/objects/effects/decals/Cleanable/robots.dm b/code/game/objects/effects/decals/Cleanable/robots.dm index f76f4863b6b..43a6c1954eb 100644 --- a/code/game/objects/effects/decals/Cleanable/robots.dm +++ b/code/game/objects/effects/decals/Cleanable/robots.dm @@ -1,29 +1,23 @@ -// Note: BYOND is object oriented. There is no reason for this to be copy/pasted blood code. - -/obj/effect/decal/cleanable/blood/robot +/obj/effect/decal/cleanable/blood/gibs/robot name = "robot debris" desc = "It's a useless heap of junk... or is it?" icon = 'icons/mob/robots.dmi' icon_state = "gib1" - basecolor="#2B2B2B" + basecolor="#030303" random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7") -/obj/effect/decal/cleanable/blood/robot/dry() //pieces of robots do not dry up like +/obj/effect/decal/cleanable/blood/gibs/robot/dry() //pieces of robots do not dry up like return -/obj/effect/decal/cleanable/blood/robot/update_icon() - color = "#FFFFFF" - return - -/obj/effect/decal/cleanable/blood/robot/proc/streak(var/list/directions) +/obj/effect/decal/cleanable/blood/gibs/robot/streak(var/list/directions) spawn (0) var/direction = pick(directions) for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++) sleep(3) if (i > 0) if (prob(40)) - /*var/obj/effect/decal/cleanable/oil/o =*/ - new /obj/effect/decal/cleanable/blood/oil/streak(src.loc) + var/obj/effect/decal/cleanable/blood/oil/streak = new(src.loc) + streak.update_icon() else if (prob(10)) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) @@ -31,22 +25,23 @@ if (step_to(src, get_step(src, direction), 0)) break -/obj/effect/decal/cleanable/blood/robot/limb +/obj/effect/decal/cleanable/blood/gibs/robot/limb random_icon_states = list("gibarm", "gibleg") -/obj/effect/decal/cleanable/blood/robot/up +/obj/effect/decal/cleanable/blood/gibs/robot/up random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7","gibup1","gibup1") //2:7 is close enough to 1:4 -/obj/effect/decal/cleanable/blood/robot/down +/obj/effect/decal/cleanable/blood/gibs/robot/down random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7","gibdown1","gibdown1") //2:7 is close enough to 1:4 /obj/effect/decal/cleanable/blood/oil name = "motor oil" desc = "It's black and greasy. Looks like Beepsky made another mess." - basecolor="#3B3B3B" - icon = 'icons/mob/robots.dmi' - icon_state = "floor1" - random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7") + basecolor="#030303" + +/obj/effect/decal/cleanable/blood/oil/dry() + return /obj/effect/decal/cleanable/blood/oil/streak - random_icon_states = list("streak1", "streak2", "streak3", "streak4", "streak5") \ No newline at end of file + random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5") + amount = 2 \ No newline at end of file diff --git a/code/game/objects/effects/spawners/gibspawner.dm b/code/game/objects/effects/spawners/gibspawner.dm index 70ddaed1d3d..5446ba348e6 100644 --- a/code/game/objects/effects/spawners/gibspawner.dm +++ b/code/game/objects/effects/spawners/gibspawner.dm @@ -17,7 +17,7 @@ ..() xeno - gibtypes = list(/obj/effect/decal/cleanable/blood/xeno/xgibs/up,/obj/effect/decal/cleanable/blood/xeno/xgibs/down,/obj/effect/decal/cleanable/blood/xeno/xgibs,/obj/effect/decal/cleanable/blood/xeno/xgibs,/obj/effect/decal/cleanable/blood/xeno/xgibs/body,/obj/effect/decal/cleanable/blood/xeno/xgibs/limb,/obj/effect/decal/cleanable/blood/xeno/xgibs/core) + gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno/up,/obj/effect/decal/cleanable/blood/gibs/xeno/down,/obj/effect/decal/cleanable/blood/gibs/xeno,/obj/effect/decal/cleanable/blood/gibs/xeno,/obj/effect/decal/cleanable/blood/gibs/xeno/body,/obj/effect/decal/cleanable/blood/gibs/xeno/limb,/obj/effect/decal/cleanable/blood/gibs/xeno/core) gibamounts = list(1,1,1,1,1,1,1) New() @@ -27,7 +27,7 @@ robot sparks = 1 - gibtypes = list(/obj/effect/decal/cleanable/blood/robot/up,/obj/effect/decal/cleanable/blood/robot/down,/obj/effect/decal/cleanable/blood/robot,/obj/effect/decal/cleanable/blood/robot,/obj/effect/decal/cleanable/blood/robot,/obj/effect/decal/cleanable/blood/robot/limb) + gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/robot/up,/obj/effect/decal/cleanable/blood/gibs/robot/down,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot/limb) gibamounts = list(1,1,1,1,1,1) New() diff --git a/code/game/objects/items/devices/uplinks.dm b/code/game/objects/items/devices/uplinks.dm index e04ab62671e..4e42765238d 100644 --- a/code/game/objects/items/devices/uplinks.dm +++ b/code/game/objects/items/devices/uplinks.dm @@ -7,8 +7,10 @@ A list of items and costs is stored under the datum of every game mode, alongsid */ /obj/item/device/uplink + var/welcome // Welcoming menu message var/items // List of items + var/valid_items = list() var/item_data // raw item text var/list/ItemList // Parsed list of items var/uses // Numbers of crystals @@ -58,6 +60,12 @@ A list of items and costs is stored under the datum of every game mode, alongsid + //Halfassed fix for href exploit ~Z + for(var/D in ItemList) + var/list/O = stringsplit(D, ":") + if(O.len>0) + valid_items += O[1] + //Let's build a menu! /obj/item/device/uplink/proc/generate_menu() @@ -87,7 +95,7 @@ A list of items and costs is stored under the datum of every game mode, alongsid continue path_text = O[1] - cost = text2num(O[2]) + cost = Clamp(text2num(O[2]),1,20) //Another halfassed fix for href exploit ~Z if(cost>uses) continue @@ -378,7 +386,12 @@ A list of items and costs is stored under the datum of every game mode, alongsid return 1 if(..(href, href_list) == 1) + + if(!(href_list["buy_item"] in valid_items)) + return + var/path_obj = text2path(href_list["buy_item"]) + var/obj/I = new path_obj(get_turf(usr)) if(ishuman(usr)) var/mob/living/carbon/human/A = usr @@ -427,6 +440,3 @@ A list of items and costs is stored under the datum of every game mode, alongsid ..() hidden_uplink = new(src) hidden_uplink.uses = 10 - - - diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 884b0671eed..98efacef1a3 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -65,6 +65,7 @@ var/list/admin_verbs_admin = list( /client/proc/cmd_admin_rejuvenate, /client/proc/toggleattacklogs, /client/proc/toggledebuglogs, + /client/proc/toggleghostwriters, /datum/admins/proc/show_skills, /client/proc/check_customitem_activity, /client/proc/man_up, @@ -724,6 +725,21 @@ var/list/admin_verbs_mod = list( usr << "You now won't get attack log messages" +/client/proc/toggleghostwriters() + set name = "Toggle ghost writers" + set category = "Server" + if(!holder) return + if(config) + if(config.cult_ghostwriter) + config.cult_ghostwriter = 0 + src << "Disallowed ghost writers." + message_admins("Admin [key_name_admin(usr)] has disabled ghost writers.", 1) + else + config.cult_ghostwriter = 1 + src << "Enabled ghost writers." + message_admins("Admin [key_name_admin(usr)] has enabled ghost writers.", 1) + + /client/proc/toggledebuglogs() set name = "Toggle Debug Log Messages" set category = "Preferences" diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 1b55ca6b039..87ed4787058 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -479,7 +479,6 @@ dat += "Show Objective" dat += "" - /* if(ticker.mode.ninjas.len > 0) dat += "
" for(var/datum/mind/ninja in ticker.mode.ninjas) @@ -491,7 +490,6 @@ else dat += "" dat += "
Ninjas
Ninja not found!
" - */ if(ticker.mode.cult.len) dat += "
" diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 153451431c7..304e96b0fad 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1122,6 +1122,8 @@ datum/preferences UI_style = "Orange" if("Orange") UI_style = "old" + if("old") + UI_style = "White" else UI_style = "Midnight" diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index b61c1224794..9627c55d824 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -21,6 +21,7 @@ var/antagHUD = 0 universal_speak = 1 var/atom/movable/following = null + /mob/dead/observer/New(mob/body) sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF see_invisible = SEE_INVISIBLE_OBSERVER @@ -496,3 +497,79 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp dat += data_core.get_manifest() src << browse(dat, "window=manifest;size=370x420;can_close=1") + +//Used for drawing on walls with blood puddles as a spooky ghost. +/mob/dead/verb/bloody_doodle() + + set category = "Ghost" + set name = "Write in blood" + set desc = "If the round is sufficiently spooky, write a short message in blood on the floor or a wall. Remember, no IC in OOC or OOC in IC." + + if(!(config.cult_ghostwriter)) + src << "\red That verb is not currently permitted." + return + + if (!src.stat) + return + + if (usr != src) + return 0 //something is terribly wrong + + var/ghosts_can_write + if(ticker.mode.name == "cult") + var/datum/game_mode/cult/C = ticker.mode + if(C.cult.len > config.cult_ghostwriter_req_cultists) + ghosts_can_write = 1 + + if(!ghosts_can_write) + src << "\red The veil is not thin enough for you to do that." + return + + var/list/choices = list() + for(var/obj/effect/decal/cleanable/blood/B in view(1,src)) + if(B.amount > 0) + choices += B + + if(!choices.len) + src << "There is no blood to use nearby." + return + + var/obj/effect/decal/cleanable/blood/choice = input(src,"What blood would you like to use?") in null|choices + + var/direction = input(src,"Which way?","Tile selection") as anything in list("Here","North","South","East","West") + var/turf/simulated/T = src.loc + if (direction != "Here") + T = get_step(T,text2dir(direction)) + + if (!istype(T)) + src << "You cannot doodle there." + return + + if(!choice || choice.amount == 0 || !(src.Adjacent(choice))) + return + + var/doodle_color = (choice.basecolor) ? choice.basecolor : "#A10808" + + var/num_doodles = 0 + for (var/obj/effect/decal/cleanable/blood/writing/W in T) + num_doodles++ + if (num_doodles > 4) + src << "There is no space to write on!" + return + + var/max_length = 50 + + var/message = stripped_input(src,"Write a message. It cannot be longer than [max_length] characters.","Blood writing", "") + + if (message) + + if (length(message) > max_length) + message += "-" + src << "You ran out of blood to write with!" + + var/obj/effect/decal/cleanable/blood/writing/W = new(T) + W.basecolor = doodle_color + W.update_icon() + W.message = message + W.add_hiddenprint(src) + W.visible_message("\red Invisible fingers crudely paint something in blood on [T]...") \ 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 546a9231456..6063f544d62 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -520,7 +520,7 @@ proc/get_damage_icon_part(damage_state, body_part) else if(blood_DNA) var/image/bloodsies = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands") - bloodsies.color = blood_color + bloodsies.color = hand_blood_color overlays_standing[GLOVES_LAYER] = bloodsies else overlays_standing[GLOVES_LAYER] = null diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index 0141d9c5c1a..8c98daaa872 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -22,6 +22,7 @@ var/obj/item/inventory_back var/facehugger +/* /mob/living/simple_animal/corgi/Life() ..() regenerate_icons() @@ -253,6 +254,7 @@ if(/obj/item/clothing/head/soft) name = "Corgi Tech [real_name]" desc = "The reason your yellow gloves have chew-marks." +*/ //IAN! SQUEEEEEEEEE~ diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index 6fd7db5d10e..b375755f546 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -79,7 +79,7 @@ if(stance_step in list(1,4,7)) //every 3 ticks var/action = pick( list( "growls at [target_mob]", "stares angrily at [target_mob]", "prepares to attack [target_mob]", "closely watches [target_mob]" ) ) if(action) - emote(action) + custom_emote(1,action) if(!found_mob) stance_step-- @@ -90,7 +90,7 @@ if(HOSTILE_STANCE_ATTACKING) if(stance_step >= 20) //attacks for 20 ticks, then it gets tired and needs to rest - emote( "is worn out and needs to rest" ) + custom_emote(1, "is worn out and needs to rest" ) stance = HOSTILE_STANCE_TIRED stance_step = 0 walk(src, 0) //This stops the bear's walking @@ -118,14 +118,16 @@ /mob/living/simple_animal/hostile/bear/FindTarget() . = ..() if(.) - emote("stares alertly at [.]") + custom_emote(1,"stares alertly at [.]") stance = HOSTILE_STANCE_ALERT /mob/living/simple_animal/hostile/bear/LoseTarget() ..(5) /mob/living/simple_animal/hostile/bear/AttackingTarget() - emote( pick( list("slashes at [target_mob]", "bites [target_mob]") ) ) + if(!Adjacent(target_mob)) + return + custom_emote(1, pick( list("slashes at [target_mob]", "bites [target_mob]") ) ) var/damage = rand(20,30) diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm index 353ca6156f3..f1a5c15c4b9 100644 --- a/code/modules/mob/living/simple_animal/hostile/carp.dm +++ b/code/modules/mob/living/simple_animal/hostile/carp.dm @@ -44,7 +44,7 @@ /mob/living/simple_animal/hostile/carp/FindTarget() . = ..() if(.) - emote("nashes at [.]") + custom_emote(1,"nashes at [.]") /mob/living/simple_animal/hostile/carp/AttackingTarget() . =..() diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm index 88aa24d29e2..cdefaa644e7 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm @@ -47,7 +47,7 @@ /mob/living/simple_animal/hostile/hivebot/Die() ..() visible_message("[src] blows apart!") - new /obj/effect/decal/cleanable/blood/robot(src.loc) + new /obj/effect/decal/cleanable/blood/gibs/robot(src.loc) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(3, 1, src) s.start() diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 403c31b17f2..2dcbe0d949f 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -87,6 +87,8 @@ return 1 /mob/living/simple_animal/hostile/proc/AttackingTarget() + if(!Adjacent(target_mob)) + return if(isliving(target_mob)) var/mob/living/L = target_mob L.attack_animal(src) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index bb3bbcdb3dc..560590cbad0 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -218,6 +218,7 @@ if (istype(user, /mob/living/silicon) && get_dist(src,user)>1) return src.attack_hand(user) + src.add_fingerprint(user) if (istype(W, /obj/item/weapon/crowbar) && opened) if (has_electronics==1) if (terminal) diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index 685122e05c5..18be233b9b9 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -51,6 +51,9 @@ if(istype(A, /obj/item/ammo_magazine)) if((load_method == MAGAZINE) && loaded.len) return var/obj/item/ammo_magazine/AM = A + if(AM.stored_ammo.len <= 0) + user << "The magazine is empty!" + return for(var/obj/item/ammo_casing/AC in AM.stored_ammo) if(loaded.len >= max_shells) break @@ -93,6 +96,7 @@ AM.loc = get_turf(src) empty_mag = null update_icon() + AM.update_icon() user << "\blue You unload magazine from \the [src]!" else user << "\red Nothing loaded in \the [src]!" diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 0b3145cb9a5..07bf9bd0f6c 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -89,6 +89,7 @@ if(!loaded.len && empty_mag) empty_mag.loc = get_turf(src.loc) empty_mag = null + user << "The Magazine falls out and clatters on the floor!" return diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm index 96e037a23a6..17f8d1ce11e 100644 --- a/code/modules/reagents/reagent_containers/dropper.dm +++ b/code/modules/reagents/reagent_containers/dropper.dm @@ -12,7 +12,7 @@ var/filled = 0 afterattack(obj/target, mob/user , flag) - if(!target.reagents) return + if(!target.reagents || !flag) return if(filled) @@ -105,4 +105,4 @@ //////////////////////////////////////////////////////////////////////////////// /// Droppers. END -//////////////////////////////////////////////////////////////////////////////// \ No newline at end of file +//////////////////////////////////////////////////////////////////////////////// diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 3a0a200efa2..04eff0de6ea 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -1325,7 +1325,7 @@ src.streak(dirs) -/obj/effect/decal/cleanable/blood/robot/gib/pipe_eject(var/direction) +/obj/effect/decal/cleanable/blood/gibs/robot/pipe_eject(var/direction) var/list/dirs if(direction) dirs = list( direction, turn(direction, -45), turn(direction, 45)) diff --git a/config/example/config.txt b/config/example/config.txt index fb320da581a..1075a5ab677 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -229,3 +229,9 @@ USEALIENWHITELIST ## Path to the python2 executable on the system. Leave blank for default. ## Default is "python" on Windows, "/usr/bin/env python2" on UNIX. #PYTHON_PATH + +## Uncommen to allow ghosts to write in blood during Cult rounds. +ALLOW_CULT_GHOSTWRITER + +## Sets the minimum number of cultists needed for ghosts to write in blood. +REQ_CULT_GHOSTWRITER 6 \ No newline at end of file diff --git a/icons/effects/blood.dmi b/icons/effects/blood.dmi index 74ee727581e..6f634b9447b 100644 Binary files a/icons/effects/blood.dmi and b/icons/effects/blood.dmi differ diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index 84aa670c5a1..05f5f846a73 100644 Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ diff --git a/maps/tgstation2.dmm b/maps/tgstation2.dmm index d8655a8517a..5b0ab4a0118 100644 --- a/maps/tgstation2.dmm +++ b/maps/tgstation2.dmm @@ -935,7 +935,7 @@ "arY" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold{pipe_color = "red"; dir = 1; icon_state = "manifold-r-f"; level = 1; name = "pipe manifold"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fsmaint) "arZ" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/fsmaint) "asa" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/fsmaint) -"asb" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/effect/decal/cleanable/blood/robot,/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/maintenance/fsmaint) +"asb" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/obj/effect/decal/cleanable/blood/gibs/robot,/obj/machinery/space_heater,/turf/simulated/floor/plating,/area/maintenance/fsmaint) "asc" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 10},/turf/simulated/wall,/area/maintenance/fsmaint) "asd" = (/obj/structure/rack{dir = 1},/obj/item/clothing/suit/fire/firefighter,/obj/item/weapon/tank/oxygen,/obj/item/clothing/mask/gas,/obj/item/weapon/extinguisher,/obj/item/clothing/head/hardhat/red,/obj/item/clothing/glasses/meson,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/maintenance/fsmaint) "ase" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 6},/area/maintenance/fsmaint)
Cultists