diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_fountain_hall.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_fountain_hall.dmm
index b367a068f15..918b0e894b7 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_fountain_hall.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_fountain_hall.dmm
@@ -8,19 +8,19 @@
},
/area/ruin/unpowered)
"c" = (
-/obj/structure/divine/healingfountain/anyone,
+/obj/structure/healingfountain,
/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/lava/smooth
},
/area/ruin/unpowered)
"d" = (
-/obj/structure/divine/conduit,
+/obj/structure/fluff/divine/conduit,
/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/lava/smooth
},
/area/ruin/unpowered)
"e" = (
-/obj/structure/divine/sacrificealtar,
+/obj/structure/sacrificealtar,
/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/lava/smooth
},
diff --git a/_maps/RandomZLevels/Academy.dmm b/_maps/RandomZLevels/Academy.dmm
index 4577417fc7b..260a66f8642 100644
--- a/_maps/RandomZLevels/Academy.dmm
+++ b/_maps/RandomZLevels/Academy.dmm
@@ -852,7 +852,7 @@
/turf/closed/wall,
/area/awaymission/academy/headmaster)
"cI" = (
-/obj/structure/divine/trap/damage,
+/obj/structure/trap/damage,
/turf/open/floor/carpet,
/area/awaymission/academy/headmaster)
"cJ" = (
@@ -3881,11 +3881,11 @@
d2 = 4;
icon_state = "2-4"
},
-/obj/structure/divine/trap/chill,
+/obj/structure/trap/chill,
/turf/open/floor/plating,
/area/awaymission/academy/academyaft)
"kN" = (
-/obj/structure/divine/trap/fire,
+/obj/structure/trap/fire,
/turf/open/floor/engine,
/area/awaymission/academy/academyaft)
"kO" = (
@@ -3946,7 +3946,7 @@
/turf/open/floor/engine/cult,
/area/awaymission/academy/academycellar)
"la" = (
-/obj/structure/divine/trap/damage,
+/obj/structure/trap/damage,
/turf/open/floor/engine/cult,
/area/awaymission/academy/academycellar)
"lb" = (
diff --git a/_maps/RandomZLevels/caves.dmm b/_maps/RandomZLevels/caves.dmm
index 839dee842a4..dea105695ea 100644
--- a/_maps/RandomZLevels/caves.dmm
+++ b/_maps/RandomZLevels/caves.dmm
@@ -167,7 +167,7 @@
name = "\improper BMP Asteroid Level 4"
})
"av" = (
-/obj/structure/divine/trap/stun{
+/obj/structure/trap/stun{
desc = "A rune inscribed in the floor, the air feeling electrified around it.";
name = "shock rune"
},
@@ -474,7 +474,7 @@
name = "\improper BMP Asteroid Level 3"
})
"aY" = (
-/obj/structure/divine/trap/fire{
+/obj/structure/trap/fire{
desc = "An old rune inscribed on the floor, giving off an intense amount of heat.";
name = "flame rune"
},
@@ -485,7 +485,7 @@
name = "\improper BMP Asteroid Level 4"
})
"aZ" = (
-/obj/structure/divine/trap/fire{
+/obj/structure/trap/fire{
desc = "An old rune inscribed on the floor, giving off an intense amount of heat.";
name = "flame rune"
},
@@ -672,7 +672,7 @@
name = "\improper BMP Asteroid Level 4"
})
"bs" = (
-/obj/structure/divine/trap/stun{
+/obj/structure/trap/stun{
desc = "A rune inscribed in the floor, the air feeling electrified around it.";
name = "shock rune"
},
diff --git a/_maps/RandomZLevels/research.dmm b/_maps/RandomZLevels/research.dmm
index d66f49ddb40..3f56227c366 100644
--- a/_maps/RandomZLevels/research.dmm
+++ b/_maps/RandomZLevels/research.dmm
@@ -4907,7 +4907,7 @@
/turf/open/floor/mineral/plasma,
/area/space)
"nd" = (
-/obj/structure/divine/healingfountain/anyone,
+/obj/structure/healingfountain,
/turf/open/floor/mineral/plasma,
/area/space)
"ne" = (
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index ae44b7d3bde..073f251c330 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -62703,6 +62703,8 @@
network = list("SS13","Medbay")
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
+/obj/machinery/limbgrower,
+/obj/item/weapon/reagent_containers/glass/beaker/synthflesh,
/turf/open/floor/plasteel/whiteblue/side{
dir = 4
},
diff --git a/_maps/map_files/MiniStation/cargopacks.dm b/_maps/map_files/MiniStation/cargopacks.dm
index a6a1db75df3..097711e7f43 100644
--- a/_maps/map_files/MiniStation/cargopacks.dm
+++ b/_maps/map_files/MiniStation/cargopacks.dm
@@ -1,31 +1,3 @@
-/datum/supply_pack/engineering/oxygen
- name = "Oxygen Canister"
- cost = 15
- contains = list(/obj/machinery/portable_atmospherics/canister/oxygen)
- crate_name = "oxygen canister crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/engineering/toxins
- name = "Plasma Canister"
- cost = 30
- contains = list(/obj/machinery/portable_atmospherics/canister/toxins)
- crate_name = "plasma canister crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/engineering/nitrogen
- name = "Nitrogen Canister"
- cost = 20
- contains = list(/obj/machinery/portable_atmospherics/canister/nitrogen)
- crate_name = "nitrogen canister crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/engineering/carbon_dio
- name = "Carbon Dioxide Canister"
- cost = 35
- contains = list(/obj/machinery/portable_atmospherics/canister/carbon_dioxide)
- crate_name = "carbon dioxide canister crate"
- crate_type = /obj/structure/closet/crate/large
-
/obj/machinery/hydroponics/constructable/unattached
anchored = 0
diff --git a/_maps/map_files/TgStation/tgstation.2.1.3.dmm b/_maps/map_files/TgStation/tgstation.2.1.3.dmm
index a23232c6e3e..ec77a16dc25 100644
--- a/_maps/map_files/TgStation/tgstation.2.1.3.dmm
+++ b/_maps/map_files/TgStation/tgstation.2.1.3.dmm
@@ -38438,13 +38438,8 @@
/turf/open/floor/plasteel/white,
/area/medical/sleeper)
"bGS" = (
-/obj/structure/table,
-/obj/item/weapon/reagent_containers/glass/bottle/epinephrine{
- pixel_x = 7;
- pixel_y = -3
- },
-/obj/item/weapon/reagent_containers/glass/bottle/morphine,
-/obj/item/weapon/reagent_containers/syringe,
+/obj/machinery/limbgrower,
+/obj/item/weapon/reagent_containers/glass/beaker/synthflesh,
/turf/open/floor/plasteel/white,
/area/medical/sleeper)
"bGT" = (
@@ -39187,6 +39182,18 @@
pixel_y = 2
},
/obj/item/weapon/storage/box/syringes,
+/obj/item/weapon/reagent_containers/glass/bottle/epinephrine{
+ pixel_x = 7;
+ pixel_y = -3
+ },
+/obj/item/weapon/reagent_containers/glass/bottle/morphine{
+ pixel_x = 8;
+ pixel_y = -3
+ },
+/obj/item/weapon/reagent_containers/syringe{
+ pixel_x = 6;
+ pixel_y = -3
+ },
/turf/open/floor/plasteel/white,
/area/medical/sleeper)
"bIn" = (
diff --git a/_maps/map_files/generic/z2.dmm b/_maps/map_files/generic/z2.dmm
index b9586bc48b5..723bcc61f73 100644
--- a/_maps/map_files/generic/z2.dmm
+++ b/_maps/map_files/generic/z2.dmm
@@ -5307,7 +5307,7 @@
/turf/open/floor/plating,
/area/ctf)
"qD" = (
-/obj/structure/divine/trap/ctf/blue,
+/obj/structure/trap/ctf/blue,
/turf/open/floor/plasteel/blue,
/area/ctf)
"qE" = (
@@ -5335,7 +5335,7 @@
/turf/open/floor/plasteel/darkred,
/area/ctf)
"qI" = (
-/obj/structure/divine/trap/ctf/red,
+/obj/structure/trap/ctf/red,
/turf/open/floor/plasteel/darkred,
/area/ctf)
"qJ" = (
@@ -5379,7 +5379,7 @@
/turf/open/floor/plasteel/circuit/gcircuit/off,
/area/ctf)
"qQ" = (
-/obj/structure/divine/trap/ctf/red,
+/obj/structure/trap/ctf/red,
/turf/open/floor/plasteel/red,
/area/ctf)
"qR" = (
diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm
index 57e6573bc73..6bbc2fe1b59 100644
--- a/code/__DEFINES/hud.dm
+++ b/code/__DEFINES/hud.dm
@@ -30,16 +30,14 @@
#define ANTAG_HUD_OPS 8
#define ANTAG_HUD_WIZ 9
#define ANTAG_HUD_SHADOW 10
-#define ANTAG_HUD_HOG_BLUE 11
-#define ANTAG_HUD_HOG_RED 12
-#define ANTAG_HUD_TRAITOR 13
-#define ANTAG_HUD_NINJA 14
-#define ANTAG_HUD_CHANGELING 15
-#define ANTAG_HUD_ABDUCTOR 16
-#define ANTAG_HUD_DEVIL 17
-#define ANTAG_HUD_SINTOUCHED 18
-#define ANTAG_HUD_SOULLESS 19
-#define ANTAG_HUD_CLOCKWORK 20
+#define ANTAG_HUD_TRAITOR 11
+#define ANTAG_HUD_NINJA 12
+#define ANTAG_HUD_CHANGELING 13
+#define ANTAG_HUD_ABDUCTOR 14
+#define ANTAG_HUD_DEVIL 15
+#define ANTAG_HUD_SINTOUCHED 16
+#define ANTAG_HUD_SOULLESS 17
+#define ANTAG_HUD_CLOCKWORK 18
// Notification action types
#define NOTIFY_JUMP "jump"
diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index fa2ad08b30b..ad3d3d6027b 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -4,6 +4,8 @@
#define in_range(source, user) (get_dist(source, user) <= 1)
+#define is_cleanable(A) (istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/rune)) //if something is cleanable
+
// MOB HELPERS
#define ishuman(A) (istype(A, /mob/living/carbon/human))
diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm
index ebdedff9517..0ff00ff276f 100644
--- a/code/__DEFINES/machines.dm
+++ b/code/__DEFINES/machines.dm
@@ -22,6 +22,7 @@
#define CRAFTLATHE 8 //Uses fuck if I know. For use eventually.
#define MECHFAB 16 //Remember, objects utilising this flag should have construction_time and construction_cost vars.
#define BIOGENERATOR 32 //Uses biomass
+#define LIMBGROWER 64 //Uses synthetic flesh
//Note: More then one of these can be added to a design but imprinter and lathe designs are incompatable.
#define MC_CPU "CPU"
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index a246df231ce..1ec6a0ed426 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -482,7 +482,6 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define STORAGE_VIEW_DEPTH 2
-
// Medal names
#define BOSS_KILL_MEDAL "Killer"
diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm
index aff4dea38c8..51502947f6b 100644
--- a/code/__DEFINES/role_preferences.dm
+++ b/code/__DEFINES/role_preferences.dm
@@ -21,8 +21,6 @@
#define ROLE_GANG "gangster"
#define ROLE_ABDUCTOR "abductor"
#define ROLE_REVENANT "revenant"
-#define ROLE_HOG_GOD "hand of god: god"
-#define ROLE_HOG_CULTIST "hand of god: cultist"
#define ROLE_DEVIL "devil"
#define ROLE_SERVANT_OF_RATVAR "servant of Ratvar"
@@ -45,8 +43,6 @@ var/global/list/special_roles = list(
ROLE_GANG = /datum/game_mode/gang,
ROLE_REVENANT,
ROLE_ABDUCTOR = /datum/game_mode/abduction,
- ROLE_HOG_GOD = /datum/game_mode/hand_of_god,
- ROLE_HOG_CULTIST = /datum/game_mode/hand_of_god,
ROLE_DEVIL = /datum/game_mode/devil,
ROLE_SERVANT_OF_RATVAR = /datum/game_mode/clockwork_cult,
)
diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm
index ad0ea23e9da..0902579bac8 100644
--- a/code/_onclick/hud/_defines.dm
+++ b/code/_onclick/hud/_defines.dm
@@ -51,17 +51,17 @@
#define ui_storage1 "CENTER+1:18,SOUTH:5"
#define ui_storage2 "CENTER+2:20,SOUTH:5"
-#define ui_borg_sensor "CENTER-3:16, SOUTH:5" //borgs
-#define ui_borg_lamp "CENTER-4:16, SOUTH:5" //borgies
-#define ui_borg_thrusters "CENTER-5:16, SOUTH:5"//borgies
-#define ui_inv1 "CENTER-2:16,SOUTH:5" //borgs
-#define ui_inv2 "CENTER-1 :16,SOUTH:5" //borgs
-#define ui_inv3 "CENTER :16,SOUTH:5" //borgs
-#define ui_borg_module "CENTER+1:16,SOUTH:5"
-#define ui_borg_store "CENTER+2:16,SOUTH:5" //borgs
-
-#define ui_borg_camera "CENTER+3:21,SOUTH:5" //borgs
-#define ui_borg_album "CENTER+4:21,SOUTH:5" //borgs
+#define ui_borg_sensor "CENTER-3:16, SOUTH:5" //borgs
+#define ui_borg_lamp "CENTER-4:16, SOUTH:5" //borgs
+#define ui_borg_thrusters "CENTER-5:16, SOUTH:5" //borgs
+#define ui_inv1 "CENTER-2:16,SOUTH:5" //borgs
+#define ui_inv2 "CENTER-1 :16,SOUTH:5" //borgs
+#define ui_inv3 "CENTER :16,SOUTH:5" //borgs
+#define ui_borg_module "CENTER+1:16,SOUTH:5" //borgs
+#define ui_borg_store "CENTER+2:16,SOUTH:5" //borgs
+#define ui_borg_camera "CENTER+3:21,SOUTH:5" //borgs
+#define ui_borg_album "CENTER+4:21,SOUTH:5" //borgs
+#define ui_borg_talk_wheel "CENTER+4:21,SOUTH+1:5" //borgs
#define ui_monkey_head "CENTER-4:13,SOUTH:5" //monkey
#define ui_monkey_mask "CENTER-3:14,SOUTH:5" //monkey
@@ -69,6 +69,7 @@
#define ui_alien_storage_l "CENTER-2:14,SOUTH:5"//alien
#define ui_alien_storage_r "CENTER+1:18,SOUTH:5"//alien
+#define ui_alien_talk_wheel "EAST-3:26,SOUTH:5" //alien
#define ui_drone_drop "CENTER+1:18,SOUTH:5" //maintenance drones
#define ui_drone_pull "CENTER+2:2,SOUTH:5" //maintenance drones
diff --git a/code/_onclick/hud/alien.dm b/code/_onclick/hud/alien.dm
index 2cd637f9653..305d7719b68 100644
--- a/code/_onclick/hud/alien.dm
+++ b/code/_onclick/hud/alien.dm
@@ -70,6 +70,11 @@
H.leap_icon.screen_loc = ui_alien_storage_r
static_inventory += H.leap_icon
+ using = new/obj/screen/wheel/talk
+ using.screen_loc = ui_alien_talk_wheel
+ wheels += using
+ static_inventory += using
+
using = new /obj/screen/drop()
using.icon = 'icons/mob/screen_alien.dmi'
using.screen_loc = ui_drop_throw
diff --git a/code/_onclick/hud/alien_larva.dm b/code/_onclick/hud/alien_larva.dm
index 9594fe08e61..4c04cc363ac 100644
--- a/code/_onclick/hud/alien_larva.dm
+++ b/code/_onclick/hud/alien_larva.dm
@@ -21,6 +21,11 @@
pull_icon.screen_loc = ui_pull_resist
hotkeybuttons += pull_icon
+ using = new/obj/screen/wheel/talk
+ using.screen_loc = ui_alien_talk_wheel
+ wheels += using
+ static_inventory += using
+
zone_select = new /obj/screen/zone_sel/alien()
zone_select.update_icon(mymob)
static_inventory += zone_select
diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm
index 623b49723ae..0dfb1dbb14a 100644
--- a/code/_onclick/hud/hud.dm
+++ b/code/_onclick/hud/hud.dm
@@ -33,6 +33,8 @@
var/obj/screen/throw_icon
var/obj/screen/module_store_icon
+ var/list/wheels = list() //list of the wheel screen objects
+
var/list/static_inventory = list() //the screen objects which are static
var/list/toggleable_inventory = list() //the screen objects which can be hidden
var/list/obj/screen/hotkeybuttons = list() //the buttons that can be used via hotkeys
@@ -64,6 +66,8 @@
qdel(module_store_icon)
module_store_icon = null
+ wheels = null //all wheels are also in static_inventory
+
if(static_inventory.len)
for(var/thing in static_inventory)
qdel(thing)
@@ -199,7 +203,18 @@
return
/datum/hud/proc/persistant_inventory_update(mob/viewer)
- return
+ if(!mymob)
+ return
+ var/mob/living/L = mymob
+
+ var/mob/screenmob = viewer || L
+
+ for(var/X in wheels)
+ var/obj/screen/wheel/W = X
+ if(W.toggled)
+ screenmob.client.screen |= W.buttons_list
+ else
+ screenmob.client.screen -= W.buttons_list
//Triggered when F12 is pressed (Unless someone changed something in the DMF)
/mob/verb/button_pressed_F12()
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index 93f36820fd8..2e7d9e7a5b7 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -95,6 +95,11 @@
using.icon = ui_style
static_inventory += using
+ using = new/obj/screen/wheel/talk
+ using.icon = ui_style
+ wheels += using
+ static_inventory += using
+
using = new /obj/screen/inventory/area_creator
using.icon = ui_style
static_inventory += using
@@ -352,9 +357,12 @@
if(H.wear_mask) screenmob.client.screen -= H.wear_mask
if(H.head) screenmob.client.screen -= H.head
+
+
/datum/hud/human/persistant_inventory_update(mob/viewer)
if(!mymob)
return
+ ..()
var/mob/living/carbon/human/H = mymob
var/mob/screenmob = viewer || H
@@ -394,11 +402,12 @@
if(hud_version != HUD_STYLE_NOHUD)
for(var/obj/item/I in H.held_items)
I.screen_loc = ui_hand_position(H.get_held_index_of_item(I))
- H.client.screen += I
+ screenmob.client.screen += I
else
for(var/obj/item/I in H.held_items)
I.screen_loc = null
- H.client.screen -= I
+ screenmob.client.screen -= I
+
/mob/living/carbon/human/verb/toggle_hotkey_verbs()
set category = "OOC"
diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm
index dd6ec4bef44..588d212375a 100644
--- a/code/_onclick/hud/monkey.dm
+++ b/code/_onclick/hud/monkey.dm
@@ -16,6 +16,11 @@
using.screen_loc = ui_movi
static_inventory += using
+ using = new/obj/screen/wheel/talk
+ using.icon = ui_style
+ wheels += using
+ static_inventory += using
+
using = new /obj/screen/drop()
using.icon = ui_style
using.screen_loc = ui_drop_throw
diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm
index ac42696bc56..af7eabd8e9a 100644
--- a/code/_onclick/hud/other_mobs.dm
+++ b/code/_onclick/hud/other_mobs.dm
@@ -11,31 +11,3 @@
if(client && !hud_used)
hud_used = new /datum/hud/brain(src)
-/datum/hud/hog_god/New(mob/owner)
- ..()
- healths = new /obj/screen/healths/deity()
- infodisplay += healths
-
- deity_power_display = new /obj/screen/deity_power_display()
- infodisplay += deity_power_display
-
- deity_follower_display = new /obj/screen/deity_follower_display()
- infodisplay += deity_follower_display
-
-
-/mob/camera/god/create_mob_hud()
- if(client && !hud_used)
- hud_used = new /datum/hud/hog_god(src)
-
-/obj/screen/deity_power_display
- name = "Faith"
- icon_state = "deity_power"
- screen_loc = ui_deitypower
- layer = HUD_LAYER
-
-/obj/screen/deity_follower_display
- name = "Followers"
- icon_state = "deity_followers"
- screen_loc = ui_deityfollowers
- layer = HUD_LAYER
-
diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm
index aaf740f479e..0ac784718ae 100644
--- a/code/_onclick/hud/robot.dm
+++ b/code/_onclick/hud/robot.dm
@@ -93,6 +93,11 @@
var/mob/living/silicon/robot/mymobR = mymob
var/obj/screen/using
+ using = new/obj/screen/wheel/talk
+ using.screen_loc = ui_borg_talk_wheel
+ wheels += using
+ static_inventory += using
+
//Radio
using = new /obj/screen/robot/radio()
using.screen_loc = ui_borg_radio
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index cb9c698efaf..8dedf4b91b7 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -480,3 +480,139 @@
/obj/screen/healthdoll
name = "health doll"
screen_loc = ui_healthdoll
+
+
+
+/obj/screen/wheel
+ name = "wheel"
+ layer = HUD_LAYER
+ icon_state = ""
+ screen_loc = null //if you make a new wheel, remember to give it a screen_loc
+ var/list/buttons_names = list() //list of the names for each button, its length is the amount of buttons.
+ var/toggled = 0 //wheel is hidden/shown
+ var/wheel_buttons_type //the type of buttons used with this wheel.
+ var/list/buttons_list = list()
+
+/obj/screen/wheel/New()
+ ..()
+ build_options()
+
+
+//we create the buttons for the wheel and place them in a square spiral fashion.
+/obj/screen/wheel/proc/build_options()
+ var/obj/screen/wheel_button/close_wheel/CW = new ()
+ buttons_list += CW //the close option
+ CW.wheel = src
+
+ var/list/offset_x_list = list()
+ var/list/offset_y_list = list()
+ var/num = 1
+ var/N = 1
+ var/M = 0
+ var/sign = -1
+ my_loop:
+ while(offset_y_list.len < buttons_names.len)
+ for(var/i=1, i<=num, i++)
+ offset_y_list += N
+ offset_x_list += M
+ if(offset_y_list.len == buttons_names.len)
+ break my_loop
+ if(N != 0)
+ N = 0
+ M = -sign
+ else
+ N = sign
+ M = 0
+ sign = -sign
+ num++
+
+ var/screenx = 8
+ var/screeny = 8
+ for(var/i = 1, i <= buttons_names.len, i++)
+ var/obj/screen/wheel_button/WB = new wheel_buttons_type()
+ WB.wheel = src
+ buttons_list += WB
+ screenx += offset_x_list[i]
+ screeny += offset_y_list[i]
+ WB.screen_loc = "[screenx], [screeny]"
+ set_button(WB, i)
+
+/obj/screen/wheel/proc/set_button(obj/screen/wheel_button/WB, button_number)
+ WB.name = buttons_names[button_number]
+ return
+
+/obj/screen/wheel/Destroy()
+ for(var/obj/screen/S in buttons_list)
+ qdel(S)
+ return ..()
+
+/obj/screen/wheel/Click()
+ if(world.time <= usr.next_move)
+ return
+ if(usr.stat)
+ return
+ if(isliving(usr))
+ var/mob/living/L = usr
+ if(toggled)
+ L.client.screen -= buttons_list
+ else
+ L.client.screen |= buttons_list
+ toggled = !toggled
+
+
+/obj/screen/wheel/talk
+ name = "talk wheel"
+ icon_state = "talk_wheel"
+ screen_loc = "11:6,2:-11"
+ wheel_buttons_type = /obj/screen/wheel_button/talk
+ buttons_names = list("help","hello","bye","stop","thanks","come","out", "yes", "no")
+ var/list/word_messages = list(list("Help!","Help me!"), list("Hello.", "Hi."), list("Bye.", "Goodbye."),\
+ list("Stop!", "Halt!"), list("Thanks.", "Thanks!", "Thank you."), \
+ list("Come.", "Follow me."), list("Out!", "Go away!", "Get out!"), \
+ list("Yes.", "Affirmative."), list("No.", "Negative"))
+
+/obj/screen/wheel/talk/set_button(obj/screen/wheel_button/WB, button_number)
+ ..()
+ var/obj/screen/wheel_button/talk/T = WB //we already know what type the button is exactly.
+ T.icon_state = "talk_[T.name]"
+ T.word_messages = word_messages[button_number]
+
+
+/obj/screen/wheel_button
+ name = "default wheel button"
+ screen_loc = "8,8"
+ layer = HUD_LAYER
+ mouse_opacity = 2
+ var/obj/screen/wheel/wheel
+
+/obj/screen/wheel_button/Destroy()
+ wheel = null
+ return ..()
+
+/obj/screen/wheel_button/close_wheel
+ name = "close wheel"
+ icon_state = "x3"
+
+/obj/screen/wheel_button/close_wheel/Click()
+ if(isliving(usr))
+ var/mob/living/L = usr
+ L.client.screen -= wheel.buttons_list
+ wheel.toggled = !wheel.toggled
+
+
+/obj/screen/wheel_button/talk
+ name = "talk option"
+ icon_state = "talk_help"
+ var/talk_cooldown = 0
+ var/list/word_messages = list()
+
+/obj/screen/wheel_button/talk/Click(location, control,params)
+ if(isliving(usr))
+ var/mob/living/L = usr
+ if(L.stat)
+ return
+
+ if(word_messages.len && talk_cooldown < world.time)
+ talk_cooldown = world.time + 10
+ L.say(pick(word_messages))
+
diff --git a/code/controllers/subsystem/spacedrift.dm b/code/controllers/subsystem/spacedrift.dm
index 51b8df01619..856f51ce7ac 100644
--- a/code/controllers/subsystem/spacedrift.dm
+++ b/code/controllers/subsystem/spacedrift.dm
@@ -32,8 +32,15 @@ var/datum/subsystem/spacedrift/SSspacedrift
if (MC_TICK_CHECK)
return
continue
+
+ if (AM.inertia_next_move > world.time)
+ if (MC_TICK_CHECK)
+ return
+ continue
+
if (!AM.loc || AM.loc != AM.inertia_last_loc || AM.Process_Spacemove(0))
AM.inertia_dir = 0
+
if (!AM.inertia_dir)
AM.inertia_last_loc = null
processing -= AM
@@ -43,7 +50,10 @@ var/datum/subsystem/spacedrift/SSspacedrift
var/old_dir = AM.dir
var/old_loc = AM.loc
+ AM.inertia_moving = TRUE
step(AM, AM.inertia_dir)
+ AM.inertia_moving = FALSE
+ AM.inertia_next_move = world.time + AM.inertia_move_delay
if (AM.loc == old_loc)
AM.inertia_dir = 0
diff --git a/code/datums/hud.dm b/code/datums/hud.dm
index 62c1700f58d..75adb165d3a 100644
--- a/code/datums/hud.dm
+++ b/code/datums/hud.dm
@@ -12,8 +12,6 @@ var/datum/atom_hud/huds = list( \
ANTAG_HUD_OPS = new/datum/atom_hud/antag(), \
ANTAG_HUD_WIZ = new/datum/atom_hud/antag(), \
ANTAG_HUD_SHADOW = new/datum/atom_hud/antag(), \
- ANTAG_HUD_HOG_BLUE = new/datum/atom_hud/antag(),\
- ANTAG_HUD_HOG_RED = new/datum/atom_hud/antag(),\
ANTAG_HUD_TRAITOR = new/datum/atom_hud/antag/hidden(),\
ANTAG_HUD_NINJA = new/datum/atom_hud/antag/hidden(),\
ANTAG_HUD_CHANGELING = new/datum/atom_hud/antag/hidden(),\
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index eed2f5960c8..b7c70b57878 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -178,16 +178,6 @@
ticker.mode.remove_gangster(src,0,1,1)
remove_objectives()
-/datum/mind/proc/remove_hog_follower_prophet()
- ticker.mode.red_deity_followers -= src
- ticker.mode.red_deity_prophets -= src
- ticker.mode.blue_deity_prophets -= src
- ticker.mode.blue_deity_followers -= src
- ticker.mode.update_hog_icons_removed(src, "red")
- ticker.mode.update_hog_icons_removed(src, "blue")
-
-
-
/datum/mind/proc/remove_antag_equip()
var/list/Mob_Contents = current.get_contents()
for(var/obj/item/I in Mob_Contents)
@@ -225,12 +215,6 @@
else if(is_gangster(creator))
ticker.mode.add_gangster(src, creator.mind.gang_datum, TRUE)
- else if(is_handofgod_redcultist(creator) || is_handofgod_redprophet(creator))
- ticker.mode.add_hog_follower(src, "Red")
-
- else if(is_handofgod_bluecultist(creator) || is_handofgod_blueprophet(creator))
- ticker.mode.add_hog_follower(src, "Blue")
-
else if(is_revolutionary_in_general(creator))
ticker.mode.add_revolutionary(src)
@@ -494,38 +478,6 @@
sections["traitor"] = text
- /** HAND OF GOD **/
- text = "hand of god"
- if(ticker.mode.config_tag == "handofgod")
- text = uppertext(text)
- text = "[text]: "
- if (src in ticker.mode.red_deities)
- text += "RED GOD|red prophet|red follower|employee|blue god|blue prophet|blue follower"
- else if(src in ticker.mode.red_deity_prophets)
- text += "red god|RED PROPHET|red follower|employee|blue god|blue prophet|blue follower"
- else if (src in ticker.mode.red_deity_followers)
- text += "red god|red prophet|RED FOLLOWER|employee|blue god|blue prophet|blue follower"
- else if (src in ticker.mode.blue_deities)
- text += "red god|red prophet|red follower|employee|BLUE GOD|blue prophet|blue follower"
- else if (src in ticker.mode.blue_deity_prophets)
- text += "red god|red prophet|red follower|employee|blue god|BLUE PROPHET|blue follower"
- else if (src in ticker.mode.blue_deity_followers)
- text += "red god|red prophet|red follower|employee|blue god|blue prophet|BLUE FOLLOWER"
- else
- text += "red god|red prophet|red follower|EMPLOYEE|blue god|blue prophet|blue follower"
-
- if(current && current.client && (ROLE_HOG_GOD in current.client.prefs.be_special))
- text += "|HOG God Enabled in Prefs"
- else
- text += "|HOG God Disabled in Prefs"
-
- if(current && current.client && (ROLE_HOG_CULTIST in current.client.prefs.be_special))
- text += "|HOG Cultist Enabled in Prefs"
- else
- text += "|HOG Disabled in Prefs"
-
- sections["follower"] = text
-
if(ishuman(current) || ismonkey(current))
/** CHANGELING ***/
@@ -700,7 +652,7 @@
if(!def_value)//If it's a custom objective, it will be an empty string.
def_value = "custom"
- var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "maroon", "debrain", "protect", "destroy", "prevent", "hijack", "escape", "survive", "martyr", "steal", "download", "nuclear", "capture", "absorb", "custom","follower block (HOG)","build (HOG)","deicide (HOG)", "follower escape (HOG)", "sacrifice prophet (HOG)")
+ var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "maroon", "debrain", "protect", "destroy", "prevent", "hijack", "escape", "survive", "martyr", "steal", "download", "nuclear", "capture", "absorb", "custom")
if (!new_obj_type)
return
@@ -802,22 +754,6 @@
new_objective.owner = src
new_objective.target_amount = target_number
- if("follower block (HOG)")
- new_objective = new /datum/objective/follower_block
- new_objective.owner = src
- if("build (HOG)")
- new_objective = new /datum/objective/build
- new_objective.owner = src
- if("deicide (HOG)")
- new_objective = new /datum/objective/deicide
- new_objective.owner = src
- if("follower escape (HOG)")
- new_objective = new /datum/objective/escape_followers
- new_objective.owner = src
- if("sacrifice prophet (HOG)")
- new_objective = new /datum/objective/sacrifice_prophet
- new_objective.owner = src
-
if ("custom")
var/expl = stripped_input(usr, "Custom objective:", "Objective", objective ? objective.explanation_text : "")
if (!expl)
@@ -854,46 +790,6 @@
objective.completed = !objective.completed
log_admin("[key_name(usr)] toggled the win state for [current]'s objective: [objective.explanation_text]")
- else if (href_list["handofgod"])
- switch(href_list["handofgod"])
- if("clear") //wipe handofgod status
- if((src in ticker.mode.red_deity_followers) || (src in ticker.mode.blue_deity_followers) || (src in ticker.mode.red_deity_prophets) || (src in ticker.mode.blue_deity_prophets))
- remove_hog_follower_prophet()
- current << "You have been brainwashed... again! Your faith is no more!"
- message_admins("[key_name_admin(usr)] has de-hand of god'ed [current].")
- log_admin("[key_name(usr)] has de-hand of god'ed [current].")
-
- if("red follower")
- make_Handofgod_follower("red")
- message_admins("[key_name_admin(usr)] has red follower'ed [current].")
- log_admin("[key_name(usr)] has red follower'ed [current].")
-
- if("red prophet")
- make_Handofgod_prophet("red")
- message_admins("[key_name_admin(usr)] has red prophet'ed [current].")
- log_admin("[key_name(usr)] has red prophet'ed [current].")
-
- if("blue follower")
- make_Handofgod_follower("blue")
- message_admins("[key_name_admin(usr)] has blue follower'ed [current].")
- log_admin("[key_name(usr)] has blue follower'ed [current].")
-
- if("blue prophet")
- make_Handofgod_prophet("blue")
- message_admins("[key_name_admin(usr)] has blue prophet'ed [current].")
- log_admin("[key_name(usr)] has blue prophet'ed [current].")
-
- if("red god")
- make_Handofgod_god("red")
- message_admins("[key_name_admin(usr)] has red god'ed [current].")
- log_admin("[key_name(usr)] has red god'ed [current].")
-
- if("blue god")
- make_Handofgod_god("blue")
- message_admins("[key_name_admin(usr)] has blue god'ed [current].")
- log_admin("[key_name(usr)] has blue god'ed [current].")
-
-
else if (href_list["revolution"])
switch(href_list["revolution"])
if("clear")
@@ -1567,119 +1463,6 @@
L = agent_landmarks[team]
H.loc = L.loc
-
-/datum/mind/proc/make_Handofgod_follower(colour)
- . = 0
- switch(colour)
- if("red")
- //Remove old allegiances
- if(src in ticker.mode.blue_deity_followers || src in ticker.mode.blue_deity_prophets)
- current << "You are no longer a member of the Blue cult!"
-
- ticker.mode.blue_deity_followers -= src
- ticker.mode.blue_deity_prophets -= src
- current.faction |= "red god"
- current.faction -= "blue god"
-
- if(src in ticker.mode.red_deity_prophets)
- current << "You have lost the connection with your deity, but you still believe in their grand design, You are no longer a prophet!"
- ticker.mode.red_deity_prophets -= src
-
- ticker.mode.red_deity_followers |= src
- current << "You are now a follower of the red cult's god!"
-
- special_role = "Hand of God: Red Follower"
- . = 1
- if("blue")
- //Remove old allegiances
- if(src in ticker.mode.red_deity_followers || src in ticker.mode.red_deity_prophets)
- current << "You are no longer a member of the Red cult!"
-
- ticker.mode.red_deity_followers -= src
- ticker.mode.red_deity_prophets -= src
- current.faction -= "red god"
- current.faction |= "blue god"
-
- if(src in ticker.mode.blue_deity_prophets)
- current << "You have lost the connection with your deity, but you still believe in their grand design, You are no longer a prophet!"
- ticker.mode.blue_deity_prophets -= src
-
- ticker.mode.blue_deity_followers |= src
- current << "You are now a follower of the blue cult's god!"
-
- special_role = "Hand of God: Blue Follower"
- . = 1
- else
- return 0
-
- ticker.mode.update_hog_icons_removed(src,"red")
- ticker.mode.update_hog_icons_removed(src,"blue")
- //ticker.mode.greet_hog_follower(src,colour)
- ticker.mode.update_hog_icons_added(src, colour)
-
-/datum/mind/proc/make_Handofgod_prophet(colour)
- . = 0
- switch(colour)
- if("red")
- //Remove old allegiances
-
- if(src in ticker.mode.blue_deity_followers || src in ticker.mode.blue_deity_prophets)
- current << "You are no longer a member of the Blue cult!"
- current.faction -= "blue god"
- current.faction |= "red god"
-
- ticker.mode.blue_deity_followers -= src
- ticker.mode.blue_deity_prophets -= src
- ticker.mode.red_deity_followers -= src
-
- ticker.mode.red_deity_prophets |= src
- current << "You are now a prophet of the red cult's god!"
-
- special_role = "Hand of God: Red Prophet"
- . = 1
- if("blue")
- //Remove old allegiances
-
- if(src in ticker.mode.red_deity_followers || src in ticker.mode.red_deity_prophets)
- current << "You are no longer a member of the Red cult!"
- current.faction -= "red god"
- current.faction |= "blue god"
-
- ticker.mode.red_deity_followers -= src
- ticker.mode.red_deity_prophets -= src
- ticker.mode.blue_deity_followers -= src
-
- ticker.mode.blue_deity_prophets |= src
- current << "You are now a prophet of the blue cult's god!"
-
- special_role = "Hand of God: Blue Prophet"
- . = 1
-
- else
- return 0
-
- ticker.mode.update_hog_icons_removed(src,"red")
- ticker.mode.update_hog_icons_removed(src,"blue")
- ticker.mode.greet_hog_follower(src,colour)
- ticker.mode.update_hog_icons_added(src, colour)
-
-/datum/mind/proc/make_Handofgod_god(colour)
- switch(colour)
- if("red")
- current.become_god("red")
- ticker.mode.add_god(src,"red")
- if("blue")
- current.become_god("blue")
- ticker.mode.add_god(src,"blue")
- else
- return 0
- ticker.mode.forge_deity_objectives(src)
- ticker.mode.remove_hog_follower(src,0)
- ticker.mode.update_hog_icons_added(src, colour)
-// ticker.mode.greet_hog_follower(src,colour)
- return 1
-
-
/datum/mind/proc/AddSpell(obj/effect/proc_holder/spell/S)
spell_list += S
S.action.Grant(current)
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 8cb112ca8f8..e71b533d3c8 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -13,7 +13,10 @@
var/verb_exclaim = "exclaims"
var/verb_yell = "yells"
var/inertia_dir = 0
- var/inertia_last_loc
+ var/atom/inertia_last_loc
+ var/inertia_moving = 0
+ var/inertia_next_move = 0
+ var/inertia_move_delay = 5
var/pass_flags = 0
var/moving_diagonally = 0 //0: not doing a diagonal move. 1 and 2: doing the first/second step of the diagonal move
glide_size = 8
@@ -71,13 +74,13 @@
last_move = direct
setDir(direct)
-
if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc,direct)) //movement failed due to buckled mob(s)
. = 0
//Called after a successful Move(). By this point, we've already moved
/atom/movable/proc/Moved(atom/OldLoc, Dir)
- if (!inertia_dir)
+ if (!inertia_moving)
+ inertia_next_move = world.time + inertia_move_delay
newtonian_move(Dir)
return 1
diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm
index fe14f5486f8..8cd3b7d2f89 100644
--- a/code/game/data_huds.dm
+++ b/code/game/data_huds.dm
@@ -61,10 +61,16 @@
//called when a carbon changes virus
/mob/living/carbon/proc/check_virus()
+ var/threat = 0
for(var/datum/disease/D in viruses)
- if((!(D.visibility_flags & HIDDEN_SCANNER)) && (D.severity != NONTHREAT))
- return 1
- return 0
+ if(!(D.visibility_flags & HIDDEN_SCANNER))
+ if (D.severity != NONTHREAT) //a buffing virus gets an icon
+ threat = 2
+ return threat //harmful viruses have priority
+ else
+ threat = 1 //aka good virus
+
+ return threat
//helper for getting the appropriate health status
/proc/RoundHealth(mob/living/M)
@@ -155,13 +161,16 @@
/mob/living/carbon/med_hud_set_status()
var/image/holder = hud_list[STATUS_HUD]
var/icon/I = icon(icon, icon_state, dir)
+ var/virus_state = check_virus()
holder.pixel_y = I.Height() - world.icon_size
if(status_flags & XENO_HOST)
holder.icon_state = "hudxeno"
else if(stat == DEAD || (status_flags & FAKEDEATH))
holder.icon_state = "huddead"
- else if(check_virus())
+ else if(virus_state == 2)
holder.icon_state = "hudill"
+ else if(virus_state == 1)
+ holder.icon_state = "hudbuff"
else
holder.icon_state = "hudhealthy"
diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index 9c7b709b6b6..0b1d11cd3c4 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -74,9 +74,8 @@ This file contains the arcane tome files.
Successful conversions will produce a tome for the new cultist, in addition to healing them.
\
Successful sacrifices will please the Geometer, can complete your objective if it sacrificed the sacrifice target, and will attempt to place the target into a soulstone.
"
- text += "Raise Dead
This rune requires two corpses. To perform the ritual, place the corpse you wish to revive onto \
- the rune and the offering body adjacent to it. When the rune is invoked, the body to be sacrificed will turn to dust, the life force flowing into the revival target. Assuming the target is not moved \
- within a few seconds, they will be brought back to life, healed of all ailments.
"
+ text += "Raise Dead
This rune requires the corpse of a cultist placed upon the rune, and one person sacrificed for each revival you wish to do.\
+ Provided there are remaining revivals from those sacrificed, invoking the rune will revive the cultist placed upon it.
"
text += "Electromagnetic Disruption
Robotic lifeforms have time and time again been the downfall of fledgling cults. This rune may allow you to gain the upper \
hand against these pests. By using the rune, a large electromagnetic pulse will be emitted from the rune's location. The size of the EMP will grow significantly for each additional adjacent cultist when the \
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index 6e3ceba0756..d42b1bdeaff 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -1,4 +1,4 @@
-/var/list/sacrificed = list()
+/var/list/sacrificed = list() //a mixed list of minds and mobs
var/list/non_revealed_runes = (subtypesof(/obj/effect/rune) - /obj/effect/rune/malformed)
/*
@@ -337,6 +337,9 @@ var/list/teleport_runes = list()
allow_excess_invokers = 1
rune_in_use = FALSE
+/obj/effect/rune/convert/do_invoke_glow()
+ return
+
/obj/effect/rune/convert/invoke(var/list/invokers)
if(rune_in_use)
return
@@ -352,11 +355,12 @@ var/list/teleport_runes = list()
rune_in_use = TRUE
visible_message("[src] pulses blood red!")
color = "#7D1717"
- ..()
var/mob/living/L = pick(myriad_targets)
var/is_clock = is_servant_of_ratvar(L)
var/is_convertable = is_convertable_to_cult(L.mind)
if(L.stat != DEAD && (is_clock || is_convertable))
+ invocation = "Mah'weyh pleggh at e'ntrath!"
+ ..()
if(is_clock)
L.visible_message("[L]'s eyes glow a defiant yellow!", \
"\"Stop resisting. You will be mi-\"\n\
@@ -365,8 +369,10 @@ var/list/teleport_runes = list()
else if(is_convertable)
do_convert(L, invokers)
else
+ invocation = "Barhah hra zar'garis!"
+ ..()
do_sacrifice(L, invokers)
- color = initial(color)
+ animate(src, color = initial(color), time = 5)
rune_in_use = FALSE
/obj/effect/rune/convert/proc/do_convert(mob/living/convertee, list/invokers)
@@ -383,8 +389,8 @@ var/list/teleport_runes = list()
var/brutedamage = convertee.getBruteLoss()
var/burndamage = convertee.getFireLoss()
if(brutedamage || burndamage)
- convertee.adjustBruteLoss(-brutedamage)
- convertee.adjustFireLoss(-burndamage)
+ convertee.adjustBruteLoss(-(brutedamage * 0.75))
+ convertee.adjustFireLoss(-(burndamage * 0.75))
convertee.visible_message("[convertee] writhes in pain \
[brutedamage || burndamage ? "even as their wounds heal and close" : "as the markings below them glow a bloody red"]!", \
"AAAAAAAAAAAAAA-")
@@ -406,9 +412,11 @@ var/list/teleport_runes = list()
var/sacrifice_fulfilled = FALSE
if(sacrificial.mind)
- sacrificed.Add(sacrificial.mind)
+ sacrificed += sacrificial.mind
if(is_sacrifice_target(sacrificial.mind))
sacrifice_fulfilled = TRUE
+ else
+ sacrificed += sacrificial
PoolOrNew(/obj/effect/overlay/temp/cult/sac, get_turf(src))
for(var/M in invokers)
@@ -478,6 +486,7 @@ var/list/teleport_runes = list()
M << "Nar-Sie does not respond!"
fail_invoke()
log_game("Summon Nar-Sie rune failed - gametype is not cult")
+ return
if(locate(/obj/singularity/narsie) in poi_list)
for(var/M in invokers)
@@ -511,50 +520,47 @@ var/list/teleport_runes = list()
..()
return
-//Rite of Resurrection: Requires two corpses. Revives one and gibs the other.
+//Rite of Resurrection: Requires the corpse of a cultist and that there have been less revives than the number of people sacrificed
/obj/effect/rune/raise_dead
cultist_name = "Raise Dead"
- cultist_desc = "requires two corpses, one on the rune and one adjacent to the rune. The one on the rune is brought to life, the other is turned to ash."
+ cultist_desc = "requires the corpse of a cultist placed upon the rune. Provided there have been sufficient sacrifices, they will be revived."
invocation = null //Depends on the name of the user - see below
icon_state = "1"
color = "#C80000"
+ var/static/revives_used = 0
+
+/obj/effect/rune/raise_dead/examine(mob/user)
+ ..()
+ if(iscultist(user) || user.stat == DEAD)
+ var/revive_number = 0
+ if(sacrificed.len)
+ revive_number = sacrificed.len - revives_used
+ user << "Revives Remaining: [revive_number]"
/obj/effect/rune/raise_dead/invoke(var/list/invokers)
var/turf/T = get_turf(src)
- var/mob/living/mob_to_sacrifice
var/mob/living/mob_to_revive
- var/list/potential_sacrifice_mobs = list()
var/list/potential_revive_mobs = list()
var/mob/living/user = invokers[1]
if(rune_in_use)
return
- for(var/mob/living/M in orange(1,T))
- if(M.stat == DEAD && !iscultist(M))
- potential_sacrifice_mobs |= M
- if(!potential_sacrifice_mobs.len)
- user << "There are no eligible sacrifices nearby!"
- log_game("Raise Dead rune failed - no catalyst corpses")
- fail_invoke()
- return
for(var/mob/living/M in T.contents)
- if(M.stat == DEAD)
+ if(iscultist(M) && M.stat == DEAD)
potential_revive_mobs |= M
if(!potential_revive_mobs.len)
- user << "There is no eligible revival target on the rune!"
+ user << "There are no dead cultists on the rune!"
log_game("Raise Dead rune failed - no corpses to revive")
fail_invoke()
return
- if(potential_sacrifice_mobs.len > 1)
- mob_to_sacrifice = input(user, "Choose a corpse to sacrifice.", "Corpse to Sacrifice") as null|anything in potential_sacrifice_mobs
- else
- mob_to_sacrifice = potential_sacrifice_mobs[1]
- if(!src || qdeleted(src) || rune_in_use || !validness_checks(mob_to_sacrifice, user, TRUE))
+ if(!sacrificed.len || sacrificed.len <= revives_used)
+ user << "You have sacrificed too few people to revive a cultist!"
+ fail_invoke()
return
if(potential_revive_mobs.len > 1)
- mob_to_revive = input(user, "Choose a corpse to revive.", "Corpse to Revive") as null|anything in potential_revive_mobs
+ mob_to_revive = input(user, "Choose a cultist to revive.", "Cultist to Revive") as null|anything in potential_revive_mobs
else
mob_to_revive = potential_revive_mobs[1]
- if(!src || qdeleted(src) || rune_in_use || !validness_checks(mob_to_sacrifice, user, TRUE) || !validness_checks(mob_to_revive, user, FALSE))
+ if(!src || qdeleted(src) || rune_in_use || !validness_checks(mob_to_revive, user))
return
rune_in_use = 1
if(user.name == "Herbert West")
@@ -562,19 +568,7 @@ var/list/teleport_runes = list()
else
user.say("Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!")
..()
- mob_to_sacrifice.visible_message("[mob_to_sacrifice]'s body rises into the air, connected to [mob_to_revive] by a glowing tendril!")
- mob_to_revive.Beam(mob_to_sacrifice,icon_state="sendbeam",time=20)
- sleep(20)
- if(!mob_to_sacrifice || !in_range(mob_to_sacrifice, src))
- rune_in_use = 0
- return
- if(!mob_to_revive || mob_to_revive.stat != DEAD)
- visible_message("The glowing tendril snaps against the rune with a shocking crack.")
- rune_in_use = 0
- fail_invoke()
- return
- mob_to_sacrifice.visible_message("[mob_to_sacrifice] disintegrates into a pile of bones.")
- mob_to_sacrifice.dust()
+ revives_used++
mob_to_revive.revive(1, 1) //This does remove disabilities and such, but the rune might actually see some use because of it!
mob_to_revive.grab_ghost()
mob_to_revive << "\"PASNAR SAVRAE YAM'TOTH. Arise.\""
@@ -582,7 +576,7 @@ var/list/teleport_runes = list()
"You awaken suddenly from the void. You're alive!")
rune_in_use = 0
-/obj/effect/rune/raise_dead/proc/validness_checks(mob/living/target_mob, mob/living/user, saccing)
+/obj/effect/rune/raise_dead/proc/validness_checks(mob/living/target_mob, mob/living/user)
var/turf/T = get_turf(src)
if(!user)
return 0
@@ -591,28 +585,28 @@ var/list/teleport_runes = list()
if(!target_mob)
fail_invoke()
return 0
- if(saccing)
- if(!in_range(target_mob, src))
- user << "The sacrificial target has been moved!"
- fail_invoke()
- log_game("Raise Dead rune failed - catalyst corpse moved")
- return 0
- if(target_mob.stat != DEAD)
- user << "The sacrificial target must be dead!"
- fail_invoke()
- log_game("Raise Dead rune failed - catalyst corpse is not dead")
- return 0
- else if(!(target_mob in T.contents))
- user << "The corpse to revive has been moved!"
+ if(!(target_mob in T.contents))
+ user << "The cultist to revive has been moved!"
fail_invoke()
log_game("Raise Dead rune failed - revival target moved")
return 0
+ var/mob/dead/observer/ghost = target_mob.get_ghost(TRUE)
+ if(!ghost)
+ user << "The corpse to revive has no spirit!"
+ fail_invoke()
+ log_game("Raise Dead rune failed - revival target has no ghost")
+ return 0
+ if(!sacrificed.len || sacrificed.len <= revives_used)
+ user << "You have sacrificed too few people to revive a cultist!"
+ fail_invoke()
+ log_game("Raise Dead rune failed - too few sacrificed")
+ return 0
return 1
/obj/effect/rune/raise_dead/fail_invoke()
..()
for(var/mob/living/M in range(1,src))
- if(M.stat == DEAD)
+ if(iscultist(M) && M.stat == DEAD)
M.visible_message("[M] twitches.")
@@ -681,7 +675,7 @@ var/list/teleport_runes = list()
var/turf/T = get_turf(src)
rune_in_use = 1
affecting = user
- user.color = "#7e1717"
+ user.color = "#7D1717"
user.visible_message("[user] freezes statue-still, glowing an unearthly red.", \
"You see what lies beyond. All is revealed. While this is a wondrous experience, your physical form will waste away in this state. Hurry...")
user.ghostize(1)
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index a1cf737631b..6dc61afc365 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -539,8 +539,6 @@
ticker.mode.remove_cultist(newborgie, 0, 0)
ticker.mode.remove_revolutionary(newborgie, 0)
ticker.mode.remove_gangster(newborgie, 0, remove_bosses=1)
- ticker.mode.remove_hog_follower(newborgie, 0)
-
/datum/game_mode/proc/generate_station_goals()
var/list/possible = list()
diff --git a/code/game/gamemodes/handofgod/_handofgod.dm b/code/game/gamemodes/handofgod/_handofgod.dm
deleted file mode 100644
index 2de6b0f782d..00000000000
--- a/code/game/gamemodes/handofgod/_handofgod.dm
+++ /dev/null
@@ -1,476 +0,0 @@
-
-var/global/list/global_handofgod_traptypes = list()
-var/global/list/global_handofgod_structuretypes = list()
-
-#define CONDUIT_RANGE 15
-
-
-/datum/game_mode
- var/list/datum/mind/red_deities = list()
- var/list/datum/mind/red_deity_prophets = list()
- var/list/datum/mind/red_deity_followers = list()
-
- var/list/datum/mind/blue_deities = list()
- var/list/datum/mind/blue_deity_prophets = list()
- var/list/datum/mind/blue_deity_followers = list()
-
- var/list/datum/mind/unassigned_followers = list() //for roundstart team assigning
- var/list/datum/mind/assigned_to_red = list()
- var/list/datum/mind/assigned_to_blue = list()
-
-
-/datum/game_mode/hand_of_god
- name = "hand of god"
- config_tag = "handofgod"
- antag_flag = ROLE_HOG_CULTIST //Followers use ROLE_HOG_CULTIST, Gods are picked later on with ROLE_HOG_GOD
-
- required_players = 25
- required_enemies = 8
- recommended_enemies = 8
- restricted_jobs = list("Chaplain","AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel")
-
- announce_span = "danger"
- announce_text = "Two cults are trying to overthrow one another!\n\
- Gods: Protect your nexus and eliminate the enemy god.\n\
- Prophets: Lead your cult by your deity's will.\n\
- Followers: Follow your prophet's orders and lead your deity to victory.\n\
- Crew: Destroy both cults before they can grow in strength."
-
-
-/////////////
-//Pre setup//
-/////////////
-
-/datum/game_mode/hand_of_god/pre_setup()
- if(config.protect_roles_from_antagonist)
- restricted_jobs += protected_jobs
-
- if(config.protect_assistant_from_antagonist)
- restricted_jobs += "Assistant"
-
- for(var/F in 1 to recommended_enemies)
- if(!antag_candidates.len)
- break
- var/datum/mind/follower = pick_n_take(antag_candidates)
- unassigned_followers += follower
- follower.restricted_roles = restricted_jobs
- log_game("[follower.key] (ckey) has been selected as a follower, however teams have not been decided yet.")
-
- while(unassigned_followers.len > (required_enemies / 2))
- var/datum/mind/chosen = pick_n_take(unassigned_followers)
- add_hog_follower(chosen,"red")
-
- while(unassigned_followers.len)
- var/datum/mind/chosen = pick_n_take(unassigned_followers)
- add_hog_follower(chosen,"blue")
-
- return 1
-
-
-//////////////
-//Post Setup//
-//////////////
-
-//Pick a follower to uplift into a god
-/datum/game_mode/hand_of_god/post_setup()
-
- //Find viable red god
- var/list/red_god_possibilities = get_players_for_role(ROLE_HOG_GOD)
- red_god_possibilities &= red_deity_followers //followers only
- if(!red_god_possibilities.len) //No candidates? just pick any follower regardless of prefs
- red_god_possibilities = red_deity_followers
-
- //Make red god
- var/datum/mind/red_god = pick_n_take(red_god_possibilities)
- if(red_god)
- red_god.current.become_god("red")
- remove_hog_follower(red_god,0)
- add_god(red_god,"red")
-
- //Find viable blue god
- var/list/blue_god_possibilities = get_players_for_role(ROLE_HOG_GOD)
- blue_god_possibilities &= blue_deity_followers //followers only
- if(!blue_god_possibilities.len) //No candidates? just pick any follower regardless of prefs
- blue_god_possibilities = blue_deity_followers
-
- //Make blue god
- var/datum/mind/blue_god = pick_n_take(blue_god_possibilities)
- if(blue_god)
- blue_god.current.become_god("blue")
- remove_hog_follower(blue_god,0)
- add_god(blue_god,"blue")
-
-
- //Forge objectives
- //This is done here so that both gods exist
- if(red_god)
- ticker.mode.forge_deity_objectives(red_god)
- if(blue_god)
- ticker.mode.forge_deity_objectives(blue_god)
-
-
- ..()
-
-///////////////////
-//Objective Procs//
-///////////////////
-
-/datum/game_mode/proc/forge_deity_objectives(datum/mind/deity)
- switch(rand(1,100))
- if(1 to 30)
- var/datum/objective/deicide/deicide = new
- deicide.owner = deity
- if(deicide.find_target())//Hard to kill the other god if there is none
- deity.objectives += deicide
-
- if(!(locate(/datum/objective/escape_followers) in deity.objectives))
- var/datum/objective/escape_followers/recruit = new
- recruit.owner = deity
- deity.objectives += recruit
- recruit.gen_amount_goal(8, 12)
-
- if(31 to 60)
- var/datum/objective/sacrifice_prophet/sacrifice = new
- sacrifice.owner = deity
- deity.objectives += sacrifice
-
- if(!(locate(/datum/objective/escape_followers) in deity.objectives))
- var/datum/objective/escape_followers/recruit = new
- recruit.owner = deity
- deity.objectives += recruit
- recruit.gen_amount_goal(8, 12)
-
- if(61 to 85)
- var/datum/objective/build/build = new
- build.owner = deity
- deity.objectives += build
- build.gen_amount_goal(8, 16)
-
- var/datum/objective/sacrifice_prophet/sacrifice = new
- sacrifice.owner = deity
- deity.objectives += sacrifice
-
- if(!(locate(/datum/objective/escape_followers) in deity.objectives))
- var/datum/objective/escape_followers/recruit = new
- recruit.owner = deity
- deity.objectives += recruit
- recruit.gen_amount_goal(8, 12)
-
- else
- if (!locate(/datum/objective/follower_block) in deity.objectives)
- var/datum/objective/follower_block/block = new
- block.owner = deity
- deity.objectives += block
-
-///////////////
-//Greet procs//
-///////////////
-
-/datum/game_mode/proc/greet_hog_follower(datum/mind/follower_mind,colour)
- if(follower_mind in blue_deity_prophets || follower_mind in red_deity_prophets)
- follower_mind.current << "You have been appointed as the prophet of the [colour] deity! You are the only one who can communicate with your deity at will. Guide your followers, but be wary, for many will want you dead."
- else if(colour)
- follower_mind.current << "You are a follower of the [colour] cult's deity!"
- else
- follower_mind.current << "You are a follower of a cult's deity!"
-
-
-/////////////////
-//Convert procs//
-/////////////////
-
-/datum/game_mode/proc/add_hog_follower(datum/mind/follower_mind, colour = "No Colour")
- var/mob/living/carbon/human/H = follower_mind.current
- if(isloyal(H))
- H << "Your mindshield implant blocked the influence of the [colour] deity. "
- return 0
- if((follower_mind in red_deity_followers) || (follower_mind in red_deity_prophets) || (follower_mind in blue_deity_followers) || (follower_mind in blue_deity_prophets))
- H << "You already belong to a deity. Your strong faith has blocked out the conversion attempt by the followers of the [colour] deity."
- return 0
- var/obj/item/weapon/nullrod/N = H.null_rod_check()
- if(N)
- H << "Your holy weapon prevented the [colour] deity from brainwashing you."
- return 0
-
- if(colour == "red")
- red_deity_followers += follower_mind
- if(colour == "blue")
- blue_deity_followers += follower_mind
-
- H.faction |= "[colour] god"
- follower_mind.current << "You are now a follower of the [colour] deity! Follow your deity's prophet in order to complete your deity's objectives. Convert crewmembers to your cause by using your deity's nexus. And remember - there is no you, there is only the cult."
- update_hog_icons_added(follower_mind, colour)
- follower_mind.special_role = "Hand of God: [capitalize(colour)] Follower"
- follower_mind.current.attack_log += "\[[time_stamp()]\] Has been converted to the [colour] follower cult!"
- return 1
-
-
-/datum/game_mode/proc/add_god(datum/mind/god_mind, colour = "No Colour")
- remove_hog_follower(god_mind, announce = 0)
- if(colour == "red")
- red_deities += god_mind
- if(colour == "blue")
- blue_deities += god_mind
- god_mind.current.attack_log += "\[[time_stamp()]\] Has been made into a [colour] deity!"
- god_mind.special_role = "Hand of God: [colour] God"
- update_hog_icons_added(god_mind, colour)
-
-//////////////////
-//Deconvert proc//
-//////////////////
-
-/datum/game_mode/proc/remove_hog_follower(datum/mind/follower_mind, announce = 1)//deconverts both
- if(follower_mind.current)
- if(is_handofgod_cultist(follower_mind.current) || is_handofgod_prophet(follower_mind.current))
- follower_mind.remove_hog_follower_prophet()
- update_hog_icons_removed(follower_mind,"red")
- update_hog_icons_removed(follower_mind,"blue")
-
- var/mob/living/carbon/human/H = follower_mind.current
- H.faction -= "red god"
- H.faction -= "blue god"
-
- if(announce)
- follower_mind.current.attack_log += "\[[time_stamp()]\] Has been deconverted from a deity's cult!"
- follower_mind.current << "Your mind has been cleared from the brainwashing the followers have done to you. Now you serve yourself and the crew."
- for(var/mob/living/M in view(follower_mind.current))
- M << "[follower_mind.current] looks like their faith is shattered. They're no longer a cultist!"
-
-
-
-//////////////////////
-// Mob helper procs //
-//////////////////////
-
-/proc/is_handofgod_god(A)
- if(istype(A, /mob/camera/god))
- return 1
- return 0
-
-
-/proc/is_handofgod_bluecultist(A)
- if(ishuman(A))
- var/mob/living/carbon/human/H = A
- if(H.mind)
- if(H.mind in ticker.mode.blue_deity_followers|ticker.mode.blue_deity_prophets)
- return 1
- return 0
-
-
-/proc/is_handofgod_redcultist(A)
- if(ishuman(A))
- var/mob/living/carbon/human/H = A
- if(H.mind)
- if(H.mind in ticker.mode.red_deity_followers|ticker.mode.red_deity_prophets)
- return 1
- return 0
-
-
-/proc/is_handofgod_blueprophet(A)
- if(ishuman(A))
- var/mob/living/carbon/human/H = A
- if(H.mind)
- if(H.mind in ticker.mode.blue_deity_prophets)
- return 1
- return 0
-
-
-/proc/is_handofgod_redprophet(A)
- if(ishuman(A))
- var/mob/living/carbon/human/H = A
- if(H.mind)
- if(H.mind in ticker.mode.red_deity_prophets)
- return 1
- return 0
-
-
-
-/proc/is_handofgod_cultist(A) //any of them what so ever, blue, red, hot pink, whatever.
- if(is_handofgod_redcultist(A))
- return 1
- if(is_handofgod_bluecultist(A))
- return 1
- return 0
-
-
-/proc/is_handofgod_prophet(A) //any of them what so ever, blue, red, hot pink, whatever
- if(ishuman(A))
- var/mob/living/carbon/human/H = A
- if(H.mind)
- if(H.mind in ticker.mode.blue_deity_prophets|ticker.mode.red_deity_prophets)
- return 1
- return 0
-
-
-/mob/camera/god/proc/is_handofgod_myprophet(A)
- if(!ishuman(A))
- return 0
- var/mob/living/carbon/human/H = A
- if(!H.mind)
- return 0
- if(side == "red")
- if(H.mind in ticker.mode.red_deity_prophets)
- return 1
- else if(side == "blue")
- if(H.mind in ticker.mode.blue_deity_prophets)
- return 1
-
-
-/mob/camera/god/proc/is_handofgod_myfollowers(mob/A)
- if(!ishuman(A))
- return 0
- var/mob/living/carbon/human/H = A
- if(!H.mind)
- return 0
- if(side == "red")
- if(H.mind in ticker.mode.red_deity_prophets|ticker.mode.red_deity_followers)
- return 1
- else if(side == "blue")
- if(H.mind in ticker.mode.blue_deity_prophets|ticker.mode.blue_deity_followers)
- return 1
-
-//////////////////////
-//Roundend Reporting//
-//////////////////////
-
-
-/datum/game_mode/hand_of_god/declare_completion()
- if(red_deities.len)
- var/text = "
The red cult:"
- for(var/datum/mind/red_god in red_deities)
- var/godwin = 1
-
- text += "
[red_god.key] was the red deity, [red_god.name] ("
- if(red_god.current)
- if(red_god.current.stat == DEAD)
- text += "died"
- else
- text += "survived"
- else
- text += "ceased existing"
- text += ")"
- if(red_deity_prophets.len)
- for(var/datum/mind/red_prophet in red_deity_prophets)
- text += "
The red prophet was [red_prophet.name] ([red_prophet.key])"
- else
- text += "
the red prophet was killed for their beliefs."
-
- text += "
Red follower count: [red_deity_followers.len]"
- text += "
Red followers: "
- for(var/datum/mind/player in red_deity_followers)
- text += "[player.name] ([player.key]), "
-
- var/objectives = ""
- if(red_god.objectives.len)
- var/count = 1
- for(var/datum/objective/O in red_god.objectives)
- if(O.check_completion())
- objectives += "
Objective #[count]: [O.explanation_text] Success!"
- feedback_add_details("god_objective","[O.type]|SUCCESS")
- else
- objectives += "
Objective #[count]: [O.explanation_text] Fail."
- feedback_add_details("god_objective","[O.type]|FAIL")
- godwin = 0
- count++
-
- text += objectives
-
- if(godwin)
- text += "
The red cult and deity were successful!"
- feedback_add_details("god_success","SUCCESS")
- else
- text += "
The red cult and deity have failed!"
- feedback_add_details("god_success","FAIL")
-
- text += "
"
-
- world << text
-
- if(blue_deities.len)
- var/text = "
The blue cult:"
- for(var/datum/mind/blue_god in blue_deities)
- var/godwin = 1
-
- text += "
[blue_god.key] was the blue deity, [blue_god.name] ("
- if(blue_god.current)
- if(blue_god.current.stat == DEAD)
- text += "died"
- else
- text += "survived"
- else
- text += "ceased existing"
- text += ")"
- if(blue_deity_prophets.len)
- for(var/datum/mind/blue_prophet in blue_deity_prophets)
- text += "
The blue prophet was [blue_prophet.name] ([blue_prophet.key])"
- else
- text += "
the blue prophet was killed for their beliefs."
-
- text += "
Blue follower count: [blue_deity_followers.len]"
- text += "
Blue followers: "
- for(var/datum/mind/player in blue_deity_followers)
- text += "[player.name] ([player.key])"
-
- var/objectives = ""
- if(blue_god.objectives.len)
- var/count = 1
- for(var/datum/objective/O in blue_god.objectives)
- if(O.check_completion())
- objectives += "
Objective #[count]: [O.explanation_text] Success!"
- feedback_add_details("god_objective","[O.type]|SUCCESS")
- else
- objectives += "
Objective #[count]: [O.explanation_text] Fail."
- feedback_add_details("god_objective","[O.type]|FAIL")
- godwin = 0
- count++
-
- text += objectives
-
- if(godwin)
- text += "
The blue cult and deity were successful!"
- feedback_add_details("god_success","SUCCESS")
- else
- text += "
The blue cult and deity have failed!"
- feedback_add_details("god_success","FAIL")
-
- text += "
"
-
- world << text
-
- ..()
- return 1
-
-
-/datum/game_mode/proc/update_hog_icons_added(datum/mind/hog_mind,side)
- var/hud_key
- var/rank = 0
- if(side == "red")
- hud_key = ANTAG_HUD_HOG_RED
- if(is_handofgod_redprophet(hog_mind.current))
- rank = 1
-
- else if(side == "blue")
- hud_key = ANTAG_HUD_HOG_BLUE
- if(is_handofgod_blueprophet(hog_mind.current))
- rank = 1
-
- if(is_handofgod_god(hog_mind.current))
- rank = 2
-
- if(hud_key)
- var/datum/atom_hud/antag/hog_hud = huds[hud_key]
- hog_hud.join_hud(hog_mind.current)
- set_antag_hud(hog_mind.current, "hog-[side]-[rank]")
-
-
-/datum/game_mode/proc/update_hog_icons_removed(datum/mind/hog_mind,side)
- var/hud_key
- if(side == "red")
- hud_key = ANTAG_HUD_HOG_RED
- else if(side == "blue")
- hud_key = ANTAG_HUD_HOG_BLUE
-
- if(hud_key)
- var/datum/atom_hud/antag/hog_hud = huds[hud_key]
- hog_hud.leave_hud(hog_mind.current)
- set_antag_hud(hog_mind.current,null)
diff --git a/code/game/gamemodes/handofgod/actions.dm b/code/game/gamemodes/handofgod/actions.dm
deleted file mode 100644
index 766a2522fde..00000000000
--- a/code/game/gamemodes/handofgod/actions.dm
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Prophet's innate godspeak */
-/datum/action/innate/godspeak
- name = "Godspeak"
- button_icon_state = "godspeak"
- check_flags = AB_CHECK_CONSCIOUS
- var/mob/camera/god/god = null
-
-/datum/action/innate/godspeak/IsAvailable()
- if(..())
- if(god)
- return 1
- return 0
-
-/datum/action/innate/godspeak/Activate()
- var/msg = input(owner,"Speak to your god","Godspeak","") as null|text
- if(!msg)
- return
- var/rendered = "Prophet [owner]: [msg]"
- god << rendered
- owner << rendered
- for(var/mob/M in mob_list)
- if(isobserver(M))
- var/link = FOLLOW_LINK(M, owner)
- M << "[link] [rendered]"
-
-/datum/action/innate/godspeak/Destroy()
- god = null
- return ..()
diff --git a/code/game/gamemodes/handofgod/god.dm b/code/game/gamemodes/handofgod/god.dm
deleted file mode 100644
index 5a238736052..00000000000
--- a/code/game/gamemodes/handofgod/god.dm
+++ /dev/null
@@ -1,290 +0,0 @@
-
-/mob/camera/god
- name = "deity" //Auto changes to the player's deity name/random name
- real_name = "deity"
- icon = 'icons/mob/mob.dmi'
- icon_state = "marker"
- invisibility = 60
- see_in_dark = 0
- see_invisible = 55
- sight = SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
- languages_spoken = ALL
- languages_understood = ALL
- hud_possible = list(ANTAG_HUD)
- mouse_opacity = 0 //can't be clicked
-
- var/faith = 100 //For initial prophet appointing/stupid purchase
- var/max_faith = 100
- var/side = "neutral" //Red or Blue for the gamemode
- var/obj/structure/divine/nexus/god_nexus = null //The source of the god's power in this realm, kill it and the god is kill
- var/nexus_required = FALSE //If the god dies from losing it's nexus, defaults to off so that gods don't instantly die at roundstart
- var/followers_required = 0 //Same as above
- var/alive_followers = 0
- var/list/structures = list()
- var/list/conduits = list()
- var/prophets_sacrificed_in_name = 0
- var/image/ghostimage = null //For observer with darkness off visiblity
- var/list/prophets = list()
- var/datum/action/innate/godspeak/speak2god
-
-/mob/camera/god/New()
- ..()
- update_icons()
- build_hog_construction_lists()
-
- //Force nexuses after 15 minutes in hand of god mode
- if(ticker && ticker.mode && ticker.mode.name == "hand of god")
- addtimer(src, "forceplacenexus", 9000, FALSE)
-
-
-//Rebuilds the list based on the gamemode's lists
-//As they are the most accurate each tick
-/mob/camera/god/proc/get_my_followers()
- switch(side)
- if("red")
- . = ticker.mode.red_deity_followers|ticker.mode.red_deity_prophets
- if("blue")
- . = ticker.mode.blue_deity_followers|ticker.mode.blue_deity_prophets
- else
- . = list()
-
-
-/mob/camera/god/Destroy()
- var/list/followers = get_my_followers()
- for(var/datum/mind/F in followers)
- if(F.current)
- F.current << "Your god is DEAD!"
- for(var/X in prophets)
- speak2god.Remove(X)
- ghost_darkness_images -= ghostimage
- updateallghostimages()
- return ..()
-
-
-
-/mob/camera/god/proc/forceplacenexus()
- if(god_nexus)
- return
-
- if(ability_cost(0,1,0))
- place_nexus()
-
- else
- if(blobstart.len) //we're on invalid turf, try to pick from blobstart
- loc = pick(blobstart)
- place_nexus() //if blobstart fails, places on dense turf, but better than nothing
- src << "You failed to place your nexus, and it has been placed for you!"
-
-
-/mob/camera/god/update_icons()
- icon_state = "[initial(icon_state)]-[side]"
-
- if(ghostimage)
- ghost_darkness_images -= ghostimage
-
- ghostimage = image(src.icon,src,src.icon_state)
- ghost_darkness_images |= ghostimage
- updateallghostimages()
-
-
-/mob/camera/god/Stat()
- ..()
- if(statpanel("Status"))
- if(god_nexus)
- stat("Nexus health: ", god_nexus.health)
- stat("Followers: ", alive_followers)
- stat("Faith: ", "[faith]/[max_faith]")
-
-
-/mob/camera/god/Login()
- ..()
- sync_mind()
- src << "You are a deity!"
- src << "You are a deity and are worshipped by a cult! You are rather weak right now, but that will change as you gain more followers."
- src << "You will need to place an anchor to this world, a Nexus, in two minutes. If you don't, one will be placed immediately below you."
- src << "Your Follower count determines how many people believe in you and are a part of your cult."
- src << "Your Nexus Integrity tells you the condition of your nexus. If your nexus is destroyed, you will die. Place your Nexus on a safe, isolated place, that is still accessible to your followers."
- src << "Your Faith is used to interact with the world. This will regenerate on its own, and it goes faster when you have more followers and power pylons."
- src << "The first thing you should do after placing your nexus is to appoint a prophet. Only prophets can hear you talk, unless you use an expensive power."
- update_health_hud()
-
-
-/mob/camera/god/update_health_hud()
- if(god_nexus && hud_used && hud_used.healths)
- hud_used.healths.maptext = " [god_nexus.health]
"
-
-
-/mob/camera/god/proc/add_faith(faith_amt)
- if(faith_amt)
- faith = round(Clamp(faith+faith_amt, 0, max_faith))
- if(hud_used && hud_used.deity_power_display)
- hud_used.deity_power_display.maptext = " [faith]
"
-
-
-
-/mob/camera/god/proc/place_nexus()
- if(god_nexus || (z != 1))
- return 0
-
- var/obj/structure/divine/nexus/N = new(get_turf(src))
- N.assign_deity(src)
- god_nexus = N
- nexus_required = TRUE
- verbs -= /mob/camera/god/verb/constructnexus
- //verbs += /mob/camera/god/verb/movenexus //Translocators have no sprite
- update_health_hud()
-
- var/area/A = get_area(src)
- if(A)
- var/areaname = A.name
- var/list/followers = get_my_followers()
- for(var/datum/mind/F in followers)
- if(F.current)
- F.current << "Your god's nexus is in \the [areaname]"
-
-
-/mob/camera/god/verb/freeturret()
- set category = "Deity"
- set name = "Free Turret (0)"
- set desc = "Place a single turret, for 0 faith."
-
- if(!ability_cost(0,1,1))
- return
- var/obj/structure/divine/defensepylon/DP = new(get_turf(src))
- DP.assign_deity(src)
- verbs -= /mob/camera/god/verb/freeturret
-
-
-
-/mob/camera/god/proc/update_followers()
- alive_followers = 0
- var/list/all_followers = get_my_followers()
- for(var/datum/mind/F in all_followers)
- if(F.current && F.current.stat != DEAD)
- alive_followers++
-
- if(hud_used && hud_used.deity_follower_display)
- hud_used.deity_follower_display.maptext = " [alive_followers]
"
-
-
-/mob/camera/god/proc/check_death()
- if(!alive_followers)
- src << "You no longer have any followers. You shudder as you feel your existence cease..."
- if(god_nexus && !qdeleted(god_nexus))
- god_nexus.visible_message("\The [src] suddenly disappears!")
- qdel(god_nexus)
- qdel(src)
-
-
-/mob/camera/god/say(msg)
- if(!msg)
- return
- if(client)
- if(client.prefs.muted & MUTE_IC)
- src << "You cannot send IC messages (muted)."
- return
- if(src.client.handle_spam_prevention(msg,MUTE_IC))
- return
- if(stat)
- return
-
- god_speak(msg)
-
-
-/mob/camera/god/proc/god_speak(msg)
- log_say("Hand of God: [capitalize(side)] God/[key_name(src)] : [msg]")
- msg = trim(copytext(sanitize(msg), 1, MAX_MESSAGE_LEN))
- if(!msg)
- return
-
- msg = say_quote(msg, get_spans())
- var/rendered = "Divine Telepathy, [name] [msg]"
- src << rendered
-
- for(var/mob/M in mob_list)
- if(is_handofgod_myfollowers(M))
- M << rendered
- if(isobserver(M))
- var/link = FOLLOW_LINK(M, src)
- M << "[link] [rendered]"
-
-
-/mob/camera/god/emote(act,m_type = 1 ,msg = null)
- return
-
-
-/mob/camera/god/Move(NewLoc, Dir = 0)
- loc = NewLoc
-
-
-
-/mob/camera/god/Topic(href, href_list)
- if(href_list["create_structure"])
- if(!ability_cost(75,1,1))
- return
-
- var/obj/structure/divine/construct_type = text2path(href_list["create_structure"]) //it's a path but we need to initial() some vars
- if(!construct_type)
- return
-
- add_faith(-75)
- var/obj/structure/divine/construction_holder/CH = new(get_turf(src))
- CH.assign_deity(src)
- CH.setup_construction(construct_type)
- CH.visible_message("[src] has created a transparent, unfinished [initial(construct_type.name)]. It can be finished by adding materials.")
- src << "You may click a construction site to cancel it, but only faith is refunded."
- structure_construction_ui(src)
- return
-
- if(href_list["place_trap"])
- if(!ability_cost(20,1,1))
- return
-
- var/atom/trap_type = text2path(href_list["place_trap"])
- if(!trap_type)
- return
-
- src << "You lay \a [initial(trap_type.name)]"
- add_faith(-20)
- new trap_type(get_turf(src))
- return
-
- ..()
-
-
-/mob/camera/god/proc/structure_construction_ui(mob/camera/god/user)
- var/dat = ""
- for(var/t in global_handofgod_structuretypes)
- if(global_handofgod_structuretypes[t])
- var/obj/structure/divine/apath = global_handofgod_structuretypes[t]
- dat += "
[capitalize(t)]
"
- var/imgstate = initial(apath.autocolours) ? "[initial(apath.icon_state)]-[side]" : "[initial(apath.icon_state)]"
- var/icon/I = icon('icons/obj/hand_of_god_structures.dmi',imgstate)
- var/img_component = lowertext(t)
- //I hate byond, but atleast it autocaches these so it's only 1*number_of_structures worth of actual calls
- user << browse_rsc(I,"hog_structure-[img_component].png")
- dat += "
"
- dat += "Description: [initial(apath.desc)]
"
- dat += "Construct [capitalize(t)]
"
-
- var/datum/browser/popup = new(src, "structures","Construct Structure",350,500)
- popup.set_content(dat)
- popup.open()
-
-
-/mob/camera/god/proc/trap_construction_ui(mob/camera/god/user)
- var/dat = ""
- for(var/t in global_handofgod_traptypes)
- if(global_handofgod_traptypes[t])
- var/obj/structure/divine/trap/T = global_handofgod_traptypes[t]
- dat += "[capitalize(t)]
"
- var/icon/I = icon('icons/obj/hand_of_god_structures.dmi',"[initial(T.icon_state)]")
- var/img_component = lowertext(t)
- user << browse_rsc(I,"hog_trap-[img_component].png")
- dat += "
"
- dat += "Description: [initial(T.desc)]
"
- dat += "Place [capitalize(t)]
"
-
- var/datum/browser/popup = new(src, "traps", "Place Trap",350,500)
- popup.set_content(dat)
- popup.open()
diff --git a/code/game/gamemodes/handofgod/objectives.dm b/code/game/gamemodes/handofgod/objectives.dm
deleted file mode 100644
index dc31d67f46c..00000000000
--- a/code/game/gamemodes/handofgod/objectives.dm
+++ /dev/null
@@ -1,129 +0,0 @@
-
-/datum/objective/build
- dangerrating = 15
- martyr_compatible = 1
-
-
-/datum/objective/build/proc/gen_amount_goal(lower, upper)
- target_amount = rand(lower, upper)
- explanation_text = "Build [target_amount] shrines."
- return target_amount
-
-
-/datum/objective/build/check_completion()
- if(!owner || !owner.current)
- return 0
-
- var/shrines = 0
- if(is_handofgod_god(owner.current))
- var/mob/camera/god/G = owner.current
- for(var/obj/structure/divine/shrine/S in G.structures)
- S++
-
- return (shrines >= target_amount)
-
-
-
-/datum/objective/deicide
- dangerrating = 20
- martyr_compatible = 1
-
-/datum/objective/deicide/check_completion()
- if(target)
- if(target.current) //Gods are deleted when they lose
- return 0
- return 1
-
-
-/datum/objective/deicide/find_target()
- if(!owner || !owner.current)
- return
-
- if(is_handofgod_god(owner.current))
- var/mob/camera/god/G = owner.current
- if(G.side == "red")
- if(ticker.mode.blue_deities.len)
- target = ticker.mode.blue_deities[1]
- if(G.side == "blue")
- if(ticker.mode.red_deities.len)
- target = ticker.mode.red_deities[1]
- if(!target)
- return 0
- update_explanation_text()
-
-/datum/objective/deicide/update_explanation_text()
- ..()
- if(target && target.current)
- explanation_text = "Phase [target.name], the false god, out of this plane of existence.."
- else
- explanation_text = "Free Objective"
-
-
-
-/datum/objective/follower_block
- explanation_text = "Do not allow any followers of the false god to escape on the station's shuttle alive."
- dangerrating = 25
- martyr_compatible = 1
-
-/datum/objective/follower_block/check_completion()
- var/side = "ABORT"
- if(is_handofgod_redcultist(owner.current))
- side = "red"
- else if(is_handofgod_bluecultist(owner.current))
- side = "blue"
- if(side == "ABORT")
- return 0
-
- var/area/A = SSshuttle.emergency.areaInstance
-
- for(var/mob/living/player in player_list)
- if(player.mind && player.stat != DEAD && get_area(player) == A)
- if(side == "red")
- if(is_handofgod_bluecultist(player))
- return 0
- else if(side == "blue")
- if(is_handofgod_redcultist(player))
- return 0
- return 1
-
-
-
-/datum/objective/escape_followers
- dangerrating = 5
-
-
-/datum/objective/escape_followers/proc/gen_amount_goal(lower,upper)
- target_amount = rand(lower,upper)
- explanation_text = "Your will must surpass this station. Having [target_amount] followers escape on the shuttle or pods will allow that."
- return target_amount
-
-
-/datum/objective/escape_followers/check_completion()
- var/escaped = 0
- if(is_handofgod_god(owner.current))
- var/mob/camera/god/G = owner.current
- if(G.side == "red")
- for(var/datum/mind/follower_mind in ticker.mode.red_deity_followers)
- if(follower_mind.current && follower_mind.current.stat != DEAD)
- if(follower_mind.current.onCentcom())
- escaped++
-
- if(G.side == "blue")
- for(var/datum/mind/follower_mind in ticker.mode.blue_deity_followers)
- if(follower_mind.current && follower_mind.current.stat != DEAD)
- if(follower_mind.current.onCentcom())
- escaped++
-
- return (escaped >= target_amount)
-
-
-/datum/objective/sacrifice_prophet
- explanation_text = "A false prophet is preaching their god's faith on the station. Sacrificing them will show the mortals who the true god is."
- dangerrating = 10
-
-
-/datum/objective/sacrifice_prophet/check_completion()
- var/mob/camera/god/G = owner.current
- if(istype(G))
- return G.prophets_sacrificed_in_name
- return 0
diff --git a/code/game/gamemodes/handofgod/powers.dm b/code/game/gamemodes/handofgod/powers.dm
deleted file mode 100644
index 30b3365cfcd..00000000000
--- a/code/game/gamemodes/handofgod/powers.dm
+++ /dev/null
@@ -1,363 +0,0 @@
-/mob/camera/god/proc/ability_cost(cost = 0,structures = 0, requires_conduit = 0, can_place_near_enemy_nexus = 0)
- if(faith < cost)
- src << "You lack the faith!"
- return 0
-
- if(structures)
- if(!isturf(loc) || istype(loc, /turf/open/space))
- src << "Your structure would just float away, you need stable ground!"
- return 0
-
- var/turf/T = get_turf(src)
- if(T)
- if(T.density)
- src << "There is something blocking your structure!"
- return 0
-
- for(var/atom/movable/AM in T)
- if(AM == src)
- continue
- if(AM.density)
- src << "There is something blocking your structure!"
- return 0
-
- if(requires_conduit)
- //Organised this way as there can be multiple conduits, so it's more likely to be a conduit check.
- var/valid = 0
-
- for(var/obj/structure/divine/conduit/C in conduits)
- if(get_dist(src, C) <= CONDUIT_RANGE)
- valid++
- break
-
- if(!valid)
- if(get_dist(src, god_nexus) <= CONDUIT_RANGE)
- valid++
-
- if(!valid)
- src << "You must be near your Nexus or a Conduit to do this!"
- return 0
-
- if(!can_place_near_enemy_nexus)
- var/datum/mind/enemy
- switch(side)
- if("red")
- if(ticker.mode.blue_deities.len)
- enemy = ticker.mode.blue_deities[1]
- if("blue")
- if(ticker.mode.red_deities.len)
- enemy = ticker.mode.red_deities[1]
-
- if(enemy && is_handofgod_god(enemy.current))
- var/mob/camera/god/enemy_god = enemy.current
- if(enemy_god.god_nexus && (get_dist(src,enemy_god.god_nexus) <= CONDUIT_RANGE*2))
- src << "You are too close to the other god's stronghold!"
- return 0
-
- return 1
-
-
-/mob/camera/god/verb/returntonexus()
- set category = "Deity"
- set name = "Goto Nexus"
- set desc = "Teleports you to your next instantly."
-
- if(god_nexus)
- Move(get_turf(god_nexus))
- else
- src << "You don't even have a Nexus, construct one."
-
-
-/mob/camera/god/verb/jumptofollower()
- set category = "Deity"
- set name = "Jump to Follower"
- set desc = "Teleports you to one of your followers."
- var/list/following = list()
- if(side == "red")
- following = ticker.mode.red_deity_followers|ticker.mode.red_deity_prophets
- else if(side == "blue")
- following = ticker.mode.blue_deity_followers|ticker.mode.blue_deity_prophets
- else
- src << "You are unaligned, and thus do not have followers"
- return
-
- var/datum/mind/choice = input("Choose a follower","Jump to Follower") as null|anything in following
- if(choice && choice.current)
- Move(get_turf(choice.current))
-
-
-/mob/camera/god/verb/newprophet()
- set category = "Deity"
- set name = "Appoint Prophet (100)"
- set desc = "Appoint one of your followers as your Prophet, who can hear your words"
-
- var/list/following = list()
-
- if(!ability_cost(100))
- return
- if(side == "red")
- var/datum/mind/old_proph = locate() in ticker.mode.red_deity_prophets
- if(old_proph && old_proph.current && old_proph.current.stat != DEAD)
- src << "You can only have one prophet alive at a time."
- return
- else
- following = ticker.mode.red_deity_followers
- else if(side == "blue")
- var/datum/mind/old_proph = locate() in ticker.mode.blue_deity_prophets
- if(old_proph && old_proph.current && old_proph.current.stat != DEAD)
- src << "You can only have one prophet alive at a time."
- return
- else
- following = ticker.mode.blue_deity_followers
-
- else
- src << "You are unalligned, and thus do not have prophets"
- return
-
- var/datum/mind/choice = input("Choose a follower to make into your prophet","Prophet Uplifting") as null|anything in following
- if(choice && choice.current && choice.current.stat != DEAD)
- src << "You choose [choice.current] as your prophet."
- choice.make_Handofgod_prophet(side)
- speak2god = new()
- speak2god.god = src
- speak2god.Grant(choice.current)
-
- //Prophet gear
- var/mob/living/carbon/human/H = choice.current
- var/popehat = null
- var/popestick = null
- var/success = ""
- switch(side)
- if("red")
- popehat = /obj/item/clothing/head/helmet/plate/crusader/prophet/red
- popestick = /obj/item/weapon/godstaff/red
- if("blue")
- popehat = /obj/item/clothing/head/helmet/plate/crusader/prophet/blue
- popestick = /obj/item/weapon/godstaff/blue
-
- if(popehat)
- var/obj/item/clothing/head/helmet/plate/crusader/prophet/P = new popehat()
-
- if(H.equip_to_slot_if_possible(P,slot_in_backpack,0,1,1))
- success = "It is in your backpack."
- else
- H.unEquip(H.head)
- H.equip_to_slot_or_del(P,slot_head)
- success = "It is on your head."
-
- if(success)
- H << "A powerful hat has been bestowed upon you, you will need to wear it to utilize your staff fully."
- H << "[success]"
-
- if(popestick)
- var/obj/item/weapon/godstaff/G = new popestick()
- G.god = src
- if(!H.equip_to_slot_if_possible(G,slot_in_backpack,0,1,1))
- if(!H.put_in_hands(G))
- G.loc = get_turf(H)
- success = "It is on the floor..."
- else
- success = "It is in your hands..."
- else
- success = "It is in your backpack..."
-
- if(success)
- H << "A powerful staff has been bestowed upon you, you can use this to convert the false god's structures!"
- H << "[success]"
- //end prophet gear
-
- add_faith(-100)
-
-
-/mob/camera/god/verb/talk(msg as text)
- set category = "Deity"
- set name = "Talk to Anyone (20)"
- set desc = "Allows you to send a message to anyone, regardless of their faith."
- if(!ability_cost(20))
- return
- var/mob/choice = input("Choose who you wish to talk to", "Talk to ANYONE") as null|anything in mob_list
- if(choice)
- var/original = msg
- msg = "You hear a voice coming from everywhere and nowhere... [msg]"
- choice << msg
- src << "You say the following to [choice], [original]"
- add_faith(-20)
-
-
-/mob/camera/god/verb/smite()
- set category = "Deity"
- set name = "Smite (40)"
- set desc = "Hits anything under you with a moderate amount of damage."
-
- if(!ability_cost(40,0,1))
- return
- if(!range(7,god_nexus))
- src << "You lack the strength to smite this far from your nexus."
- return
-
- var/has_smitten = 0 //Hast thou been smitten, infidel?
- for(var/mob/living/L in get_turf(src))
- L.adjustFireLoss(20)
- L.adjustBruteLoss(20)
- L << "You feel the wrath of [name]!"
- has_smitten = 1
- if(has_smitten)
- add_faith(-40)
-
-
-/mob/camera/god/verb/disaster()
- set category = "Deity"
- set name = "Invoke Disaster (300)" //difficult to reach without lots of followers
- set desc = "Tug at the fibres of reality itself and bend it to your whims!"
-
- if(!ability_cost(300,0,1))
- return
-
- var/event = pick(/datum/round_event/meteor_wave, /datum/round_event/communications_blackout, /datum/round_event/radiation_storm, /datum/round_event/carp_migration,
- /datum/round_event/spacevine, /datum/round_event/vent_clog, /datum/round_event/wormholes)
- if(event)
- new event()
- add_faith(-300)
-
-
-/mob/camera/god/verb/constructnexus()
- set category = "Deity"
- set name = "Construct Nexus"
- set desc = "Instantly creates your nexus, You can only do this once, make sure you're happy with it!"
-
- if(!ability_cost(0,1,0))
- return
-
- place_nexus()
-
-
-/* //Transolocators have no sprite
-/mob/camera/god/verb/movenexus()
- set category = "Deity"
- set name = "Relocate Nexus (50)"
- set desc = "Instantly relocates your nexus to an existing translocator belonging to your faith, this destroys the translocator in the process"
-
- if(ability_cost(50,0,0) && god_nexus)
- var/list/translocators = list()
- var/list/used_keys = list()
- for(var/obj/structure/divine/translocator/T in structures)
- translocators["[T.name] ([get_area(T)])"] = T
-
- if(!translocators.len)
- src << "You have no translocators!"
- return
-
- var/picked = input(src,"Choose a translocator","Relocate Nexus") as null|anything in translocators
- if(!picked || !translocators[picked])
- return
-
- var/obj/structure/divine/translocator/T = translocators[T]
- var/turf/Tturf = get_turf(T)
- god_nexus.loc = T
- translocators[picked] = null
- add_faith(-50)
- qdel(T)
-*/
-
-/mob/camera/god/verb/construct_structures()
- set category = "Deity"
- set name = "Construct Structure (75)"
- set desc = "Create the foundation of a divine object."
-
- if(!ability_cost(75,1,1))
- return
-
- structure_construction_ui(src)
-
-
-/mob/camera/god/verb/construct_traps()
- set category = "Deity"
- set name = "Construct Trap (20)"
- set desc = "Creates a ward or trap."
-
- if(!ability_cost(20,1,1))
- return
-
- trap_construction_ui(src)
-
-
-
-/mob/camera/god/verb/construct_items()
- set category = "Deity"
- set name = "Construct Items (20)"
- set desc = "Construct some items for your followers"
-
- if(!ability_cost(20,1,1))
- return
-
- var/list/item_types = list("claymore sword" = /obj/item/weapon/claymore/hog)
- if(side == "red")
- item_types["red banner"] = /obj/item/weapon/banner/red
- item_types["red bannerbackpack"] = /obj/item/weapon/storage/backpack/bannerpack/red
- item_types["red armour"] = /obj/item/weapon/storage/box/itemset/crusader/red
-
- else if(side == "blue")
- item_types["blue banner"] = /obj/item/weapon/banner/blue
- item_types["blue bannerbackpack"] = /obj/item/weapon/storage/backpack/bannerpack/blue
- item_types["blue armour"] = /obj/item/weapon/storage/box/itemset/crusader/blue
-
-
- var/item = input("Choose what you wish to create.", "Divine Items") as null|anything in item_types
- if(!item || !item_types[item] || !ability_cost(20,1,1))
- return
-
- src << "You produce \a [item]"
- add_faith(-20)
-
- var/itemtype = item_types[item]
- new itemtype (get_turf(src))
-
-
-
-/mob/camera/god/verb/veil_structures()
- set category = "Deity"
- set name = "Veil Structures (20)"
- set desc = "Hide your structures from sight and touch, but prevent yourself from using them."
-
- if(!ability_cost(20,1,1))
- return
-
- src << "You focus your powers and start dragging your influence into the spiritual plane."
- for(var/mob/M in orange(3,src))//Yes I know this is terrible, but visible message doesnt work for this
- M << "The air begins to shimmer..."
- if(do_after(src, 30, 0, src))
- for(var/obj/structure/divine/R in orange(3,src))
- if(istype(R, /obj/structure/divine/nexus)|| istype(R, /obj/structure/divine/trap)||(src.side != R.side))
- continue
- R.visible_message("[R] fades away.")
- R.invisibility = 55
- R.alpha = 100 //To help ghosts distinguish hidden structures
- R.density = 0
- R.deactivate()
- src << "You hide your influence from view"
- add_faith(-20)
-
-
-/mob/camera/god/verb/reveal_structures()
- set category = "Deity"
- set name = "Reveal Structures (20)"
- set desc = "Make your structures visible again and allow them to be used."
-
- if(!ability_cost(20,1,1))
- return
-
- src << "You focus your powers and start dragging your influence into the material plane."
- for(var/mob/M in orange(3,src))//Yes I know this is terrible, but visible message doesnt work for this
- M << "The air begins to shimmer..."
- if(do_after(src, 40, 0, src))
- for(var/obj/structure/divine/R in orange(3,src))
- if(istype(R, /obj/structure/divine/nexus)|| istype(R, /obj/structure/divine/trap)||(src.side != R.side))
- continue
- R.visible_message("[R] suddenly appears!")
- R.invisibility = 0
- R.alpha = initial(R.alpha)
- R.density = initial(R.density)
- R.activate()
- src << "You bring your influence into view"
- add_faith(-20)
-
diff --git a/code/game/gamemodes/handofgod/structures.dm b/code/game/gamemodes/handofgod/structures.dm
deleted file mode 100644
index 79d6615d06b..00000000000
--- a/code/game/gamemodes/handofgod/structures.dm
+++ /dev/null
@@ -1,661 +0,0 @@
-
-/proc/build_hog_construction_lists()
- if(global_handofgod_traptypes.len && global_handofgod_structuretypes.len)
- return
-
- var/list/types = subtypesof(/obj/structure/divine) - /obj/structure/divine/trap
- for(var/T in types)
- var/obj/structure/divine/D = T
- if(initial(D.constructable))
- if(initial(D.trap))
- global_handofgod_traptypes[initial(D.name)] = T
- else
- global_handofgod_structuretypes[initial(D.name)] = T
-
-/obj/structure/divine
- name = "divine construction site"
- icon = 'icons/obj/hand_of_god_structures.dmi'
- desc = "An unfinished divine building"
- anchored = 1
- density = 1
- var/constructable = TRUE
- var/trap = FALSE
- var/metal_cost = 0
- var/glass_cost = 0
- var/lesser_gem_cost = 0
- var/greater_gem_cost = 0
- var/mob/camera/god/deity
- var/side = "neutral" //"blue" or "red", also used for colouring structures when construction is started by a deity
- var/health = 100
- var/maxhealth = 100
- var/deactivated = 0 //Structures being hidden can't be used. Mainly to prevent invisible defense pylons.
- var/autocolours = TRUE //do we colour to our side?
-
-/obj/structure/divine/New()
- ..()
-
-/obj/structure/divine/proc/deactivate()
- deactivated = 1
-
-/obj/structure/divine/proc/activate()
- deactivated = 0
-
-
-/obj/structure/divine/proc/update_icons()
- if(autocolours)
- icon_state = "[initial(icon_state)]-[side]"
-
-
-/obj/structure/divine/Destroy()
- if(deity)
- deity.structures -= src
- return ..()
-
-
-
-/obj/structure/divine/attackby(obj/item/I, mob/user)
-
- //Structure conversion/capture
- if(istype(I, /obj/item/weapon/godstaff))
- if(!is_handofgod_cultist(user))
- user << "You're not quite sure what the hell you're even doing."
- return
- var/obj/item/weapon/godstaff/G = I
- if(G.god && deity != G.god)
- assign_deity(G.god, alert_old_deity = TRUE)
- visible_message("\The [src] has been captured by [user]!")
- else
- return ..()
-
-/obj/structure/divine/attacked_by(obj/item/I, mob/living/user)
- ..()
- take_damage(I.force, I.damtype, 1)
-
-/obj/structure/divine/proc/take_damage(damage, damage_type = BRUTE, sound_effect = 1)
- switch(damage_type)
- if(BRUTE)
- if(sound_effect)
- if(damage)
- playsound(loc, 'sound/weapons/smash.ogg', 50, 1)
- else
- playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
- if(BURN)
- if(sound_effect)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
- else
- return
- health -= damage
- if(!health)
- visible_message("\The [src] was destroyed!")
- qdel(src)
-
-
-/obj/structure/divine/bullet_act(obj/item/projectile/P)
- . = ..()
- take_damage(P.damage, P.damage_type, 0)
-
-
-/obj/structure/divine/attack_alien(mob/living/carbon/alien/humanoid/user)
- user.changeNext_move(CLICK_CD_MELEE)
- user.do_attack_animation(src)
- add_hiddenprint(user)
- visible_message("\The [user] slashes at [src]!")
- playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1)
- take_damage(20, BRUTE, 0)
-
-/obj/machinery/attack_animal(mob/living/simple_animal/M)
- M.changeNext_move(CLICK_CD_MELEE)
- M.do_attack_animation(src)
- if(M.melee_damage_upper > 0 || M.obj_damage)
- M.visible_message("[M.name] smashes against \the [src.name].",\
- "You smash against the [src.name].")
- if(M.obj_damage)
- take_damage(M.obj_damage, M.melee_damage_type, 1)
- else
- take_damage(rand(M.melee_damage_lower,M.melee_damage_upper), M.melee_damage_type, 1)
-
-
-/obj/structure/divine/proc/assign_deity(mob/camera/god/new_deity, alert_old_deity = TRUE)
- if(!new_deity)
- return 0
- if(deity)
- if(alert_old_deity)
- deity << "Your [name] was captured by [new_deity]'s cult!"
- deity.structures -= src
- deity = new_deity
- deity.structures |= src
- side = deity.side
- update_icons()
- return 1
-
-
-/obj/structure/divine/construction_holder
- alpha = 125
- constructable = FALSE
- var/obj/structure/divine/construction_result = /obj/structure/divine //a path, but typed to /obj/structure/divine for initial()
-
-
-
-/obj/structure/divine/construction_holder/assign_deity(mob/camera/god/new_deity, alert_old_deity = TRUE)
- if(..())
- color = side
-
-
-/obj/structure/divine/construction_holder/attack_god(mob/camera/god/user)
- if(user.side == side && construction_result)
- user.add_faith(75)
- visible_message("[user] has cancelled \the [initial(construction_result.name)]")
- qdel(src)
-
-
-/obj/structure/divine/construction_holder/proc/setup_construction(construct_type)
- if(ispath(construct_type))
- construction_result = construct_type
- name = "[initial(construction_result.name)] construction site "
- icon_state = initial(construction_result.icon_state)
- metal_cost = initial(construction_result.metal_cost)
- glass_cost = initial(construction_result.glass_cost)
- lesser_gem_cost = initial(construction_result.lesser_gem_cost)
- greater_gem_cost = initial(construction_result.greater_gem_cost)
- desc = "An unfinished [initial(construction_result.name)]."
-
-
-/obj/structure/divine/construction_holder/attackby(obj/item/I, mob/user)
- if(!I || !user)
- return 0
-
- if(istype(I, /obj/item/stack/sheet/metal))
- var/obj/item/stack/sheet/metal/M = I
- if(metal_cost)
- var/spend = min(metal_cost, M.amount)
- user << "You add [spend] metal to \the [src]."
- metal_cost = max(0, metal_cost - spend)
- M.use(spend)
- check_completion()
- else
- user << "\The [src] does not require any more metal!"
- return
-
- if(istype(I, /obj/item/stack/sheet/glass))
- var/obj/item/stack/sheet/glass/G = I
- if(glass_cost)
- var/spend = min(glass_cost, G.amount)
- user << "You add [spend] glass to \the [src]."
- glass_cost = max(0, glass_cost - spend)
- G.use(spend)
- check_completion()
- else
- user << "\The [src] does not require any more glass!"
- return
-
- if(istype(I, /obj/item/stack/sheet/lessergem))
- var/obj/item/stack/sheet/lessergem/LG = I
- if(lesser_gem_cost)
- var/spend = min(lesser_gem_cost, LG.amount)
- user << "You add [spend] lesser gems to \the [src]."
- lesser_gem_cost = max(0, lesser_gem_cost - spend)
- LG.use(spend)
- check_completion()
- else
- user << "\The [src] does not require any more lesser gems!"
- return
-
- if(istype(I, /obj/item/stack/sheet/greatergem))
- var/obj/item/stack/sheet/greatergem/GG = I //GG!
- if(greater_gem_cost)
- var/spend = min(greater_gem_cost, GG.amount)
- user << "You add [spend] greater gems to \the [src]."
- greater_gem_cost = max(0, greater_gem_cost - spend)
- GG.use(spend)
- check_completion()
- else
- user << "\The [src] does not require any more greater gems!"
- return
-
- else
- return ..()
-
-
-/obj/structure/divine/construction_holder/proc/check_completion()
- if(!metal_cost && !glass_cost && !lesser_gem_cost && !greater_gem_cost)
- visible_message("\The [initial(construction_result.name)] is complete!")
- var/obj/structure/divine/D = new construction_result (get_turf(src))
- D.assign_deity(deity)
- qdel(src)
-
-
-/obj/structure/divine/construction_holder/examine(mob/user)
- ..()
-
- if(metal_cost || glass_cost || lesser_gem_cost || greater_gem_cost)
- user << "To finish construction it requires the following materials:"
- if(metal_cost)
- user << "[metal_cost] metal
"
- if(glass_cost)
- user << "[glass_cost] glass
"
- if(lesser_gem_cost)
- user << "[lesser_gem_cost] lesser gems
"
- if(greater_gem_cost)
- user << "[greater_gem_cost] greater gems
"
-
-
-/obj/structure/divine/nexus
- name = "nexus"
- desc = "It anchors a deity to this world. It radiates an unusual aura. Cultists protect this at all costs. It looks well protected from explosive shock."
- icon_state = "nexus"
- health = 500
- maxhealth = 500
- constructable = FALSE
- var/faith_regen_rate = 1
- var/list/powerpylons = list()
-
-
-/obj/structure/divine/nexus/ex_act()
- return
-
-/obj/structure/divine/nexus/take_damage(damage, damage_type = BRUTE, sound_effect = 1)
- switch(damage_type)
- if(BRUTE)
- if(sound_effect)
- if(damage)
- playsound(loc, 'sound/weapons/smash.ogg', 50, 1)
- else
- playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
- if(BURN)
- if(sound_effect)
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
- else
- return
- health -= damage
- if(deity)
- deity.update_health_hud()
- if(!health)
- if(!qdeleted(deity) && deity.nexus_required)
- deity << "Your nexus was destroyed. You feel yourself fading..."
- qdel(deity)
- visible_message("\The [src] was destroyed!")
- qdel(src)
-
-
-/obj/structure/divine/nexus/New()
- START_PROCESSING(SSobj, src)
-
-
-/obj/structure/divine/nexus/process()
- if(deity)
- deity.update_followers()
- deity.add_faith(faith_regen_rate + (powerpylons.len / 5) + (deity.alive_followers / 3))
- deity.max_faith = initial(deity.max_faith) + (deity.alive_followers*10) //10 followers = 100 max faith, so disaster() at around 20 followers
- deity.check_death()
-
-
-/obj/structure/divine/nexus/Destroy()
- STOP_PROCESSING(SSobj, src)
- return ..()
-
-
-/obj/structure/divine/conduit
- name = "conduit"
- desc = "It allows a deity to extend their reach. Their powers are just as potent near a conduit as a nexus."
- icon_state = "conduit"
- health = 150
- maxhealth = 150
- metal_cost = 10
- glass_cost = 5
-
-
-/obj/structure/divine/conduit/assign_deity(mob/camera/god/new_deity, alert_old_deity = TRUE)
- if(deity)
- deity.conduits -= src
- ..()
- if(deity)
- deity.conduits += src
-
-/obj/structure/divine/conduit/deactivate()
- ..()
- if(deity)
- deity.conduits -= src
-
-/obj/structure/divine/conduit/activate()
- ..()
- if(deity)
- deity.conduits += src
-
-/* //No good sprites, and not enough items to make it viable yet
-/obj/structure/divine/forge
- name = "forge"
- desc = "A forge fueled by divine might, it allows the creation of sacred and powerful artifacts. It requires common materials to craft objects."
- icon_state = "forge"
- health = 250
- maxhealth = 250
- density = 0
- maxhealth = 250
- metal_cost = 40
-*/
-
-/obj/structure/divine/convertaltar
- name = "conversion altar"
- desc = "An altar dedicated to a deity. Cultists can \"forcefully teach\" their non-aligned crewmembers to join their side and take up their deity."
- icon_state = "convertaltar"
- density = 0
- metal_cost = 10
- can_buckle = 1
-
-
-/obj/structure/divine/convertaltar/attack_hand(mob/living/user)
- ..()
- if(deactivated)
- return
- var/mob/living/carbon/human/H = locate() in get_turf(src)
- if(!is_handofgod_cultist(user))
- user << "You try to use it, but unfortunately you don't know any rituals."
- return
- if(!H)
- return
- if(!H.mind)
- user << "Only sentients may serve your deity."
- return
- if((side == "red" && is_handofgod_redcultist(user) && !is_handofgod_redcultist(H)) || (side == "blue" && is_handofgod_bluecultist(user) && !is_handofgod_bluecultist(H)))
- user << "You invoke the conversion ritual."
- ticker.mode.add_hog_follower(H.mind, side)
- else
- user << "You invoke the conversion ritual."
- user << "But the altar ignores your words..."
-
-
-/obj/structure/divine/sacrificealtar
- name = "sacrificial altar"
- desc = "An altar designed to perform blood sacrifice for a deity. The cultists performing the sacrifice will gain a powerful material to use in their forge. Sacrificing a prophet will yield even better results."
- icon_state = "sacrificealtar"
- density = 0
- metal_cost = 15
- can_buckle = 1
-
-
-/obj/structure/divine/sacrificealtar/attack_hand(mob/living/user)
- ..()
- if(deactivated)
- return
- var/mob/living/L = locate() in get_turf(src)
- if(!is_handofgod_cultist(user))
- user << "You try to use it, but unfortunately you don't know any rituals."
- return
- if(!L)
- return
- if((side == "red" && is_handofgod_redcultist(user)) || (side == "blue" && is_handofgod_bluecultist(user)))
- if((side == "red" && is_handofgod_redcultist(L)) || (side == "blue" && is_handofgod_bluecultist(L)))
- user << "You cannot sacrifice a fellow cultist."
- return
- user << "You attempt to sacrifice [L] by invoking the sacrificial ritual."
- sacrifice(L)
- else
- user << "You attempt to sacrifice [L] by invoking the sacrificial ritual."
- user << "But the altar ignores your words..."
-
-
-/obj/structure/divine/sacrificealtar/proc/sacrifice(mob/living/L)
- if(!L)
- L = locate() in get_turf(src)
- if(L)
- if(ismonkey(L))
- var/luck = rand(1,4)
- if(luck > 3)
- new /obj/item/stack/sheet/lessergem(get_turf(src))
-
- else if(ishuman(L))
- var/mob/living/carbon/human/H = L
-
- //Sacrifice altars can't teamkill
- if(side == "red" && is_handofgod_redcultist(H))
- return
- else if(side == "blue" && is_handofgod_bluecultist(H))
- return
-
- if(is_handofgod_prophet(H))
- new /obj/item/stack/sheet/greatergem(get_turf(src))
- if(deity)
- deity.prophets_sacrificed_in_name++
- else
- new /obj/item/stack/sheet/lessergem(get_turf(src))
-
- else if(isAI(L) || istype(L, /mob/living/carbon/alien/humanoid/royal/queen))
- new /obj/item/stack/sheet/greatergem(get_turf(src))
- else
- new /obj/item/stack/sheet/lessergem(get_turf(src))
- L.gib()
-
-
-/obj/structure/divine/healingfountain
- name = "healing fountain"
- desc = "A fountain containing the waters of life... or death, depending on where your allegiances lie."
- icon_state = "fountain"
- metal_cost = 10
- glass_cost = 5
- autocolours = FALSE
- var/time_between_uses = 1800
- var/last_process = 0
- var/cult_only = TRUE
-
-/obj/structure/divine/healingfountain/anyone
- desc = "A fountain containing the waters of life."
- cult_only = FALSE
-
-/obj/structure/divine/healingfountain/attack_hand(mob/living/user)
- if(deactivated)
- return
- if(last_process + time_between_uses > world.time)
- user << "The fountain appears to be empty."
- return
- last_process = world.time
- if(!is_handofgod_cultist(user) && cult_only)
- user << "The water burns!"
- user.reagents.add_reagent("hell_water",20)
- else
- user << "The water feels warm and soothing as you touch it. The fountain immediately dries up shortly afterwards."
- user.reagents.add_reagent("godblood",20)
- update_icons()
- addtimer(src, "update_icons", time_between_uses)
-
-
-/obj/structure/divine/healingfountain/update_icons()
- if(last_process + time_between_uses > world.time)
- icon_state = "fountain"
- else
- icon_state = "fountain-[side]"
-
-
-/obj/structure/divine/powerpylon
- name = "power pylon"
- desc = "A pylon which increases the deity's rate it can influence the world."
- icon_state = "powerpylon"
- density = 1
- health = 30
- maxhealth = 30
- metal_cost = 5
- glass_cost = 15
-
-
-/obj/structure/divine/powerpylon/New()
- ..()
- if(deity && deity.god_nexus)
- deity.god_nexus.powerpylons += src
-
-
-/obj/structure/divine/powerpylon/Destroy()
- if(deity && deity.god_nexus)
- deity.god_nexus.powerpylons -= src
- return ..()
-
-
-/obj/structure/divine/powerpylon/deactivate()
- ..()
- if(deity)
- deity.god_nexus.powerpylons -= src
-
-/obj/structure/divine/powerpylon/activate()
- ..()
- if(deity)
- deity.god_nexus.powerpylons += src
-
-/obj/structure/divine/defensepylon
- name = "defense pylon"
- desc = "A pylon which is blessed to withstand many blows, and fire strong bolts at nonbelievers. A god can toggle it."
- icon_state = "defensepylon"
- health = 150
- maxhealth = 150
- metal_cost = 25
- glass_cost = 30
- var/obj/machinery/porta_turret/defensepylon_internal_turret/pylon_gun
-
-
-/obj/structure/divine/defensepylon/New()
- ..()
- pylon_gun = new(src)
- pylon_gun.base = src
- pylon_gun.faction = list("[side] god")
-
-
-/obj/structure/divine/defensepylon/Destroy()
- qdel(pylon_gun) //just in case
- return ..()
-
-
-/obj/structure/divine/defensepylon/examine(mob/user)
- ..()
- user << "\The [src] looks [pylon_gun.on ? "on" : "off"]."
-
-
-/obj/structure/divine/defensepylon/assign_deity(mob/camera/god/new_deity, alert_old_deity = TRUE)
- if(..() && pylon_gun)
- pylon_gun.faction = list("[side] god")
- pylon_gun.side = side
-
-/obj/structure/divine/defensepylon/attack_god(mob/camera/god/user)
- if(user.side == side)
- if(deactivated)
- user << "You need to reveal it first!"
- return
- pylon_gun.on = !pylon_gun.on
- icon_state = (pylon_gun.on) ? "defensepylon-[side]" : "defensepylon"
-
-/obj/structure/divine/defensepylon/deactivate()
- ..()
- pylon_gun.on = 0
- icon_state = (pylon_gun.on) ? "defensepylon-[side]" : "defensepylon"
-
-/obj/structure/divine/defensepylon/activate()
- ..()
- pylon_gun.on = 1
- icon_state = (pylon_gun.on) ? "defensepylon-[side]" : "defensepylon"
-
-//This sits inside the defensepylon, to avoid copypasta
-/obj/machinery/porta_turret/defensepylon_internal_turret
- name = "defense pylon"
- desc = "A plyon which is blessed to withstand many blows, and fire strong bolts at nonbelievers."
- icon = 'icons/obj/hand_of_god_structures.dmi'
- installation = null
- always_up = 1
- use_power = 0
- has_cover = 0
- health = 200
- projectile = /obj/item/projectile/beam/pylon_bolt
- eprojectile = /obj/item/projectile/beam/pylon_bolt
- shot_sound = 'sound/weapons/emitter2.ogg'
- eshot_sound = 'sound/weapons/emitter2.ogg'
- base_icon_state = "defensepylon"
- active_state = ""
- off_state = ""
- faction = null
- emp_vunerable = 0
- var/side = "neutral"
-
-/obj/machinery/porta_turret/defensepylon_internal_turret/setup()
- return
-
-/obj/machinery/porta_turret/defensepylon_internal_turret/shootAt(atom/movable/target)
- var/obj/item/projectile/A = ..()
- if(A)
- A.color = side
-
-/obj/machinery/porta_turret/defensepylon_internal_turret/assess_perp(mob/living/carbon/human/perp)
- if(perp.handcuffed) //dishonourable to kill somebody who might be converted.
- return 0
- var/badtarget = 0
- switch(side)
- if("blue")
- badtarget = is_handofgod_bluecultist(perp)
- if("red")
- badtarget = is_handofgod_redcultist(perp)
- else
- badtarget = 1
- if(badtarget)
- return 0
- return 10
-
-
-
-/obj/item/projectile/beam/pylon_bolt
- name = "divine bolt"
- icon_state = "greyscale_bolt"
- damage = 15
-
-
-/obj/structure/divine/shrine
- name = "shrine"
- desc = "A shrine dedicated to a deity."
- icon_state = "shrine"
- metal_cost = 15
- glass_cost = 15
-
-
-/obj/structure/divine/shrine/assign_deity(mob/camera/god/new_deity, alert_old_deity = TRUE)
- if(..())
- name = "shrine to [new_deity.name]"
- desc = "A shrine dedicated to [new_deity.name]"
-
-
-
-
-//Functional, but need sprites
-/*
-/obj/structure/divine/translocator
- name = "translocator"
- desc = "A powerful structure, made with a greater gem. It allows a deity to move their nexus to where this stands"
- icon_state = "translocator"
- health = 100
- maxhealth = 100
- metal_cost = 20
- glass_cost = 20
- greater_gem_cost = 1
-
-
-/obj/structure/divine/lazarusaltar
- name = "lazarus altar"
- desc = "A very powerful altar capable of bringing life back to the recently deceased, made with a greater gem. It can revive anyone and will heal virtually all wounds, but they are but a shell of their former self."
- icon_state = "lazarusaltar"
- density = 0
- health = 100
- maxhealth = 100
- metal_cost = 20
- greater_gem_cost = 1
-
-
-/obj/structure/divine/lazarusaltar/attack_hand(mob/living/user)
- var/mob/living/L = locate() in get_turf(src)
- if(!is_handofgod_culstist(user))
- user << "You try to use it, but unfortunately you don't know any rituals."
- return
- if(!L)
- return
-
- if((side == "red" && is_handofgod_redcultist(user))) || (side == "blue" && is_handofgod_bluecultist(user)))
- user << "You attempt to revive [L] by invoking the rebirth ritual."
- L.revive()
- L.adjustCloneLoss(50)
- L.adjustStaminaLoss(100)
- else
- user << "You attempt to revive [L] by invoking the rebirth ritual."
- user << "But the altar ignores your words..."
-*/
-
-
diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
index 116d910e056..55a703913be 100644
--- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
+++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm
@@ -50,11 +50,10 @@
if(disguise == null)
return
stealth_active = 1
- if(istype(src.loc, /mob/living/carbon/human))
- var/mob/living/carbon/human/M = src.loc
- addtimer(GLOBAL_PROC, "anim", 0, FALSE, M.loc, M, 'icons/mob/mob.dmi',
- null, "cloak", null, M.dir)
-
+ if(istype(loc, /mob/living/carbon/human))
+ var/mob/living/carbon/human/M = loc
+ PoolOrNew(/obj/effect/overlay/temp/dir_setting/ninja/cloak,
+ list(get_turf(M), M.dir))
M.name_override = disguise.name
M.icon = disguise.icon
M.icon_state = disguise.icon_state
@@ -65,10 +64,10 @@
if(!stealth_active)
return
stealth_active = 0
- if(istype(src.loc, /mob/living/carbon/human))
- var/mob/living/carbon/human/M = src.loc
- addtimer(GLOBAL_PROC, "anim", 0, FALSE, M.loc, M, 'icons/mob/mob.dmi',
- null, "uncloak", null, M.dir)
+ if(istype(loc, /mob/living/carbon/human))
+ var/mob/living/carbon/human/M = loc
+ PoolOrNew(/obj/effect/overlay/temp/dir_setting/ninja,
+ list(get_turf(M), M.dir))
M.name_override = null
M.cut_overlays()
M.regenerate_icons()
@@ -92,11 +91,11 @@
ActivateStealth()
/obj/item/clothing/suit/armor/abductor/vest/proc/Adrenaline()
- if(istype(src.loc, /mob/living/carbon/human))
+ if(istype(loc, /mob/living/carbon/human))
if(combat_cooldown != initial(combat_cooldown))
- src.loc << "Combat injection is still recharging."
+ loc << "Combat injection is still recharging."
return
- var/mob/living/carbon/human/M = src.loc
+ var/mob/living/carbon/human/M = loc
M.adjustStaminaLoss(-75)
M.SetParalysis(0)
M.SetStunned(0)
diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm
index f63dfae041e..2ac221435fc 100644
--- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm
+++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm
@@ -63,6 +63,7 @@
icon = 'icons/obj/surgery.dmi'
name = "pile of viscera"
desc = "A repulsive pile of guts and gore."
+ gender = NEUTER
random_icon_states = list("innards")
/mob/living/simple_animal/slaughter/phasein()
diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm
index 98d0f963433..e0d0fdb3d00 100644
--- a/code/game/gamemodes/nuclear/nuclearbomb.dm
+++ b/code/game/gamemodes/nuclear/nuclearbomb.dm
@@ -91,7 +91,7 @@ var/bomb_set
if (istype(I, /obj/item/weapon/disk/nuclear))
if(!user.drop_item())
return
- I.loc = src
+ I.forceMove(src)
auth = I
add_fingerprint(user)
return
@@ -496,6 +496,20 @@ This is here to make the tiles around the station mininuke change when it's arme
poi_list |= src
START_PROCESSING(SSobj, src)
+/obj/item/weapon/disk/nuclear/attackby(obj/item/I, mob/living/user, params)
+ if(istype(I, /obj/item/weapon/claymore/highlander))
+ var/obj/item/weapon/claymore/highlander/H = I
+ if(H.nuke_disk)
+ user << "Wait... what?"
+ qdel(H.nuke_disk)
+ H.nuke_disk = null
+ return
+ user.visible_message("[user] captures [src]!", "You've got the disk! Defend it with your life!")
+ loc = H
+ H.nuke_disk = src
+ return 1
+ return ..()
+
/obj/item/weapon/disk/nuclear/suicide_act(mob/user)
user.visible_message("[user] is \
going delta! It looks like they're comitting suicide.")
diff --git a/code/game/machinery/limbgrower.dm b/code/game/machinery/limbgrower.dm
new file mode 100644
index 00000000000..14c8415adf8
--- /dev/null
+++ b/code/game/machinery/limbgrower.dm
@@ -0,0 +1,238 @@
+#define LIMBGROWER_MAIN_MENU 1
+#define LIMBGROWER_CATEGORY_MENU 2
+#define LIMBGROWER_CHEMICAL_MENU 3
+//use these for the menu system
+
+
+/obj/machinery/limbgrower
+ name = "limb grower"
+ desc = "It grows new limbs using Synthflesh."
+ icon = 'icons/obj/machines/limbgrower.dmi'
+ icon_state = "limbgrower_idleoff"
+ density = 1
+ flags = OPENCONTAINER
+
+ var/operating = 0
+ anchored = 1
+ use_power = 1
+ var/disabled = 0
+ idle_power_usage = 10
+ active_power_usage = 100
+ var/busy = 0
+ var/prod_coeff = 1
+
+ var/datum/design/being_built
+ var/datum/research/files
+ var/selected_category
+ var/screen = 1
+ var/emag = FALSE //Gives access to other cool stuff
+
+ var/list/categories = list(
+ "human",
+ "lizard",
+ "plasmaman",
+ "special"
+ )
+
+/obj/machinery/limbgrower/New()
+ ..()
+ create_reagents(0)
+ var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/limbgrower(null)
+ B.apply_default_parts(src)
+ files = new /datum/research/limbgrower(src)
+
+/obj/item/weapon/circuitboard/machine/limbgrower
+ name = "circuit board (Limb Grower)"
+ build_path = /obj/machinery/limbgrower
+ origin_tech = "programming=2;biotech=2"
+ req_components = list(
+ /obj/item/weapon/stock_parts/manipulator = 1,
+ /obj/item/weapon/reagent_containers/glass/beaker = 2,
+ /obj/item/weapon/stock_parts/console_screen = 1)
+
+/obj/machinery/limbgrower/interact(mob/user)
+ if(!is_operational())
+ return
+
+ var/dat = main_win(user)
+
+ switch(screen)
+ if(LIMBGROWER_MAIN_MENU)
+ dat = main_win(user)
+ if(LIMBGROWER_CATEGORY_MENU)
+ dat = category_win(user,selected_category)
+ if(LIMBGROWER_CHEMICAL_MENU)
+ dat = chemical_win(user)
+
+ var/datum/browser/popup = new(user, "Limb Grower", name, 400, 500)
+ popup.set_content(dat)
+ popup.open()
+
+/obj/machinery/limbgrower/deconstruction()
+ for(var/obj/item/weapon/reagent_containers/glass/G in component_parts)
+ reagents.trans_to(G, G.reagents.maximum_volume)
+
+/obj/machinery/limbgrower/attackby(obj/item/O, mob/user, params)
+ if (busy)
+ user << "The Limb Grower is busy. Please wait for completion of previous operation."
+ return
+
+ if(default_deconstruction_screwdriver(user, "limbgrower_panelopen", "limbgrower_idleoff", O))
+ updateUsrDialog()
+ return
+
+ if(exchange_parts(user, O))
+ return
+
+ if(panel_open && default_deconstruction_crowbar(O))
+ return
+
+ if(user.a_intent == "harm") //so we can hit the machine
+ return ..()
+
+/obj/machinery/limbgrower/Topic(href, href_list)
+ if(..())
+ return
+ if (!busy)
+ if(href_list["menu"])
+ screen = text2num(href_list["menu"])
+
+ if(href_list["category"])
+ selected_category = href_list["category"]
+
+ if(href_list["disposeI"]) //Get rid of a reagent incase you add the wrong one by mistake
+ reagents.del_reagent(href_list["disposeI"])
+
+ if(href_list["make"])
+
+ /////////////////
+ //href protection
+ being_built = files.FindDesignByID(href_list["make"]) //check if it's a valid design
+ if(!being_built)
+ return
+
+
+ var/synth_cost = being_built.reagents["synthflesh"]*prod_coeff
+ var/power = max(2000, synth_cost/5)
+
+ if(reagents.has_reagent("synthflesh", being_built.reagents["synthflesh"]*prod_coeff))
+ busy = 1
+ use_power(power)
+ flick("limbgrower_fill",src)
+ icon_state = "limbgrower_idleon"
+ addtimer(src, "build_item",32*prod_coeff)
+
+ else
+ usr << "The limb grower is busy. Please wait for completion of previous operation."
+
+ updateUsrDialog()
+ return
+
+/obj/machinery/limbgrower/proc/build_item()
+ if(reagents.has_reagent("synthflesh", being_built.reagents["synthflesh"]*prod_coeff)) //sanity check, if this happens we are in big trouble
+ reagents.remove_reagent("synthflesh",being_built.reagents["synthflesh"]*prod_coeff)
+ var/buildpath = being_built.build_path
+ if(ispath(buildpath, /obj/item/bodypart)) //This feels like spatgheti code, but i need to initilise a limb somehow
+ build_limb(buildpath)
+ else
+ //Just build whatever it is
+ new buildpath(loc)
+ else
+ src.visible_message(" Something went very wrong and there isnt enough synthflesh anymore!")
+ busy = 0
+ flick("limbgrower_unfill",src)
+ icon_state = "limbgrower_idleoff"
+ updateUsrDialog()
+
+/obj/machinery/limbgrower/proc/build_limb(buildpath)
+ //i need to create a body part manually using a set icon (otherwise it doesnt appear)
+ var/obj/item/bodypart/limb
+ limb = new buildpath(loc)
+ if(selected_category=="human" || selected_category=="lizard") // Doing this because plasmamen have their limbs in a different icon file
+ limb.icon = 'icons/mob/human_parts_greyscale.dmi'
+ else
+ limb.icon = 'icons/mob/human_parts.dmi'
+ // Set this limb up using the specias name and body zone
+ limb.icon_state = "[selected_category]_[limb.body_zone]_s"
+ limb.name = "Synthetic [selected_category] [parse_zone(limb.body_zone)]"
+ limb.desc = "A synthetic [selected_category] limb that will morph on its first use in surgery. This one is for the [parse_zone(limb.body_zone)]"
+
+/obj/machinery/limbgrower/RefreshParts()
+ reagents.maximum_volume = 0
+ for(var/obj/item/weapon/reagent_containers/glass/G in component_parts)
+ reagents.maximum_volume += G.volume
+ G.reagents.trans_to(src, G.reagents.total_volume)
+ var/T=1.2
+ for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
+ T -= M.rating*0.2
+ prod_coeff = min(1,max(0,T)) // Coeff going 1 -> 0,8 -> 0,6 -> 0,4
+
+/obj/machinery/limbgrower/proc/main_win(mob/user)
+ var/dat = "Limb Grower Menu:
"
+ dat += "
Chemical Storage"
+ dat += materials_printout()
+ dat += "
"
+
+ for(var/C in categories)
+ if(C=="special" && !emag) //Only want to show special when console is emagged
+ continue
+
+ dat += "| [C] | "
+ dat += "
"
+ //one category per line
+
+ dat += "
"
+ return dat
+
+/obj/machinery/limbgrower/proc/category_win(mob/user,selected_category)
+ var/dat = "Return to main menu"
+ dat += "Browsing [selected_category]:
"
+ dat += materials_printout()
+
+ for(var/v in files.known_designs)
+ var/datum/design/D = files.known_designs[v]
+ if(!(selected_category in D.category))
+ continue
+ if(disabled || !can_build(D))
+ dat += "
[D.name]"
+ else
+ dat += "
[D.name]"
+ dat += "[get_design_cost(D)]
"
+
+ dat += "
"
+ return dat
+
+
+/obj/machinery/limbgrower/proc/chemical_win(mob/user)
+ var/dat = "Return to main menu"
+ dat += "Browsing Chemical Storage:
"
+ dat += materials_printout()
+
+ for(var/datum/reagent/R in reagents.reagent_list)
+ dat += "[R.name]: [R.volume]"
+ dat += "
Purge"
+
+ dat += "
"
+ return dat
+
+/obj/machinery/limbgrower/proc/materials_printout()
+ var/dat = "Total amount:> [reagents.total_volume] / [reagents.maximum_volume] cm3
"
+ return dat
+
+/obj/machinery/limbgrower/proc/can_build(datum/design/D)
+ return (reagents.has_reagent("synthflesh", D.reagents["synthflesh"]*prod_coeff)) //Return whether the machine has enough synthflesh to produce the design
+
+/obj/machinery/limbgrower/proc/get_design_cost(datum/design/D)
+ var/dat
+ if(D.reagents["synthflesh"])
+ dat += "[D.reagents["synthflesh"] * prod_coeff] Synthetic flesh "
+ return dat
+
+/obj/machinery/limbgrower/emag_act(mob/user)
+ if(emag==TRUE)
+ return
+ for(var/datum/design/D in files.possible_designs)
+ if((D.build_type & LIMBGROWER) && ("special" in D.category))
+ files.AddDesign2Known(D)
+ user << "A warning flashes onto the screen, stating that safety overrides have been deactivated"
+ emag = TRUE
\ No newline at end of file
diff --git a/code/game/objects/effects/decals/Cleanable/aliens.dm b/code/game/objects/effects/decals/Cleanable/aliens.dm
index a0e5d4a3dc3..fbc74142fd9 100644
--- a/code/game/objects/effects/decals/Cleanable/aliens.dm
+++ b/code/game/objects/effects/decals/Cleanable/aliens.dm
@@ -3,9 +3,6 @@
/obj/effect/decal/cleanable/xenoblood
name = "xeno blood"
desc = "It's green and acidic. It looks like... blood?"
- gender = PLURAL
- density = 0
- layer = ABOVE_OPEN_TURF_LAYER
icon = 'icons/effects/blood.dmi'
icon_state = "xfloor1"
random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7")
@@ -43,7 +40,6 @@
/obj/effect/decal/cleanable/xenoblood/xgibs
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")
diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm
index 916bd7d2cf3..34118d95ac3 100644
--- a/code/game/objects/effects/decals/Cleanable/humans.dm
+++ b/code/game/objects/effects/decals/Cleanable/humans.dm
@@ -1,9 +1,6 @@
/obj/effect/decal/cleanable/blood
name = "blood"
desc = "It's red and gooey. Perhaps it's the chef's cooking?"
- gender = PLURAL
- density = 0
- layer = ABOVE_NORMAL_TURF_LAYER
icon = 'icons/effects/blood.dmi'
icon_state = "floor1"
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
@@ -29,16 +26,12 @@
/obj/effect/decal/cleanable/blood/tracks
icon_state = "tracks"
desc = "They look like tracks left by wheels."
- gender = PLURAL
random_icon_states = null
/obj/effect/decal/cleanable/trail_holder //not a child of blood on purpose
name = "blood"
icon_state = "ltrails_1"
desc = "Your instincts say you shouldn't be following these."
- gender = PLURAL
- density = 0
- layer = ABOVE_OPEN_TURF_LAYER
random_icon_states = null
var/list/existing_dirs = list()
blood_DNA = list()
@@ -51,9 +44,6 @@
/obj/effect/decal/cleanable/blood/gibs
name = "gibs"
desc = "They look bloody and gruesome."
- gender = PLURAL
- density = 0
- layer = ABOVE_OPEN_TURF_LAYER
icon = 'icons/effects/blood.dmi'
icon_state = "gibbl5"
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
@@ -108,7 +98,6 @@
/obj/effect/decal/cleanable/blood/drip
name = "drips of blood"
desc = "It's red."
- gender = PLURAL
icon_state = "1"
random_icon_states = list("drip1","drip2","drip3","drip4","drip5")
bloodiness = 0
@@ -125,7 +114,6 @@
icon = 'icons/effects/footprints.dmi'
icon_state = "nothingwhatsoever"
desc = "where might they lead?"
- gender = PLURAL
random_icon_states = null
var/entered_dirs = 0
var/exited_dirs = 0
diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm
index ebf8ab3f8c5..5e460de0b80 100644
--- a/code/game/objects/effects/decals/Cleanable/misc.dm
+++ b/code/game/objects/effects/decals/Cleanable/misc.dm
@@ -1,16 +1,12 @@
/obj/effect/decal/cleanable/generic
name = "clutter"
desc = "Someone should clean that up."
- gender = PLURAL
- density = 0
- layer = ABOVE_OPEN_TURF_LAYER
icon = 'icons/obj/objects.dmi'
icon_state = "shards"
/obj/effect/decal/cleanable/ash
name = "ashes"
desc = "Ashes to ashes, dust to dust, and into space."
- gender = PLURAL
icon = 'icons/obj/objects.dmi'
icon_state = "ash"
@@ -24,25 +20,16 @@
name = "dirt"
desc = "Someone should clean that up."
icon_state = "dirt"
- gender = PLURAL
- density = 0
- layer = ABOVE_OPEN_TURF_LAYER
mouse_opacity = 0
/obj/effect/decal/cleanable/flour
name = "flour"
desc = "It's still good. Four second rule!"
- gender = PLURAL
- density = 0
- layer = ABOVE_OPEN_TURF_LAYER
icon_state = "flour"
/obj/effect/decal/cleanable/greenglow
name = "glowing goo"
desc = "Jeez. I hope that's not for lunch."
- gender = PLURAL
- density = 0
- layer = ABOVE_OPEN_TURF_LAYER
luminosity = 1
icon_state = "greenglow"
@@ -52,36 +39,34 @@
/obj/effect/decal/cleanable/cobweb
name = "cobweb"
desc = "Somebody should remove that."
- density = 0
- layer = OBJ_LAYER
+ gender = NEUTER
+ layer = WALL_OBJ_LAYER
icon_state = "cobweb1"
- burntime = 1
/obj/effect/decal/cleanable/cobweb/fire_act()
qdel(src)
+/obj/effect/decal/cleanable/cobweb2
+ name = "cobweb"
+ desc = "Somebody should remove that."
+ gender = NEUTER
+ layer = WALL_OBJ_LAYER
+ icon_state = "cobweb2"
+
+/obj/effect/decal/cleanable/cobweb2/fire_act()
+ qdel(src)
+
/obj/effect/decal/cleanable/molten_item
name = "gooey grey mass"
desc = "It looks like a melted... something."
- density = 0
- layer = OBJ_LAYER
+ gender = NEUTER
icon = 'icons/obj/chemical.dmi'
icon_state = "molten"
-/obj/effect/decal/cleanable/cobweb2
- name = "cobweb"
- desc = "Somebody should remove that."
- density = 0
- layer = OBJ_LAYER
- icon_state = "cobweb2"
-
//Vomit (sorry)
/obj/effect/decal/cleanable/vomit
name = "vomit"
desc = "Gosh, how unpleasant."
- gender = PLURAL
- density = 0
- layer = ABOVE_OPEN_TURF_LAYER
icon = 'icons/effects/blood.dmi'
icon_state = "vomit_1"
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
@@ -112,38 +97,34 @@
/obj/effect/decal/cleanable/tomato_smudge
name = "tomato smudge"
desc = "It's red."
- density = 0
- layer = ABOVE_OPEN_TURF_LAYER
+ gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("tomato_floor1", "tomato_floor2", "tomato_floor3")
/obj/effect/decal/cleanable/plant_smudge
name = "plant smudge"
- density = 0
- layer = ABOVE_OPEN_TURF_LAYER
+ gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_plant")
/obj/effect/decal/cleanable/egg_smudge
name = "smashed egg"
desc = "Seems like this one won't hatch."
- density = 0
- layer = ABOVE_OPEN_TURF_LAYER
+ gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_egg1", "smashed_egg2", "smashed_egg3")
/obj/effect/decal/cleanable/pie_smudge //honk
name = "smashed pie"
desc = "It's pie cream from a cream pie."
- density = 0
- layer = ABOVE_OPEN_TURF_LAYER
+ gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_pie")
/obj/effect/decal/cleanable/chem_pile
name = "chemical pile"
desc = "A pile of chemicals. You can't quite tell what's inside it."
- gender = PLURAL
+ gender = NEUTER
icon = 'icons/obj/objects.dmi'
icon_state = "ash"
@@ -152,8 +133,6 @@
desc = "The shredded remains of what appears to be clothing."
icon_state = "shreds"
gender = PLURAL
- density = 0
- layer = ABOVE_OPEN_TURF_LAYER
/obj/effect/decal/cleanable/shreds/New()
pixel_x = rand(-5, 5)
@@ -165,3 +144,4 @@
desc = "A sizable pile of table salt. Someone must be upset."
icon = 'icons/effects/tomatodecal.dmi'
icon_state = "salt_pile"
+ gender = NEUTER
diff --git a/code/game/objects/effects/decals/Cleanable/robots.dm b/code/game/objects/effects/decals/Cleanable/robots.dm
index 7c0666a0c6e..5b56853cff2 100644
--- a/code/game/objects/effects/decals/Cleanable/robots.dm
+++ b/code/game/objects/effects/decals/Cleanable/robots.dm
@@ -3,9 +3,6 @@
/obj/effect/decal/cleanable/robot_debris
name = "robot debris"
desc = "It's a useless heap of junk... or is it?"
- gender = PLURAL
- density = 0
- layer = ABOVE_OPEN_TURF_LAYER
icon = 'icons/mob/robots.dmi'
icon_state = "gib1"
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7")
@@ -45,9 +42,6 @@
/obj/effect/decal/cleanable/oil
name = "motor oil"
desc = "It's black and greasy. Looks like Beepsky made another mess."
- gender = PLURAL
- density = 0
- layer = ABOVE_OPEN_TURF_LAYER
icon = 'icons/mob/robots.dmi'
icon_state = "floor1"
var/viruses = list()
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index 9a24696cc87..b4a78c247b2 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -1,4 +1,6 @@
/obj/effect/decal/cleanable
+ gender = PLURAL
+ layer = ABOVE_NORMAL_TURF_LAYER
var/list/random_icon_states = list()
var/blood_state = "" //I'm sorry but cleanable/blood code is ass, and so is blood_DNA
var/bloodiness = 0 //0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints
diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm
index c629ff1e768..4a0175076a1 100644
--- a/code/game/objects/effects/decals/crayon.dm
+++ b/code/game/objects/effects/decals/crayon.dm
@@ -3,15 +3,9 @@
desc = "Graffiti. Damn kids."
icon = 'icons/effects/crayondecal.dmi'
icon_state = "rune1"
- layer = ABOVE_NORMAL_TURF_LAYER
+ gender = NEUTER
var/do_icon_rotate = TRUE
-/obj/effect/decal/cleanable/crayon/examine()
- set src in view(2)
- ..()
- return
-
-
/obj/effect/decal/cleanable/crayon/New(location, main = "#FFFFFF", var/type = "rune1", var/e_name = "rune", var/rotation = 0, var/alt_icon = null)
..()
loc = location
diff --git a/code/game/gamemodes/handofgod/items.dm b/code/game/objects/items/religion.dm
similarity index 55%
rename from code/game/gamemodes/handofgod/items.dm
rename to code/game/objects/items/religion.dm
index f512c5c11cb..4f6fa7ad3f0 100644
--- a/code/game/gamemodes/handofgod/items.dm
+++ b/code/game/objects/items/religion.dm
@@ -7,29 +7,19 @@
var/moralecooldown = 0
var/moralewait = 600
-
/obj/item/weapon/banner/attack_self(mob/living/carbon/human/user)
if(moralecooldown + moralewait > world.time)
return
- var/side = ""
- if(is_handofgod_redcultist(user))
- side = "red"
- else if (is_handofgod_bluecultist(user))
- side = "blue"
-
- if(!side)
- return
user << "You increase the morale of your fellows!"
moralecooldown = world.time
for(var/mob/living/carbon/human/H in range(4,get_turf(src)))
- if((side == "red") && is_handofgod_redcultist(H) || (side == "blue") && is_handofgod_bluecultist(H))
- H << "Your morale is increased by [user]'s banner!"
- H.adjustBruteLoss(-15)
- H.adjustFireLoss(-15)
- H.AdjustStunned(-2)
- H.AdjustWeakened(-2)
- H.AdjustParalysis(-2)
+ H << "Your morale is increased by [user]'s banner!"
+ H.adjustBruteLoss(-15)
+ H.adjustFireLoss(-15)
+ H.AdjustStunned(-2)
+ H.AdjustWeakened(-2)
+ H.AdjustParalysis(-2)
/obj/item/weapon/banner/red
@@ -38,52 +28,32 @@
item_state = "banner-red"
desc = "A banner with the logo of the red deity."
-/obj/item/weapon/banner/red/examine(mob/user)
- ..()
- if(is_handofgod_redcultist(user))
- user << "A banner representing our might against the heretics. We may use it to increase the morale of our fellow members!"
- else if(is_handofgod_bluecultist(user))
- user << "A heretical banner that should be destroyed posthaste."
-
-
/obj/item/weapon/banner/blue
name = "blue banner"
icon_state = "banner-blue"
item_state = "banner-blue"
desc = "A banner with the logo of the blue deity"
-/obj/item/weapon/banner/blue/examine(mob/user)
- ..()
-
- if(is_handofgod_redcultist(user))
- user << "A heretical banner that should be destroyed posthaste."
- else if(is_handofgod_bluecultist(user))
- user << "A banner representing our might against the heretics. We may use it to increase the morale of our fellow members!"
-
-
/obj/item/weapon/storage/backpack/bannerpack
name = "nanotrasen banner backpack"
desc = "It's a backpack with lots of extra room. A banner with Nanotrasen's logo is attached, that can't be removed."
max_combined_w_class = 27 //6 more then normal, for the tradeoff of declaring yourself an antag at all times.
icon_state = "bannerpack"
-
/obj/item/weapon/storage/backpack/bannerpack/red
name = "red banner backpack"
desc = "It's a backpack with lots of extra room. A red banner is attached, that can't be removed."
icon_state = "bannerpack-red"
-
/obj/item/weapon/storage/backpack/bannerpack/blue
name = "blue banner backpack"
desc = "It's a backpack with lots of extra room. A blue banner is attached, that can't be removed."
icon_state = "bannerpack-blue"
-
-
//this is all part of one item set
/obj/item/clothing/suit/armor/plate/crusader
name = "Crusader's Armour"
+ desc = "Armour that's comprised of metal and cloth."
icon_state = "crusader"
w_class = 4 //bulky
slowdown = 2.0 //gotta pretend we're balanced.
@@ -96,16 +66,9 @@
/obj/item/clothing/suit/armor/plate/crusader/blue
icon_state = "crusader-blue"
-/obj/item/clothing/suit/armor/plate/crusader/examine(mob/user)
- ..()
- if(!is_handofgod_cultist(user))
- user << "Armour that's comprised of metal and cloth."
- else
- user << "Armour that was used to protect from backstabs, gunshots, explosives, and lasers. The original wearers of this type of armour were trying to avoid being murdered. Since they're not around anymore, you're not sure if they were successful or not."
-
-
/obj/item/clothing/head/helmet/plate/crusader
name = "Crusader's Hood"
+ desc = "A brownish hood."
icon_state = "crusader"
w_class = 3 //normal
flags_inv = HIDEHAIR|HIDEEARS|HIDEFACE
@@ -117,140 +80,67 @@
/obj/item/clothing/head/helmet/plate/crusader/red
icon_state = "crusader-red"
-
-/obj/item/clothing/head/helmet/plate/crusader/examine(mob/user)
- ..()
- if(!is_handofgod_cultist(user))
- user << "A brownish hood."
- else
- user << "A hood that's very protective, despite being made of cloth. Due to the tendency of the wearer to be targeted for assassinations, being protected from being shot in the face was very important.."
-
-
-
//Prophet helmet
/obj/item/clothing/head/helmet/plate/crusader/prophet
name = "Prophet's Hat"
+ desc = "A religious-looking hat."
alternate_worn_icon = 'icons/mob/large-worn-icons/64x64/head.dmi'
flags = 0
armor = list(melee = 60, bullet = 60, laser = 60, energy = 50, bomb = 70, bio = 50, rad = 50) //religion protects you from disease and radiation, honk.
worn_x_dimension = 64
worn_y_dimension = 64
- var/side = "neither"
-
-/obj/item/clothing/head/helmet/plate/crusader/prophet/equipped(mob/living/carbon/user, slot)
- var/faithful = 0
- if(slot == slot_head)
- switch(side)
- if("blue")
- faithful = is_handofgod_bluecultist(user)
- if("red")
- faithful = is_handofgod_redcultist(user)
- else
- faithful = 1
- if(!faithful)
- user << "Your mind is assaulted by a vast power, furious at your desecration!"
- user.emote("scream")
- user.adjustFireLoss(10)
- user.unEquip(src)
- user.head = null
- user.update_inv_head()
- src.screen_loc = null
- user.Weaken(1)
/obj/item/clothing/head/helmet/plate/crusader/prophet/red
icon_state = "prophet-red"
- side = "red"
-
/obj/item/clothing/head/helmet/plate/crusader/prophet/blue
icon_state = "prophet-blue"
- side = "blue"
-
-
-/obj/item/clothing/head/helmet/plate/crusader/prophet/examine(mob/user)
- ..()
- if(!is_handofgod_cultist(user))
- user << "A brownish, religious-looking hat."
- else
- user << "A hat bestowed upon a prophet of gods and demigods."
- user << "This hat belongs to the [side] god."
-
-
//Structure conversion staff
/obj/item/weapon/godstaff
name = "godstaff"
+ desc = "It's a stick..?"
icon_state = "godstaff-red"
- var/mob/camera/god/god = null
+ var/conversion_color = "#ffffff"
var/staffcooldown = 0
var/staffwait = 30
-/obj/item/weapon/godstaff/examine(mob/user)
- ..()
- if(!is_handofgod_cultist(user))
- user << "It's a stick..?"
- else
- user << "A powerful staff capable of changing the allegiance of god/demigod structures."
-
-
-/obj/item/weapon/godstaff/attack_self(mob/living/carbon/user)
- if((god && !god.is_handofgod_myprophet(user)) || !god)
- user << "YOU ARE NOT THE CHOSEN ONE!"
- return
- if(!(istype(user.head, /obj/item/clothing/head/helmet/plate/crusader/prophet)))
- user << "Your connection to your diety isn't strong enough! You must wear your big hat!"
- return
+/obj/item/weapon/godstaff/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
if(staffcooldown + staffwait > world.time)
return
- user.visible_message("[user] chants deeply and waves their staff")
+ user.visible_message("[user] chants deeply and waves their staff!")
if(do_after(user, 20,1,src))
- for(var/obj/structure/divine/R in orange(3,user))
- user.say("Grant us true sight my god!")
- if(istype(R, /obj/structure/divine/nexus)|| istype(R, /obj/structure/divine/trap))
- continue
- R.visible_message("[R] suddenly appears!")
- R.invisibility = 0
- R.alpha = initial(R.alpha)
- R.density = initial(R.density)
- R.activate()
+ target.color = conversion_color //wololo
staffcooldown = world.time
/obj/item/weapon/godstaff/red
icon_state = "godstaff-red"
+ conversion_color = "#ff0000"
/obj/item/weapon/godstaff/blue
icon_state = "godstaff-blue"
-
-
+ conversion_color = "#0000ff"
/obj/item/clothing/gloves/plate
name = "Plate Gauntlets"
icon_state = "crusader"
+ desc = "They're like gloves, but made of metal."
siemens_coefficient = 0
cold_protection = HANDS
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
heat_protection = HANDS
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
-
/obj/item/clothing/gloves/plate/red
icon_state = "crusader-red"
/obj/item/clothing/gloves/plate/blue
icon_state = "crusader-blue"
-
-/obj/item/clothing/gloves/plate/examine(mob/user)
- ..()
- if(!is_handofgod_cultist(user))
- usr << "They're like gloves, but made of metal."
- else
- usr << "Protective gloves that are also blessed to protect from heat and shock."
-
-
/obj/item/clothing/shoes/plate
name = "Plate Boots"
+ desc = "Metal boots, they look heavy."
icon_state = "crusader"
w_class = 3 //normal
armor = list(melee = 50, bullet = 50, laser = 50, energy = 40, bomb = 60, bio = 0, rad = 0) //does this even do anything on boots?
@@ -268,14 +158,6 @@
icon_state = "crusader-blue"
-/obj/item/clothing/shoes/plate/examine(mob/user)
- ..()
- if(!is_handofgod_cultist(user))
- usr << "Metal boots, they look heavy."
- else
- usr << "Heavy boots that are blessed for sure footing. You'll be safe from being taken down by the heresy that is the banana peel."
-
-
/obj/item/weapon/storage/box/itemset/crusader
name = "Crusader's Armour Set" //i can't into ck2 references
desc = "This armour is said to be based on the armor of kings on another world thousands of years ago, who tended to assassinate, conspire, and plot against everyone who tried to do the same to them. Some things never change."
@@ -301,6 +183,7 @@
new /obj/item/clothing/shoes/plate/red(src)
-/obj/item/weapon/claymore/hog
+/obj/item/weapon/claymore/weak
+ desc = "This one is rusted."
force = 30
armour_penetration = 15
\ No newline at end of file
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
index 5e8b75b987a..5f1e514cde7 100644
--- a/code/game/objects/items/robot/robot_items.dm
+++ b/code/game/objects/items/robot/robot_items.dm
@@ -10,15 +10,16 @@
icon_state = "elecarm"
var/charge_cost = 30
-/obj/item/borg/stun/attack(mob/living/M, mob/living/silicon/robot/user)
+/obj/item/borg/stun/attack(mob/living/M, mob/living/user)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.check_shields(0, "[M]'s [name]", src, MELEE_ATTACK))
playsound(M, 'sound/weapons/Genhit.ogg', 50, 1)
return 0
-
- if(!user.cell.use(charge_cost))
- return
+ if(isrobot(user))
+ var/mob/living/silicon/robot/R = user
+ if(!R.cell.use(charge_cost))
+ return
user.do_attack_animation(M)
M.Weaken(5)
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index 2e765ab4e05..74be2659ad9 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -137,6 +137,7 @@
if (R.max_res_amount > 1)
var/obj/item/stack/new_item = O
new_item.amount = R.res_amount*multiplier
+ new_item.update_icon()
if(new_item.amount <= 0)//if the stack is empty, i.e it has been merged with an existing stack and has been garbage collected
return
@@ -232,7 +233,7 @@
..()
return
-/obj/item/stack/AltClick(mob/user)
+/obj/item/stack/AltClick(mob/living/user)
if(user.incapacitated())
user << "You can't do that right now!"
return
diff --git a/code/game/objects/items/weapons/implants/implant_loyality.dm b/code/game/objects/items/weapons/implants/implant_loyality.dm
index c669b279ccc..fe9a59d0df5 100644
--- a/code/game/objects/items/weapons/implants/implant_loyality.dm
+++ b/code/game/objects/items/weapons/implants/implant_loyality.dm
@@ -32,7 +32,7 @@
return -1
if(target.mind in ticker.mode.revolutionaries)
ticker.mode.remove_revolutionary(target.mind)
- if((target.mind in ticker.mode.cult) || (target.mind in ticker.mode.blue_deity_prophets|ticker.mode.red_deity_prophets|ticker.mode.red_deity_followers|ticker.mode.blue_deity_followers))
+ if(target.mind in ticker.mode.cult)
target << "You feel something interfering with your mental conditioning, but you resist it!"
else
target << "You feel a sense of peace and security. You are now protected from brainwashing."
@@ -46,7 +46,6 @@
return 1
return 0
-
/obj/item/weapon/implanter/mindshield
name = "implanter (mindshield)"
diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm
index 9f93c93eca3..b9d3a17e023 100644
--- a/code/game/objects/items/weapons/melee/energy.dm
+++ b/code/game/objects/items/weapons/melee/energy.dm
@@ -238,7 +238,6 @@
/obj/item/weapon/melee/energy/blade/dropped()
..()
- qdel(src)
/obj/item/weapon/melee/energy/blade/attack_self(mob/user)
return
diff --git a/code/game/objects/items/weapons/melee/misc.dm b/code/game/objects/items/weapons/melee/misc.dm
index b81a9cf75aa..6c20ea10f6f 100644
--- a/code/game/objects/items/weapons/melee/misc.dm
+++ b/code/game/objects/items/weapons/melee/misc.dm
@@ -21,6 +21,17 @@
user.visible_message("[user] is strangling \himself with the [src.name]! It looks like \he's trying to commit suicide.")
return (OXYLOSS)
+/obj/item/weapon/melee/synthetic_arm_blade
+ name = "synthetic arm blade"
+ desc = "A grotesque blade that on closer inspection seems made of synthentic flesh, it still feels like it would hurt very badly as a weapon."
+ icon = 'icons/obj/weapons.dmi'
+ icon_state = "arm_blade"
+ item_state = "arm_blade"
+ origin_tech = "combat=5,biotech=5"
+ w_class = 5.0
+ force = 15
+ throwforce = 10
+ sharpness = IS_SHARP
/obj/item/weapon/melee/sabre
name = "officer's sabre"
diff --git a/code/game/objects/items/weapons/mop.dm b/code/game/objects/items/weapons/mop.dm
index 2f4c84ba913..feeab19e611 100644
--- a/code/game/objects/items/weapons/mop.dm
+++ b/code/game/objects/items/weapons/mop.dm
@@ -1,5 +1,3 @@
-#define is_cleanable(A) (istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/rune))
-
/obj/item/weapon/mop
desc = "The world of janitalia wouldn't be complete without a mop."
name = "mop"
@@ -42,16 +40,14 @@ obj/item/weapon/mop/proc/clean(turf/A)
user << "Your mop is dry!"
return
- var/turf/turf = A
- if(is_cleanable(A))
- turf = A.loc
+ var/turf/T = get_turf(A)
- if(istype(turf))
- user.visible_message("[user] begins to clean \the [turf] with [src].", "You begin to clean \the [turf] with [src]...")
+ if(T)
+ user.visible_message("[user] begins to clean \the [T] with [src].", "You begin to clean \the [T] with [src]...")
- if(do_after(user, src.mopspeed, target = turf))
+ if(do_after(user, src.mopspeed, target = T))
user << "You finish mopping."
- clean(turf)
+ clean(T)
/obj/effect/attackby(obj/item/I, mob/user, params)
diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm
index 9f27404afae..38ade34e247 100644
--- a/code/game/objects/items/weapons/storage/uplink_kits.dm
+++ b/code/game/objects/items/weapons/storage/uplink_kits.dm
@@ -2,7 +2,7 @@
/obj/item/weapon/storage/box/syndicate/New()
..()
- switch (pickweight(list("bloodyspai" = 3, "stealth" = 2, "bond" = 2, "screwed" = 2, "sabotage" = 3, "guns" = 2, "murder" = 2, "implant" = 1, "hacker" = 3, "lordsingulo" = 1, "darklord" = 1, "sniper" = 1, "metaops" = 1)))
+ switch (pickweight(list("bloodyspai" = 3, "stealth" = 2, "bond" = 2, "screwed" = 2, "sabotage" = 3, "guns" = 2, "murder" = 2, "implant" = 1, "hacker" = 3, "lordsingulo" = 1, "darklord" = 1, "sniper" = 1, "metaops" = 1, "ninja" = 1)))
if("bloodyspai") // 27 tc now this is more right
new /obj/item/clothing/under/chameleon(src) // 2 tc since it's not the full set
new /obj/item/clothing/mask/chameleon(src) // Goes with above
@@ -131,6 +131,19 @@
new /obj/item/weapon/grenade/plastic/c4 (src) // 1 tc
new /obj/item/weapon/card/emag(src) // 6 tc
return
+
+ if("ninja") // 33 tc worth
+ new /obj/item/weapon/katana(src) // Unique , hard to tell how much tc this is worth. 8 tc?
+ new /obj/item/weapon/implanter/adrenalin(src) // 8 tc
+ new /obj/item/weapon/throwing_star(src) // ~5 tc for all 6
+ new /obj/item/weapon/throwing_star(src)
+ new /obj/item/weapon/throwing_star(src)
+ new /obj/item/weapon/throwing_star(src)
+ new /obj/item/weapon/throwing_star(src)
+ new /obj/item/weapon/throwing_star(src)
+ new /obj/item/weapon/storage/belt/military/assault(src) // 3 tc
+ new /obj/item/weapon/card/id/syndicate(src) // 2 tc
+ new /obj/item/device/chameleon(src) // 7 tc
/obj/item/weapon/storage/box/syndie_kit
name = "box"
diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm
index 0702a80d30c..07d09d07451 100644
--- a/code/game/objects/items/weapons/weaponry.dm
+++ b/code/game/objects/items/weapons/weaponry.dm
@@ -82,10 +82,14 @@
var/highlander_claymores = 0
/obj/item/weapon/claymore/highlander //ALL COMMENTS MADE REGARDING THIS SWORD MUST BE MADE IN ALL CAPS
desc = "THERE CAN BE ONLY ONE, AND IT WILL BE YOU!!!\nActivate it in your hand to point to the nearest victim."
+ flags = CONDUCT | NODROP
+ slot_flags = null
block_chance = 0 //RNG WON'T HELP YOU NOW, PANSY
- attack_verb = list("brutalized", "eviscerated", "disemboweled", "hacked", "carved", "cleaved", "gored") //ONLY THE MOST VISCERAL ATTACK VERBS
+ attack_verb = list("brutalized", "eviscerated", "disemboweled", "hacked", "carved", "cleaved") //ONLY THE MOST VISCERAL ATTACK VERBS
var/notches = 0 //HOW MANY PEOPLE HAVE BEEN SLAIN WITH THIS BLADE
var/announced = FALSE //IF WE ARE THE ONLY ONE LEFT STANDING
+ var/bloodthirst_level = 0 //HOW THIRSTY WE ARE FOR BLOOD
+ var/obj/item/weapon/disk/nuclear/nuke_disk //OUR STORED NUKE DISK
/obj/item/weapon/claymore/highlander/New()
..()
@@ -95,19 +99,27 @@ var/highlander_claymores = 0
/obj/item/weapon/claymore/highlander/Destroy()
STOP_PROCESSING(SSobj, src)
highlander_claymores--
+ if(nuke_disk)
+ nuke_disk.forceMove(get_turf(src))
+ nuke_disk.visible_message("The nuke disk is vulnerable!")
+ nuke_disk = null
return ..()
/obj/item/weapon/claymore/highlander/process()
if(isliving(loc))
var/mob/living/L = loc
if(L.stat != DEAD)
+ if(!announced)
+ handle_bloodthirst(L)
if(announced || admin_spawned || highlander_claymores > 1)
return
announced = TRUE
L.fully_heal()
- world << "[L.real_name] IS THE ONLY ONE LEFT STANDING!"
+ world << "[uppertext(L.real_name)] IS THE ONLY ONE LEFT STANDING!"
world << sound('sound/misc/highlander_only_one.ogg')
L << "YOU ARE THE ONLY ONE LEFT STANDING!"
+ for(var/obj/item/weapon/bloodcrawl/B in L)
+ qdel(B)
/obj/item/weapon/claymore/highlander/pickup(mob/living/user)
user << "The power of Scotland protects you! You are shielded from all stuns and knockdowns."
@@ -120,12 +132,18 @@ var/highlander_claymores = 0
/obj/item/weapon/claymore/highlander/examine(mob/user)
..()
user << "It has [!notches ? "nothing" : "[notches] notches"] scratched into the blade."
+ if(nuke_disk)
+ user << "It's holding the nuke disk!"
/obj/item/weapon/claymore/highlander/attack(mob/living/target, mob/living/user)
var/old_target_stat = target.stat
. = ..()
+ bloodthirst_level = max(bloodthirst_level - (target.mind && target.mind.special_role == "highlander" ? 15 : 5), 0)
if(target && target.stat == DEAD && old_target_stat != DEAD && target.mind && target.mind.special_role == "highlander")
user.fully_heal() //STEAL THE LIFE OF OUR FALLEN FOES
+ if(bloodthirst_level >= 30)
+ user << "[src] shakes greedily as it devours [target]'s soul. Its bloodthirst is quenched for the moment..."
+ bloodthirst_level = 0
add_notch(user)
target.visible_message("[target] crumbles to dust beneath [user]'s blows!", "As you fall, your body crumbles to dust!")
target.dust()
@@ -138,6 +156,7 @@ var/highlander_claymores = 0
closest_victim = H
if(!closest_victim)
user << "[src] thrums for a moment and falls dark. Perhaps there's nobody nearby."
+ return
user << "[src] thrums and points to the [dir2text(get_dir(user, closest_victim))]."
/obj/item/weapon/claymore/highlander/IsReflect()
@@ -196,6 +215,22 @@ var/highlander_claymores = 0
name = new_name
playsound(user, 'sound/items/Screwdriver2.ogg', 50, 1)
+/obj/item/weapon/claymore/highlander/proc/handle_bloodthirst(mob/living/S) //THE BLADE THIRSTS FOR BLOOD AND WILL PUNISH THE WEAK OR PACIFISTIC
+ bloodthirst_level += (1 + min(notches, 10))
+ if(bloodthirst_level == 30)
+ S << "[src] shudders in your hand. It hungers for battle..."
+ if(bloodthirst_level == 60)
+ S << "[src] trembles violently. Kill someone already!"
+ if(bloodthirst_level == 90)
+ S << "[src] starts shaking viciously! Shed blood or it'll give you away!"
+ if(bloodthirst_level >= 120)
+ var/turf/T = get_turf(S)
+ for(var/mob/M in player_list - S)
+ if(M.z == T.z)
+ M << "THERE IS A COWARD WHO DOES NOT FIGHT TO THE [uppertext(dir2text(get_dir(M, T)))]. THEIR NAME IS [uppertext(S.real_name)] - SLAUGHTER THEM."
+ S << "you fucked up"
+ bloodthirst_level = 100
+
/obj/item/weapon/katana
name = "katana"
desc = "Woefully underpowered in D20"
diff --git a/code/game/objects/structures/divine.dm b/code/game/objects/structures/divine.dm
new file mode 100644
index 00000000000..51415356960
--- /dev/null
+++ b/code/game/objects/structures/divine.dm
@@ -0,0 +1,46 @@
+/obj/structure/sacrificealtar
+ name = "sacrificial altar"
+ desc = "An altar designed to perform blood sacrifice for a deity."
+ icon = 'icons/obj/hand_of_god_structures.dmi'
+ icon_state = "sacrificealtar"
+ anchored = 1
+ density = 0
+ can_buckle = 1
+
+/obj/structure/sacrificealtar/attack_hand(mob/living/user)
+ ..()
+ if(!has_buckled_mobs())
+ return
+ var/mob/living/L = locate() in buckled_mobs
+ if(!L)
+ return
+ user << "You attempt to sacrifice [L] by invoking the sacrificial ritual."
+ L.gib()
+ message_admins("[key_name_admin(user)] has sacrificed [key_name_admin(L)] on the sacrifical altar.")
+
+/obj/structure/healingfountain
+ name = "healing fountain"
+ desc = "A fountain containing the waters of life."
+ icon = 'icons/obj/hand_of_god_structures.dmi'
+ icon_state = "fountain"
+ anchored = 1
+ density = 1
+ var/time_between_uses = 1800
+ var/last_process = 0
+
+/obj/structure/healingfountain/attack_hand(mob/living/user)
+ if(last_process + time_between_uses > world.time)
+ user << "The fountain appears to be empty."
+ return
+ last_process = world.time
+ user << "The water feels warm and soothing as you touch it. The fountain immediately dries up shortly afterwards."
+ user.reagents.add_reagent("godblood",20)
+ update_icons()
+ addtimer(src, "update_icons", time_between_uses)
+
+
+/obj/structure/healingfountain/proc/update_icons()
+ if(last_process + time_between_uses > world.time)
+ icon_state = "fountain"
+ else
+ icon_state = "fountain-red"
\ No newline at end of file
diff --git a/code/game/objects/structures/fluff.dm b/code/game/objects/structures/fluff.dm
index c2fa1e72cf6..13ae66801be 100644
--- a/code/game/objects/structures/fluff.dm
+++ b/code/game/objects/structures/fluff.dm
@@ -120,3 +120,43 @@
name = "dense stack of papers"
desc = "A stack of various papers, childish scribbles scattered across each page."
icon_state = "paperstack"
+
+
+/obj/structure/fluff/divine
+ name = "Miracle"
+ icon = 'icons/obj/hand_of_god_structures.dmi'
+ anchored = 1
+ density = 1
+
+/obj/structure/fluff/divine/nexus
+ name = "nexus"
+ desc = "It anchors a deity to this world. It radiates an unusual aura. It looks well protected from explosive shock."
+ icon_state = "nexus-neutral"
+
+/obj/structure/fluff/divine/conduit
+ name = "conduit"
+ desc = "It allows a deity to extend their reach. Their powers are just as potent near a conduit as a nexus."
+ icon_state = "conduit-neutral"
+
+/obj/structure/fluff/divine/convertaltar
+ name = "conversion altar"
+ desc = "An altar dedicated to a deity."
+ icon_state = "convertaltar-neutral"
+ density = 0
+ can_buckle = 1
+
+/obj/structure/fluff/divine/powerpylon
+ name = "power pylon"
+ desc = "A pylon which increases the deity's rate it can influence the world."
+ icon_state = "powerpylon"
+ can_buckle = 1
+
+/obj/structure/fluff/divine/defensepylon
+ name = "defense pylon"
+ desc = "A pylon which is blessed to withstand many blows, and fire strong bolts at nonbelievers. A god can toggle it."
+ icon_state = "defensepylon"
+
+/obj/structure/fluff/divine/shrine
+ name = "shrine"
+ desc = "A shrine dedicated to a deity."
+ icon_state = "shrine"
\ No newline at end of file
diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm
index 042ce6b307d..56e81172352 100644
--- a/code/game/objects/structures/kitchen_spike.dm
+++ b/code/game/objects/structures/kitchen_spike.dm
@@ -20,6 +20,22 @@
var/obj/F = new /obj/structure/kitchenspike(src.loc,)
transfer_fingerprints_to(F)
qdel(src)
+ else if(istype(I, /obj/item/weapon/weldingtool))
+ var/obj/item/weapon/weldingtool/WT = I
+ if(!WT.remove_fuel(0, user))
+ return
+ user << "You begin cutting \the [src] apart..."
+ playsound(src.loc, "sound/items/Welder.ogg", 40, 1)
+ if(do_after(user, 40/WT.toolspeed, 1, target = src))
+ if(!WT.isOn())
+ return
+ playsound(src.loc, "sound/items/Welder.ogg", 50, 1)
+ visible_message("[user] slices apart \the [src].",
+ "You cut \the [src] apart with \the [WT].",
+ "You hear welding.")
+ new /obj/item/stack/sheet/metal(src.loc, 4)
+ qdel(src)
+ return
else
return ..()
diff --git a/code/game/gamemodes/handofgod/traps.dm b/code/game/objects/structures/traps.dm
similarity index 76%
rename from code/game/gamemodes/handofgod/traps.dm
rename to code/game/objects/structures/traps.dm
index b39475f0ce1..b6c9e0ba7bb 100644
--- a/code/game/gamemodes/handofgod/traps.dm
+++ b/code/game/objects/structures/traps.dm
@@ -1,19 +1,14 @@
-
-/obj/structure/divine/trap
+/obj/structure/trap
name = "IT'S A TARP"
desc = "stepping on me is a guaranteed bad day"
+ icon = 'icons/obj/hand_of_god_structures.dmi'
icon_state = "trap"
density = 0
alpha = 30 //initially quite hidden when not "recharging"
- health = 20
- maxhealth = 20
- trap = TRUE
- autocolours = FALSE
var/last_trigger = 0
var/time_between_triggers = 600 //takes a minute to recharge
-
-/obj/structure/divine/trap/Crossed(atom/movable/AM)
+/obj/structure/trap/Crossed(atom/movable/AM)
if(last_trigger + time_between_triggers > world.time)
return
alpha = initial(alpha)
@@ -24,8 +19,7 @@
trap_effect(L)
animate(src, alpha = initial(alpha), time = time_between_triggers)
-
-/obj/structure/divine/trap/examine(mob/user)
+/obj/structure/trap/examine(mob/user)
..()
if(!isliving(user)) //bad ghosts, stop trying to powergame from beyond the grave
return
@@ -34,17 +28,15 @@
animate(src, alpha = initial(alpha), time = time_between_triggers)
-/obj/structure/divine/trap/proc/trap_effect(mob/living/L)
+/obj/structure/trap/proc/trap_effect(mob/living/L)
return
-
-/obj/structure/divine/trap/stun
+/obj/structure/trap/stun
name = "shock trap"
desc = "A trap that will shock you, it will burn your flesh and render you immobile, You'd better avoid it."
icon_state = "trap-shock"
-
-/obj/structure/divine/trap/stun/trap_effect(mob/living/L)
+/obj/structure/trap/stun/trap_effect(mob/living/L)
L << "You are paralyzed from the intense shock!"
L.Weaken(5)
var/turf/Lturf = get_turf(L)
@@ -52,13 +44,13 @@
new /obj/effect/particle_effect/sparks(Lturf)
-/obj/structure/divine/trap/fire
+/obj/structure/trap/fire
name = "flame trap"
desc = "A trap that will set you ablaze. You'd better avoid it."
icon_state = "trap-fire"
-/obj/structure/divine/trap/fire/trap_effect(mob/living/L)
+/obj/structure/trap/fire/trap_effect(mob/living/L)
L << "Spontaneous combustion!"
L.Weaken(1)
var/turf/Lturf = get_turf(L)
@@ -66,26 +58,26 @@
new /obj/effect/particle_effect/sparks(Lturf)
-/obj/structure/divine/trap/chill
+/obj/structure/trap/chill
name = "frost trap"
desc = "A trap that will chill you to the bone. You'd better avoid it."
icon_state = "trap-frost"
-/obj/structure/divine/trap/chill/trap_effect(mob/living/L)
+/obj/structure/trap/chill/trap_effect(mob/living/L)
L << "You're frozen solid!"
L.Weaken(1)
L.bodytemperature -= 300
new /obj/effect/particle_effect/sparks(get_turf(L))
-/obj/structure/divine/trap/damage
+/obj/structure/trap/damage
name = "earth trap"
desc = "A trap that will summon a small earthquake, just for you. You'd better avoid it."
icon_state = "trap-earth"
-/obj/structure/divine/trap/damage/trap_effect(mob/living/L)
+/obj/structure/trap/damage/trap_effect(mob/living/L)
L << "The ground quakes beneath your feet!"
L.Weaken(5)
L.adjustBruteLoss(35)
@@ -94,16 +86,14 @@
new /obj/structure/flora/rock(Lturf)
-/obj/structure/divine/trap/ward
+/obj/structure/trap/ward
name = "divine ward"
desc = "A divine barrier, It looks like you could destroy it with enough effort, or wait for it to dissipate..."
icon_state = "ward"
- health = 150
- maxhealth = 150
density = 1
time_between_triggers = 1200 //Exists for 2 minutes
-/obj/structure/divine/trap/ward/New()
+/obj/structure/trap/ward/New()
..()
QDEL_IN(src, time_between_triggers)
diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm
index e06fd5bf633..8e4841da760 100644
--- a/code/game/turfs/simulated/floor/plating.dm
+++ b/code/game/turfs/simulated/floor/plating.dm
@@ -235,6 +235,9 @@
slowdown = 2
luminosity = 1
+/turf/open/floor/plating/lava/ex_act()
+ return
+
/turf/open/floor/plating/lava/airless
initial_gas_mix = "TEMP=2.7"
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 07da6355d06..199e00dfd23 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -478,66 +478,6 @@
dat += "FLW | "
dat += ""
- if(ticker.mode.red_deities.len || ticker.mode.red_deity_prophets.len || ticker.mode.blue_deity_prophets.len || ticker.mode.red_deity_followers.len || ticker.mode.blue_deity_followers.len)
- dat += "
| Red Deity | |
"
- for(var/datum/mind/N in ticker.mode.red_deities)
- var/mob/M = N.current
- if(M)
- dat += "| Red Deity: [M.real_name][M.client ? "" : " (No Client)"][M.stat == 2 ? " (DEAD)" : ""] | "
- dat += "PM | "
- dat += "FLW |
"
- dat += "
"
-
- if(ticker.mode.blue_deities.len)
- dat += "
| Blue Deity | |
"
- for(var/datum/mind/N in ticker.mode.blue_deities)
- var/mob/M = N.current
- if(M)
- dat += "| Blue Deity: [M.real_name][M.client ? "" : " (No Client)"][M.stat == 2 ? " (DEAD)" : ""] | "
- dat += "PM | "
- dat += "FLW |
"
- dat += "
"
-
- if(ticker.mode.red_deity_prophets.len)
- dat += "
| Red Deity Prophets | |
"
- for(var/datum/mind/N in ticker.mode.red_deity_prophets)
- var/mob/M = N.current
- if(M)
- dat += "| Red Deity Prophet: [M.real_name][M.client ? "" : " (No Client)"][M.stat == 2 ? " (DEAD)" : ""] | "
- dat += "PM | "
- dat += "FLW |
"
- dat += "
"
-
- if(ticker.mode.blue_deity_prophets.len)
- dat += "
| Blue Deity Prophets | |
"
- for(var/datum/mind/N in ticker.mode.blue_deity_prophets)
- var/mob/M = N.current
- if(M)
- dat += "| Blue Deity Prophet: [M.real_name][M.client ? "" : " (No Client)"][M.stat == 2 ? " (DEAD)" : ""] | "
- dat += "PM | "
- dat += "FLW |
"
- dat += "
"
-
- if(ticker.mode.red_deity_followers.len)
- dat += "
| Red Deity Followers | |
"
- for(var/datum/mind/N in ticker.mode.red_deity_followers)
- var/mob/M = N.current
- if(M)
- dat += "| Red Deity Followers: [M.real_name][M.client ? "" : " (No Client)"][M.stat == 2 ? " (DEAD)" : ""] | "
- dat += "PM | "
- dat += "FLW |
"
- dat += "
"
-
- if(ticker.mode.blue_deity_followers.len)
- dat += "
| Blue Deity Followers | |
"
- for(var/datum/mind/N in ticker.mode.blue_deity_followers)
- var/mob/M = N.current
- if(M)
- dat += "| Blue Deity Followers: [M.real_name][M.client ? "" : " (No Client)"][M.stat == 2 ? " (DEAD)" : ""] | "
- dat += "PM | "
- dat += "FLW |
"
- dat += "
"
-
if(ticker.mode.traitors.len > 0)
dat += "
| Traitors | | |
"
for(var/datum/mind/traitor in ticker.mode.traitors)
diff --git a/code/modules/admin/verbs/onlyone.dm b/code/modules/admin/verbs/onlyone.dm
index affb6b57bc9..fa8998008d6 100644
--- a/code/modules/admin/verbs/onlyone.dm
+++ b/code/modules/admin/verbs/onlyone.dm
@@ -1,60 +1,78 @@
-/client/proc/only_one()
+var/highlander = FALSE
+/client/proc/only_one() //Gives everyone kilts, berets, claymores, and pinpointers, with the objective to hijack the emergency shuttle.
if(!ticker || !ticker.mode)
alert("The game hasn't started yet!")
return
+ highlander = TRUE
world << "THERE CAN BE ONLY ONE!!!"
world << sound('sound/misc/highlander.ogg')
+ for(var/obj/item/weapon/disk/nuclear/N in poi_list)
+ N.relocate() //Gets it out of bags and such
+
for(var/mob/living/carbon/human/H in player_list)
- if(H.stat == DEAD || !(H.client)) continue
-
- ticker.mode.traitors += H.mind
- H.mind.special_role = "highlander"
-
- H.dna.species.specflags |= NOGUNS //nice try jackass
-
- var/datum/objective/steal/steal_objective = new
- steal_objective.owner = H.mind
- steal_objective.set_target(new /datum/objective_item/steal/nukedisc)
- H.mind.objectives += steal_objective
-
- var/datum/objective/hijack/hijack_objective = new
- hijack_objective.explanation_text = "Escape on the shuttle alone. Ensure nobody else makes it out."
- hijack_objective.owner = H.mind
- H.mind.objectives += hijack_objective
-
- H.mind.announce_objectives()
-
- for (var/obj/item/I in H)
- if (istype(I, /obj/item/weapon/implant))
- continue
- qdel(I)
-
- H.equip_to_slot_or_del(new /obj/item/clothing/under/kilt/highlander(H), slot_w_uniform)
- H.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(H), slot_ears)
- H.equip_to_slot_or_del(new /obj/item/clothing/head/beret/highlander(H), slot_head)
- H.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(H), slot_shoes)
- H.equip_to_slot_or_del(new /obj/item/weapon/pinpointer(H.loc), slot_l_store)
-
- var/obj/item/weapon/card/id/W = new(H)
- W.icon_state = "centcom"
- W.access = get_all_accesses()
- W.access += get_all_centcom_access()
- W.assignment = "Highlander"
- W.registered_name = H.real_name
- W.flags |= NODROP
- W.update_label(H.real_name)
- H.equip_to_slot_or_del(W, slot_wear_id)
-
- var/obj/item/weapon/claymore/highlander/H1 = new(H)
- H.put_in_hands(H1)
- H1.pickup(H)
+ if(H.stat == DEAD || !(H.client))
+ continue
+ H.make_scottish()
message_admins("[key_name_admin(usr)] used THERE CAN BE ONLY ONE!")
log_admin("[key_name(usr)] used THERE CAN BE ONLY ONE.")
addtimer(SSshuttle.emergency, "request", 50, FALSE, null, 1)
+/mob/living/carbon/human/proc/make_scottish()
+ ticker.mode.traitors += mind
+ mind.special_role = "highlander"
+ dna.species.specflags |= NOGUNS //nice try jackass
+
+ var/datum/objective/steal/steal_objective = new
+ steal_objective.owner = mind
+ steal_objective.set_target(new /datum/objective_item/steal/nukedisc)
+ mind.objectives += steal_objective
+
+ var/datum/objective/hijack/hijack_objective = new
+ hijack_objective.explanation_text = "Escape on the shuttle alone. Ensure that nobody else makes it out."
+ hijack_objective.owner = mind
+ mind.objectives += hijack_objective
+
+ mind.announce_objectives()
+
+ for(var/obj/item/I in src)
+ if(istype(I, /obj/item/weapon/implant))
+ continue
+ qdel(I)
+ equip_to_slot_or_del(new /obj/item/clothing/under/kilt/highlander(src), slot_w_uniform)
+ equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(src), slot_ears)
+ equip_to_slot_or_del(new /obj/item/clothing/head/beret/highlander(src), slot_head)
+ equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(src), slot_shoes)
+ equip_to_slot_or_del(new /obj/item/weapon/pinpointer(src), slot_l_store)
+ for(var/obj/item/weapon/pinpointer/P in src)
+ P.attack_self(src)
+ var/obj/item/weapon/card/id/W = new(src)
+ W.icon_state = "centcom"
+ W.access = get_all_accesses()
+ W.access += get_all_centcom_access()
+ W.assignment = "Highlander"
+ W.registered_name = real_name
+ W.flags |= NODROP
+ W.update_label(real_name)
+ equip_to_slot_or_del(W, slot_wear_id)
+
+ var/obj/item/weapon/claymore/highlander/H1 = new(src)
+ if(!highlander)
+ H1.admin_spawned = TRUE //To prevent announcing
+ put_in_hands(H1)
+ H1.pickup(src) //For the stun shielding
+
+ var/obj/item/weapon/bloodcrawl/antiwelder = new(src)
+ antiwelder.name = "compulsion of honor"
+ antiwelder.desc = "You are unable to hold anything in this hand until you're the last one left!"
+ antiwelder.icon_state = "bloodhand_right"
+ put_in_hands(antiwelder)
+
+ src << "Your [H1.name] cries out for blood. Join in the slaughter, lest you be claimed yourself...\n\
+ Activate it in your hand, and it will lead to the nearest target. Attack the nuclear authentication disk with it, and you will store it."
+
/proc/only_me()
if(!ticker || !ticker.mode)
alert("The game hasn't started yet!")
diff --git a/code/modules/assembly/flash.dm b/code/modules/assembly/flash.dm
index 27b859bd10c..f174129c534 100644
--- a/code/modules/assembly/flash.dm
+++ b/code/modules/assembly/flash.dm
@@ -190,3 +190,32 @@
item_state = "nullrod"
/obj/item/device/assembly/flash/handheld //this is now the regular pocket flashes
+
+/obj/item/device/assembly/flash/armimplant
+ name = "photon projector"
+ desc = "A high-powered photon projector implant normally used for lighting purposes, but also doubles as a flashbulb weapon. Self-repair protocals fix the flashbulb if it ever burns out."
+ var/flashcd = 20
+ var/overheat = 0
+ var/obj/item/organ/cyberimp/arm/flash/I = null
+
+/obj/item/device/assembly/flash/armimplant/burn_out()
+ if(I && I.owner)
+ I.owner << "Your photon projector implant overheats and deactivates!"
+ I.Retract()
+ overheat = FALSE
+ addtimer(src, "cooldown", flashcd * 2)
+
+/obj/item/device/assembly/flash/armimplant/try_use_flash(mob/user = null)
+ if(overheat)
+ if(I && I.owner)
+ I.owner << "Your photon projector is running too hot to be used again so quickly!"
+ return FALSE
+ overheat = TRUE
+ addtimer(src, "cooldown", flashcd)
+ playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1)
+ update_icon(1)
+ return TRUE
+
+
+/obj/item/device/assembly/flash/armimplant/proc/cooldown()
+ overheat = FALSE
diff --git a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm
index 8208ada42d7..b61e862502c 100644
--- a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm
+++ b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm
@@ -65,7 +65,7 @@ Acts like a normal vent, but has an input AND output.
..()
if(!on)
- return 0
+ return FALSE
var/datum/gas_mixture/air1 = AIR1
var/datum/gas_mixture/air2 = AIR2
@@ -85,6 +85,9 @@ Acts like a normal vent, but has an input AND output.
var/transfer_moles = pressure_delta*environment.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air1.remove(transfer_moles)
+ //Removed can be null if there is no atmosphere in air1
+ if(!removed)
+ return FALSE
loc.assume_air(removed)
air_update_turf()
@@ -105,6 +108,9 @@ Acts like a normal vent, but has an input AND output.
var/transfer_moles = pressure_delta*air2.volume/(environment.temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
+ //removed can be null if there is no air in the location
+ if(!removed)
+ return FALSE
air2.merge(removed)
air_update_turf()
@@ -112,7 +118,7 @@ Acts like a normal vent, but has an input AND output.
var/datum/pipeline/parent2 = PARENT2
parent2.update = 1
- return 1
+ return TRUE
//Radio remote control
@@ -195,4 +201,4 @@ Acts like a normal vent, but has an input AND output.
#undef EXT_BOUND
#undef INPUT_MIN
-#undef OUTPUT_MAX
\ No newline at end of file
+#undef OUTPUT_MAX
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
index f95900688ec..b39fe29c0ff 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
@@ -184,9 +184,10 @@
//Take a gas sample
var/datum/gas_mixture/removed = tile.remove_air(transfer_moles)
- var/list/removed_gases = removed.gases
- if (isnull(removed)) //in space
+ //Nothing left to remove from the tile
+ if (isnull(removed))
return
+ var/list/removed_gases = removed.gases
//Filter it
var/datum/gas_mixture/filtered_out = new
diff --git a/code/modules/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm
index e6cb0ad5723..c6c4e545d42 100644
--- a/code/modules/awaymissions/capture_the_flag.dm
+++ b/code/modules/awaymissions/capture_the_flag.dm
@@ -463,31 +463,27 @@
-/obj/structure/divine/trap/ctf
+/obj/structure/trap/ctf
name = "Spawn protection"
desc = "Stay outta the enemy spawn!"
icon_state = "trap"
- health = INFINITY
- maxhealth = INFINITY
var/team = WHITE_TEAM
- constructable = FALSE
time_between_triggers = 1
alpha = 255
-/obj/structure/divine/trap/examine(mob/user)
+/obj/structure/trap/examine(mob/user)
return
-/obj/structure/divine/trap/ctf/trap_effect(mob/living/L)
+/obj/structure/trap/ctf/trap_effect(mob/living/L)
if(!(src.team in L.faction))
L << "Stay out of the enemy spawn!"
L.death()
-
-/obj/structure/divine/trap/ctf/red
+/obj/structure/trap/ctf/red
team = RED_TEAM
icon_state = "trap-fire"
-/obj/structure/divine/trap/ctf/blue
+/obj/structure/trap/ctf/blue
team = BLUE_TEAM
icon_state = "trap-frost"
diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm
index 5764994c628..b1ed528cb40 100644
--- a/code/modules/cargo/packs.dm
+++ b/code/modules/cargo/packs.dm
@@ -5,6 +5,7 @@ datum/supply_pack
var/contraband = FALSE
var/cost = 700 // Minimum cost, or infinite points are possible.
var/access = FALSE
+ var/access_any = FALSE
var/list/contains = null
var/crate_name = "crate"
var/crate_type = /obj/structure/closet/crate
@@ -17,6 +18,8 @@ datum/supply_pack
C.name = crate_name
if(access)
C.req_access = list(access)
+ if(access_any)
+ C.req_one_access = access_any
fill(C)
@@ -452,6 +455,35 @@ datum/supply_pack
crate_name = "fuel tank crate"
crate_type = /obj/structure/closet/crate/large
+/datum/supply_pack/engineering/oxygen
+ name = "Oxygen Canister"
+ cost = 1500
+ contains = list(/obj/machinery/portable_atmospherics/canister/oxygen)
+ crate_name = "oxygen canister crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/engineering/nitrogen
+ name = "Nitrogen Canister"
+ cost = 2000
+ contains = list(/obj/machinery/portable_atmospherics/canister/nitrogen)
+ crate_name = "nitrogen canister crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/engineering/carbon_dio
+ name = "Carbon Dioxide Canister"
+ cost = 3000
+ contains = list(/obj/machinery/portable_atmospherics/canister/carbon_dioxide)
+ crate_name = "carbon dioxide canister crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/science/nitrous_oxide_canister
+ name = "Nitrous Oxide Canister"
+ cost = 3000
+ access = access_atmospherics
+ contains = list(/obj/machinery/portable_atmospherics/canister/nitrous_oxide)
+ crate_name = "nitrous oxide canister crate"
+ crate_type = /obj/structure/closet/crate/secure
+
/datum/supply_pack/engineering/tools
name = "Toolbox Crate"
contains = list(/obj/item/weapon/storage/toolbox/electrical,
@@ -829,6 +861,24 @@ datum/supply_pack
crate_type = /obj/structure/closet/crate/secure
dangerous = TRUE
+/datum/supply_pack/science/bz_canister
+ name = "BZ Canister"
+ cost = 4000
+ access_any = list(access_rd, access_atmospherics)
+ contains = list(/obj/machinery/portable_atmospherics/canister/bz)
+ crate_name = "bz canister crate"
+ crate_type = /obj/structure/closet/crate/secure
+ dangerous = TRUE
+
+/datum/supply_pack/science/freon_canister
+ name = "Freon Canister"
+ cost = 6000
+ access_any = list(access_rd, access_atmospherics)
+ contains = list(/obj/machinery/portable_atmospherics/canister/freon)
+ crate_name = "freon canister crate"
+ crate_type = /obj/structure/closet/crate/secure
+ dangerous = TRUE
+
/datum/supply_pack/science/research
name = "Machine Prototype Crate"
cost = 8000
@@ -1201,6 +1251,13 @@ datum/supply_pack
crate_name = "high-capacity water tank crate"
crate_type = /obj/structure/closet/crate/large
+/datum/supply_pack/misc/water_vapor
+ name = "Water Vapor Canister"
+ cost = 2500
+ contains = list(/obj/machinery/portable_atmospherics/canister/water_vapor)
+ crate_name = "water vapor canister crate"
+ crate_type = /obj/structure/closet/crate/large
+
/datum/supply_pack/misc/lasertag
name = "Laser Tag Crate"
cost = 1500
diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm
index 40c2a19addb..9109ddefc76 100644
--- a/code/modules/mining/abandoned_crates.dm
+++ b/code/modules/mining/abandoned_crates.dm
@@ -11,12 +11,12 @@
/obj/structure/closet/crate/secure/loot/New()
..()
- var/list/digits = list("1", "2", "3", "4", "5", "6", "7", "8", "9", "z")
+ var/list/digits = list("1", "2", "3", "4", "5", "6", "7", "8", "9", "0")
code = ""
for(var/i = 0, i < codelen, i++)
var/dig = pick(digits)
code += dig
- digits -= dig //Player can enter codes with matching digits, but there are never matching digits in the answer
+ digits -= dig //there are never matching digits in the answer
var/loot = rand(1,100) //100 different crates with varying chances of spawning
switch(loot)
@@ -153,18 +153,26 @@
/obj/structure/closet/crate/secure/loot/attack_hand(mob/user)
if(locked)
user << "The crate is locked with a Deca-code lock."
- var/input = input(usr, "Enter [codelen] digits.", "Deca-Code Lock", "") as text
+ var/input = input(usr, "Enter [codelen] digits. All digits must be unique.", "Deca-Code Lock", "") as text
if(user.canUseTopic(src, 1))
+ var/list/sanitised = list()
+ var/sanitycheck = 1
+ for(var/i=1,i<=length(input),i++) //put the guess into a list
+ sanitised += text2num(copytext(input,i,i+1))
+ for(var/i=1,i<=(length(input)-1),i++) //compare each digit in the guess to all those following it
+ for(var/j=(i+1),j<=length(input),j++)
+ if(sanitised[i] == sanitised[j])
+ sanitycheck = null //if a digit is repeated, reject the input
if (input == code)
user << "The crate unlocks!"
locked = 0
cut_overlays()
add_overlay("securecrateg")
- else if (input == null || length(input) != codelen)
+ else if (input == null || sanitycheck == null || length(input) != codelen)
user << "You leave the crate alone."
else
user << "A red light flashes."
- lastattempt = replacetext(input, 0, "z")
+ lastattempt = input
attempts--
if(attempts == 0)
boom(user)
@@ -192,19 +200,21 @@
user << "* Anti-Tamper Bomb will activate after [src.attempts] failed access attempts."
if(lastattempt != null)
var/list/guess = list()
+ var/list/answer = list()
var/bulls = 0
var/cows = 0
- for(var/i = 1, i < codelen + 1, i++)
- var/a = copytext(lastattempt, i, i+1) //Stuff the code into the list
- guess += a
- guess[a] = i
- for(var/i in guess) //Go through list and count matches
- var/a = findtext(code, i)
- if(a == guess[i])
- ++bulls
- else if(a)
+ for(var/i=1,i<=length(lastattempt),i++)
+ guess += text2num(copytext(lastattempt,i,i+1))
+ for(var/i=1,i<=length(lastattempt),i++)
+ answer += text2num(copytext(code,i,i+1))
+ for(var/i = 1, i < codelen + 1, i++) // Go through list and count matches
+ if( answer.Find(guess[i],1,codelen+1))
++cows
- user << "Last code attempt had [bulls] correct digits at correct positions and [cows] correct digits at incorrect positions."
+ if( answer[i] == guess[i])
+ ++bulls
+ --cows
+
+ user << "Last code attempt, [lastattempt], had [bulls] correct digits at correct positions and [cows] correct digits at incorrect positions."
return
return ..()
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index 02e71c0f08f..365e3ade3f6 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -704,15 +704,13 @@
/obj/structure/closet/crate/necropolis/bubblegum/New()
..()
- var/loot = rand(1,4)
+ var/loot = rand(1,3)
switch(loot)
if(1)
- new /obj/item/weapon/antag_spawner/slaughter_demon(src)
- if(2)
new /obj/item/mayhem(src)
- if(3)
+ if(2)
new /obj/item/blood_contract(src)
- if(4)
+ if(3)
new /obj/item/weapon/gun/magic/staff/spellblade(src)
/obj/item/blood_contract
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 0198c4a1cf8..94ee29b74b0 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -672,7 +672,8 @@
if(B)
B.damaged_brain = 0
for(var/datum/disease/D in viruses)
- D.cure(0)
+ if (D.severity != NONTHREAT)
+ D.cure(0)
if(admin_revive)
regenerate_limbs()
handcuffed = initial(handcuffed)
diff --git a/code/modules/mob/living/silicon/login.dm b/code/modules/mob/living/silicon/login.dm
index 87e348dd92c..e0c6708d564 100644
--- a/code/modules/mob/living/silicon/login.dm
+++ b/code/modules/mob/living/silicon/login.dm
@@ -3,5 +3,4 @@
ticker.mode.remove_cultist(mind, 0, 0)
ticker.mode.remove_revolutionary(mind, 0)
ticker.mode.remove_gangster(mind, remove_bosses=1)
- ticker.mode.remove_hog_follower(mind,0)
..()
diff --git a/code/modules/mob/living/silicon/robot/login.dm b/code/modules/mob/living/silicon/robot/login.dm
index 30712e68b42..59bcff4fa60 100644
--- a/code/modules/mob/living/silicon/robot/login.dm
+++ b/code/modules/mob/living/silicon/robot/login.dm
@@ -6,4 +6,3 @@
if(mind)
ticker.mode.remove_revolutionary(mind)
ticker.mode.remove_gangster(mind,1,remove_bosses=1)
- ticker.mode.remove_hog_follower(mind, 0)
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 76f8e90ef6e..6f56ca375b9 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -785,9 +785,8 @@
if(isturf(tile))
tile.clean_blood()
for(var/A in tile)
- if(istype(A, /obj/effect))
- if(is_cleanable(A))
- qdel(A)
+ if(is_cleanable(A))
+ qdel(A)
else if(istype(A, /obj/item))
var/obj/item/cleaned_item = A
cleaned_item.clean_blood()
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 34017a7c64e..7658a71c484 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -402,4 +402,4 @@
/datum/robot_energy_storage/medical
max_energy = 2500
recharge_rate = 250
- name = "Medical Synthesizer"
+ name = "Medical Synthesizer"
diff --git a/code/modules/mob/living/simple_animal/friendly/cockroach.dm b/code/modules/mob/living/simple_animal/friendly/cockroach.dm
index 9d6a9ab7f64..fc4045ae569 100644
--- a/code/modules/mob/living/simple_animal/friendly/cockroach.dm
+++ b/code/modules/mob/living/simple_animal/friendly/cockroach.dm
@@ -53,4 +53,3 @@
icon = 'icons/effects/blood.dmi'
icon_state = "xfloor1"
random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7")
- layer = ABOVE_OPEN_TURF_LAYER
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
index 5dcfcc2b9ed..fb94224fbbf 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
@@ -46,7 +46,7 @@
staticOverlays = list()
hud_possible = list(DIAG_STAT_HUD, DIAG_HUD, ANTAG_HUD)
unique_name = TRUE
- faction = list("silicon")
+ faction = list("neutral","silicon")
dextrous = TRUE
dextrous_hud_type = /datum/hud/dextrous/drone
var/staticChoice = "static"
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
index f961094c4c9..b64463f3b7c 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
@@ -9,15 +9,15 @@ Bubblegum's footsteps are heralded by shaking booms, proving its tremendous size
It acts as a melee creature, chasing down and attacking its target while also using different attacks to augment its power that increase as it takes damage.
-It often charges, dealing massive damage to anything unfortunate enough to be standing where it's aiming.
-Whenever it isn't chasing something down, it will sink into nearby blood pools (if possible) and springs out of the closest one to its target.
-To make this possible, it sprays streams of blood at random.
-From these blood pools Bubblegum may summon slaughterlings - weak, low-damage minions designed to impede the target's progress.
+It tries to strike at its target through any bloodpools under them; if it fails to do that, it will spray blood and then attempt to warp to a bloodpool near the target.
+If it fails to warp to a target, it may summon up to 6 slaughterlings from the blood around it.
+If it does not summon all 6 slaughterlings, it will instead charge at its target, dealing massive damage to anything it hits and spraying a stream of blood.
+At half health, it will either charge three times or warp, then charge, instead of doing a single charge.
When Bubblegum dies, it leaves behind a chest that can contain three things:
- 1. A slaughter demon spawner
- 2. A bottle that, when activated, drives everyone nearby into a frenzy
- 3. A contract that marks for death the chosen target
+ 1. A bottle that, when activated, drives everyone nearby into a frenzy
+ 2. A contract that marks for death the chosen target
+ 3. A spellblade that can slice off limbs at range
Difficulty: Hard
@@ -45,6 +45,7 @@ Difficulty: Hard
pixel_x = -32
del_on_death = 1
loot = list(/obj/structure/closet/crate/necropolis/bubblegum)
+ blood_volume = BLOOD_VOLUME_MAXIMUM //BLEED FOR ME
var/charging = 0
medal_type = MEDAL_PREFIX
score_type = BUBBLEGUM_SCORE
@@ -57,6 +58,12 @@ Difficulty: Hard
desc = "You're not quite sure how a signal can be bloody."
invisibility = 100
+/mob/living/simple_animal/hostile/megafauna/bubblegum/adjustBruteLoss(amount)
+ if(amount > 0 && prob(33))
+ var/obj/effect/decal/cleanable/blood/B = new /obj/effect/decal/cleanable/blood(loc)
+ B.bloodiness = 20
+ . = ..()
+
/mob/living/simple_animal/hostile/megafauna/bubblegum/Life()
..()
move_to_delay = Clamp(round((health/maxHealth) * 10), 5, 10)
@@ -67,18 +74,21 @@ Difficulty: Hard
return
ranged_cooldown = world.time + ranged_cooldown_time
- blood_warp()
-
- if(prob(25))
+ var/warped = FALSE
+ if(!try_bloodattack())
addtimer(src, "blood_spray", 0)
+ warped = blood_warp()
+ if(warped && prob(100 - anger_modifier))
+ return
- else if(prob(5+anger_modifier/2))
- slaughterlings()
- else
- if(health > maxHealth/2 && !client)
+ if(prob(90 - anger_modifier) || slaughterlings())
+ if(health > maxHealth * 0.5 || client)
addtimer(src, "charge", 0)
else
- addtimer(src, "triple_charge", 0)
+ if(prob(70) || warped)
+ addtimer(src, "triple_charge", 0)
+ else
+ addtimer(src, "warp_charge", 0)
/mob/living/simple_animal/hostile/megafauna/bubblegum/New()
@@ -109,20 +119,22 @@ Difficulty: Hard
..()
/mob/living/simple_animal/hostile/megafauna/bubblegum/Move()
- if(!stat)
- playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1, 2, 1)
if(charging)
PoolOrNew(/obj/effect/overlay/temp/decoy/fading, list(loc,src))
DestroySurroundings()
. = ..()
+ if(!stat && .)
+ playsound(src, 'sound/effects/meteorimpact.ogg', 200, 1, 2, 1)
if(charging)
DestroySurroundings()
+/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/warp_charge()
+ blood_warp()
+ charge()
+
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/triple_charge()
charge()
- sleep(10)
charge()
- sleep(10)
charge()
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge()
@@ -139,6 +151,7 @@ Difficulty: Hard
sleep(5)
throw_at(T, get_dist(src, T), 1, src, 0)
charging = 0
+ try_bloodattack()
Goto(target, move_to_delay, minimum_distance)
@@ -166,17 +179,132 @@ Difficulty: Hard
charging = 0
+/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_mobs_on_blood()
+ var/list/targets = ListTargets()
+ . = list()
+ for(var/mob/living/L in targets)
+ var/list/bloodpool = get_pools(get_turf(L), 0)
+ if(bloodpool.len && !faction_check(L))
+ . += L
+
+/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/try_bloodattack()
+ var/list/targets = get_mobs_on_blood()
+ if(targets.len)
+ addtimer(src, "bloodattack", 0, FALSE, targets)
+
+ return TRUE
+ return FALSE
+
+/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodattack(list/targets)
+ var/mob/living/target_one = pick_n_take(targets)
+ var/turf/target_one_turf = get_turf(target_one)
+ var/mob/living/target_two
+ if(targets.len)
+ target_two = pick_n_take(targets)
+ var/turf/target_two_turf = get_turf(target_two)
+ if(target_two.stat != CONSCIOUS || prob(10))
+ PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightpaw, target_two_turf)
+ PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightthumb, target_two_turf)
+ bloodgrab(target_two_turf)
+ else
+ PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightsmack, target_two_turf)
+ bloodsmack(target_two_turf)
+
+ var/list/pools = get_pools(get_turf(target_one), 0)
+ if(pools.len)
+ target_one_turf = get_turf(target_one)
+ if(target_one.stat != CONSCIOUS || prob(10))
+ PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/leftpaw, target_one_turf)
+ PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/leftthumb, target_one_turf)
+ bloodgrab(target_one_turf)
+ else
+ PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/leftsmack, target_one_turf)
+ bloodsmack(target_one_turf)
+
+ if(!target_two && target_one)
+ pools = get_pools(get_turf(target_one), 0)
+ if(pools.len)
+ target_one_turf = get_turf(target_one)
+ if(target_one.stat != CONSCIOUS || prob(10))
+ PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightpaw, target_one_turf)
+ PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightthumb, target_one_turf)
+ bloodgrab(target_one_turf)
+ else
+ PoolOrNew(/obj/effect/overlay/temp/bubblegum_hands/rightsmack, target_one_turf)
+ bloodsmack(target_one_turf)
+
+/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodsmack(turf/T)
+ sleep(2.5)
+ for(var/mob/living/L in T)
+ if(!faction_check(L))
+ L << "[src] rends you!"
+ playsound(T, attack_sound, 100, 1, -1)
+ var/limb_to_hit = L.get_bodypart(pick("head", "chest", "r_arm", "l_arm", "r_leg", "l_leg"))
+ L.apply_damage(25, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, "melee", null, null, armour_penetration))
+ sleep(3)
+
+/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodgrab(turf/T)
+ sleep(6)
+ for(var/mob/living/L in T)
+ if(!faction_check(L))
+ L << "[src] drags you through the blood!"
+ playsound(T, 'sound/magic/enter_blood.ogg', 100, 1, -1)
+ var/turf/targetturf = get_step(src, dir)
+ L.forceMove(targetturf)
+ playsound(targetturf, 'sound/magic/exit_blood.ogg', 100, 1, -1)
+ if(L.stat != CONSCIOUS)
+ addtimer(src, "devour", 2, FALSE, L)
+ sleep(1)
+
+/obj/effect/overlay/temp/bubblegum_hands
+ icon = 'icons/effects/bubblegum.dmi'
+ duration = 9
+
+/obj/effect/overlay/temp/bubblegum_hands/rightthumb
+ icon_state = "rightthumbgrab"
+
+/obj/effect/overlay/temp/bubblegum_hands/leftthumb
+ icon_state = "leftthumbgrab"
+
+/obj/effect/overlay/temp/bubblegum_hands/rightpaw
+ icon_state = "rightpawgrab"
+ layer = BELOW_MOB_LAYER
+
+/obj/effect/overlay/temp/bubblegum_hands/leftpaw
+ icon_state = "leftpawgrab"
+ layer = BELOW_MOB_LAYER
+
+/obj/effect/overlay/temp/bubblegum_hands/rightsmack
+ icon_state = "rightsmack"
+
+/obj/effect/overlay/temp/bubblegum_hands/leftsmack
+ icon_state = "leftsmack"
+
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_warp()
+ if(Adjacent(target))
+ return FALSE
+ var/list/can_jaunt = get_pools(get_turf(src), 1)
+ if(!can_jaunt.len)
+ return FALSE
+
+ var/list/pools = get_pools(get_turf(target), 2)
+ var/list/pools_to_remove = get_pools(get_turf(target), 1)
+ pools -= pools_to_remove
+ if(!pools.len)
+ return FALSE
+
+ var/obj/effect/overlay/temp/decoy/DA = PoolOrNew(/obj/effect/overlay/temp/decoy, list(loc,src))
+ DA.color = "#FF0000"
+ var/oldtransform = DA.transform
+ DA.transform = matrix()*2
+ animate(DA, alpha = 255, color = initial(DA.color), transform = oldtransform, time = 5)
+ sleep(5)
+ qdel(DA)
+
var/obj/effect/decal/cleanable/blood/found_bloodpool
- var/list/pools = list()
- var/can_jaunt = FALSE
- for(var/obj/effect/decal/cleanable/blood/nearby in view(src,2))
- can_jaunt = TRUE
- break
- if(!can_jaunt)
- return
- for(var/obj/effect/decal/cleanable/blood/nearby in view(get_turf(target),2))
- pools += nearby
+ pools = get_pools(get_turf(target), 2)
+ pools_to_remove = get_pools(get_turf(target), 1)
+ pools -= pools_to_remove
if(pools.len)
shuffle(pools)
found_bloodpool = pick(pools)
@@ -186,35 +314,56 @@ Difficulty: Hard
forceMove(get_turf(found_bloodpool))
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1)
visible_message("And springs back out!")
+ return TRUE
+ return FALSE
+/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/get_pools(turf/T, range)
+ . = list()
+ for(var/obj/effect/decal/cleanable/blood/nearby in view(T, range))
+ . += nearby
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/blood_spray()
visible_message("[src] sprays a stream of gore!")
- var/turf/E = get_edge_target_turf(src, src.dir)
- var/range = 10
+ var/range = 6 + round(anger_modifier * 0.4)
var/turf/previousturf = get_turf(src)
- for(var/turf/J in getline(src,E))
- if(!range)
- break
+ var/turf/J = previousturf
+ var/targetdir = get_dir(src, target)
+ if(target.loc == loc)
+ targetdir = dir
+ face_atom(target)
+ new /obj/effect/decal/cleanable/blood(J)
+ for(var/i in 1 to range)
+ J = get_step(previousturf, targetdir)
PoolOrNew(/obj/effect/overlay/temp/dir_setting/bloodsplatter, list(previousturf, get_dir(previousturf, J)))
- if(!previousturf.CanAtmosPass(J))
+ playsound(previousturf,'sound/effects/splat.ogg', 100, 1, -1)
+ if(!J || !previousturf.CanAtmosPass(J))
break
- playsound(J,'sound/effects/splat.ogg', 100, 1, -1)
- new /obj/effect/decal/cleanable/blood(J)
- range--
+ var/obj/effect/decal/cleanable/blood/B = new /obj/effect/decal/cleanable/blood(J)
+ B.bloodiness = 0
previousturf = J
sleep(1)
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/slaughterlings()
visible_message("[src] summons a shoal of slaughterlings!")
- for(var/obj/effect/decal/cleanable/blood/H in range(src, 10))
- if(prob(25))
- new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/slaughter(H.loc)
+ var/max_amount = 6
+ for(var/H in get_pools(get_turf(src), 1))
+ if(!max_amount)
+ break
+ max_amount--
+ var/obj/effect/decal/cleanable/blood/B = H
+ new /mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/slaughter(B.loc)
+ return max_amount
/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/slaughter
name = "slaughterling"
desc = "Though not yet strong enough to create a true physical form, it's nonetheless determined to murder you."
- faction = list("mining")
+ density = 0
+ faction = list("mining", "boss")
weather_immunities = list("lava","ash")
+/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/slaughter/CanPass(atom/movable/mover, turf/target, height = 0)
+ if(istype(mover, /mob/living/simple_animal/hostile/megafauna/bubblegum))
+ return 1
+ return 0
+
#undef MEDAL_PREFIX
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
index c144c200d3b..37aa5575a9b 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
@@ -87,7 +87,7 @@ Difficulty: Hard
did_reset = TRUE
//visible_message("\"Vixyvrmrk xs fewi...\"")
blink(spawned_rune)
- adjustHealth(max((health - maxHealth) * 0.5, 25)) //heal for 50% of our missing health
+ adjustHealth(min((health - maxHealth) * 0.5, -50)) //heal for 50% of our missing health
wander = FALSE
/*if(health > maxHealth * 0.9)
visible_message("\"Vitemvw gsqtpixi. Stivexmrk ex qebmqyq ijjmgmirgc.\"")
diff --git a/code/modules/mob/living/simple_animal/hostile/skeleton.dm b/code/modules/mob/living/simple_animal/hostile/skeleton.dm
index ad20e68458e..4664a41082c 100644
--- a/code/modules/mob/living/simple_animal/hostile/skeleton.dm
+++ b/code/modules/mob/living/simple_animal/hostile/skeleton.dm
@@ -70,7 +70,7 @@
loot = list(/obj/effect/decal/remains/human,
/obj/item/clothing/suit/armor/riot/knight/templar,
/obj/item/clothing/head/helmet/knight/templar,
- /obj/item/weapon/claymore/hog{name = "holy sword"})
+ /obj/item/weapon/claymore/weak{name = "holy sword"})
/mob/living/simple_animal/hostile/skeleton/ice
name = "ice skeleton"
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 40d23ea638d..e59f4708e90 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -465,3 +465,15 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
M << "There were no ghosts willing to take control."
message_admins("No ghosts were willing to take control of [key_name_admin(M)])")
return FALSE
+
+//toggles the talk wheel
+/mob/verb/toggle_talk_wheel()
+ set name = "talk-wheel"
+ set hidden = 1
+
+ if(isliving(src))
+ var/mob/living/L = src
+ if(L.hud_used)
+ for(var/obj/screen/wheel/talk/TW in L.hud_used.wheels)
+ TW.Click()
+
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 3c2c95fbbf8..e947d24c1a7 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -332,6 +332,9 @@
data_core.manifest_inject(humanc)
AnnounceArrival(humanc, rank)
AddEmploymentContract(humanc)
+ if(highlander)
+ humanc << "THERE CAN BE ONLY ONE!!!"
+ humanc.make_scottish()
joined_player_list += character.ckey
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index 9ba2db5975b..6f662412c65 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -486,23 +486,6 @@
qdel(src)
-/mob/proc/become_god(var/side_colour)
- var/mob/camera/god/G = new /mob/camera/god(loc)
- G.side = side_colour
- if(mind)
- mind.transfer_to(G)
- else
- G.key = key
-
- G.job = "Deity"
- G.rename_self("deity")
- G.update_icons()
-
- . = G
- qdel(src)
-
-
-
/mob/living/carbon/human/proc/corgize()
if (notransform)
return
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 7c311d980b3..c38d9023457 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -188,11 +188,9 @@
if("emote")
M.visible_message("[M] [pick("whimpers quietly", "shivers as though cold", "glances around in paranoia")].")
if(data >= 75) // 30 units, 135 seconds
- if(iscultist(M) || is_handofgod_cultist(M) || is_handofgod_prophet(M) || is_servant_of_ratvar(M))
+ if(iscultist(M) || is_servant_of_ratvar(M))
if(iscultist(M))
ticker.mode.remove_cultist(M.mind, 1, 1)
- else if(is_handofgod_cultist(M) || is_handofgod_prophet(M))
- ticker.mode.remove_hog_follower(M.mind)
else if(is_servant_of_ratvar(M))
remove_servant_of_ratvar(M)
holder.remove_reagent(id, volume) // maybe this is a little too perfect and a max() cap on the statuses would be better??
diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
index ab7c9dd746e..ec261d12045 100644
--- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
+++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm
@@ -69,7 +69,7 @@
R.adjustHealth(50)
sleep(20)
for(var/mob/living/carbon/C in get_hearers_in_view(round(created_volume/48,1),get_turf(holder.my_atom)))
- if(iscultist(C) || is_handofgod_cultist(C))
+ if(iscultist(C))
C << "The divine explosion sears you!"
C.Weaken(2)
C.adjust_fire_stacks(5)
diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm
index 1676c8339e0..469be2bbbb2 100644
--- a/code/modules/reagents/reagent_containers/glass.dm
+++ b/code/modules/reagents/reagent_containers/glass.dm
@@ -212,6 +212,9 @@
/obj/item/weapon/reagent_containers/glass/beaker/large/epinephrine
name = "epinephrine reserve tank"
list_reagents = list("epinephrine" = 50)
+
+/obj/item/weapon/reagent_containers/glass/beaker/synthflesh
+ list_reagents = list("synthflesh" = 50)
/obj/item/weapon/reagent_containers/glass/bucket
name = "bucket"
diff --git a/code/modules/research/designs/limbgrower_designs.dm b/code/modules/research/designs/limbgrower_designs.dm
new file mode 100644
index 00000000000..591888bfd9d
--- /dev/null
+++ b/code/modules/research/designs/limbgrower_designs.dm
@@ -0,0 +1,43 @@
+/////////////////////////////////////
+//////////Limb Grower Designs ///////
+/////////////////////////////////////
+
+/datum/design/leftarm
+ name = "Left Arm"
+ id = "leftarm"
+ build_type = LIMBGROWER
+ reagents = list("synthflesh" = 25)
+ build_path = /obj/item/bodypart/l_arm
+ category = list("initial","human","lizard","plasmaman")
+
+/datum/design/rightarm
+ name = "Right Arm"
+ id = "rightarm"
+ build_type = LIMBGROWER
+ reagents = list("synthflesh" = 25)
+ build_path = /obj/item/bodypart/r_arm
+ category = list("initial","human","lizard","plasmaman")
+
+/datum/design/leftleg
+ name = "Left Leg"
+ id = "leftleg"
+ build_type = LIMBGROWER
+ reagents = list("synthflesh" = 25)
+ build_path = /obj/item/bodypart/l_leg
+ category = list("initial","human","lizard","plasmaman")
+
+/datum/design/rightleg
+ name = "Right Leg"
+ id = "rightleg"
+ build_type = LIMBGROWER
+ reagents = list("synthflesh" = 25)
+ build_path = /obj/item/bodypart/r_leg
+ category = list("initial","human","lizard","plasmaman")
+
+/datum/design/armblade
+ name = "Arm Blade"
+ id = "armblade"
+ build_type = LIMBGROWER
+ reagents = list("synthflesh" = 75)
+ build_path = /obj/item/weapon/melee/synthetic_arm_blade
+ category = list("special")
\ No newline at end of file
diff --git a/code/modules/research/research.dm b/code/modules/research/research.dm
index 94bc846e530..6d1cabc38b8 100644
--- a/code/modules/research/research.dm
+++ b/code/modules/research/research.dm
@@ -143,6 +143,16 @@ research holder datum.
if((D.build_type & AUTOLATHE) && ("initial" in D.category)) //autolathe starts without hacked designs
AddDesign2Known(D)
+//Limb Grower files
+/datum/research/limbgrower/New()
+ for(var/T in (subtypesof(/datum/tech)))
+ possible_tech += new T(src)
+ for(var/path in subtypesof(/datum/design))
+ var/datum/design/D = new path(src)
+ possible_designs += D
+ if((D.build_type & LIMBGROWER) && ("initial" in D.category))
+ AddDesign2Known(D)
+
/datum/research/autolathe/AddDesign2Known(datum/design/D)
if(!(D.build_type & AUTOLATHE))
return
diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm
index 76220ef9ddc..9cfed984f4c 100644
--- a/code/modules/surgery/organs/augments_arms.dm
+++ b/code/modules/surgery/organs/augments_arms.dm
@@ -68,6 +68,10 @@
"[holder] snaps back into your [zone == "r_arm" ? "right" : "left"] arm.",
"You hear a short mechanical noise.")
+ if(istype(holder, /obj/item/device/assembly/flash/armimplant))
+ var/obj/item/device/assembly/flash/F = holder
+ F.SetLuminosity(0)
+
owner.unEquip(holder, 1)
holder.loc = src
holder = null
@@ -85,6 +89,10 @@
holder.w_class = 5
holder.materials = null
+ if(istype(holder, /obj/item/device/assembly/flash/armimplant))
+ var/obj/item/device/assembly/flash/F = holder
+ F.SetLuminosity(7)
+
var/obj/item/arm_item = owner.get_active_held_item()
if(arm_item)
@@ -178,3 +186,45 @@
items_list += new /obj/item/weapon/kitchen/knife/combat/cyborg(src)
return 1
return 0
+
+/obj/item/organ/cyberimp/arm/esword
+ name = "arm-mounted energy blade"
+ desc = "An illegal, and highly dangerous cybernetic implant that can project a deadly blade of concentrated enregy."
+ contents = newlist(/obj/item/weapon/melee/energy/blade)
+
+/obj/item/organ/cyberimp/arm/medibeam
+ name = "integrated medical beamgun"
+ desc = "A cybernetic implant that allows the user to project a healing beam from their hand."
+ contents = newlist(/obj/item/weapon/gun/medbeam)
+
+/obj/item/organ/cyberimp/arm/flash
+ name = "integrated high-intensity photon projector" //Why not
+ desc = "An integrated projector mounted onto a user's arm, that is able to be used as a powerful flash."
+ contents = newlist(/obj/item/device/assembly/flash/armimplant)
+
+/obj/item/organ/cyberimp/arm/flash/New()
+ ..()
+ if(locate(/obj/item/device/assembly/flash/armimplant) in items_list)
+ var/obj/item/device/assembly/flash/armimplant/F = locate(/obj/item/device/assembly/flash/armimplant) in items_list
+ F.I = src
+
+/obj/item/organ/cyberimp/arm/baton
+ name = "arm electrification implant"
+ desc = "An illegal combat implant that allows the user to administer disabling shocks from their arm."
+ contents = newlist(/obj/item/borg/stun)
+
+/obj/item/organ/cyberimp/arm/combat
+ name = "combat cybernetics implant"
+ desc = "A powerful cybernetic implant that contains combat modules built into the user's arm"
+ contents = newlist(/obj/item/weapon/melee/energy/blade, /obj/item/weapon/gun/medbeam, /obj/item/borg/stun, /obj/item/device/assembly/flash/armimplant)
+
+/obj/item/organ/cyberimp/arm/combat/New()
+ ..()
+ if(locate(/obj/item/device/assembly/flash/armimplant) in items_list)
+ var/obj/item/device/assembly/flash/armimplant/F = locate(/obj/item/device/assembly/flash/armimplant) in items_list
+ F.I = src
+
+/obj/item/organ/cyberimp/arm/surgery
+ name = "surgical toolset implant"
+ desc = "A set of surgical tools hidden behind a concealed panel on the user's arm"
+ contents = newlist(/obj/item/weapon/retractor, /obj/item/weapon/hemostat, /obj/item/weapon/cautery, /obj/item/weapon/surgicaldrill, /obj/item/weapon/scalpel, /obj/item/weapon/circular_saw, /obj/item/weapon/surgical_drapes)
diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm
index b977b039dff..5121e955a1b 100644
--- a/code/modules/surgery/organs/augments_chest.dm
+++ b/code/modules/surgery/organs/augments_chest.dm
@@ -197,3 +197,4 @@
toggle(silent=1)
return 0
+
diff --git a/html/changelog.html b/html/changelog.html
index 85e774e50bf..0a1e74bb5a1 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -55,6 +55,70 @@
-->
+
20 September 2016
+
Ergovisavi updated:
+
+ - fixed "friendly" xenobio mobs and mining drones attacking station drones
+
+
Joan updated:
+
+ - Miners can now buy KA AoE damage mods from the mining vendor for 2000 points per mod.
+ - Combined the Convert and Sacrifice runes into one rune. It'll convert targets that are alive and eligible, and attempt to sacrifice them otherwise. The only changes to mechanics are that: Converting someone will heal them of all brute and burn damage they had, and sacrificing anything will always produce a soulstone(but will still only sometimes fill it)
+ - You can no longer teleport to Teleport runes that have dense objects on top of them.
+ - Wall runes will now activate other nearby wall runes when activated, but will automatically disable after a minute and a half of continuous activity and become unusable for 5 seconds.
+ - The Blood Boil rune no longer does all of its damage instantly or stuns, but if you remain in range for the full duration you will be sent deep into critical.
+ - Bubblegum has been seen reaching through blood. Try not to get hit.
+ - The Raise Dead rune no longer requires a noncultist corpse to revive a cultist; instead, it will draw from the pool of all people sacrificed to power the rune.
+
+
Mekhi updated:
+
+ - Nanotrasen has been experimenting on cybernetics for a while, and rumors are they have a few combat prototypes available...
+ - New arm implants: Energy-blade projector, implanted medical beamgun, stun-arm implant (Like the borg version), flash implant that is automatically-regenerating and doubles as a powerful flashlight. There is also one with all four items in one. Also, a surgery toolkit implant. Adminspawn only for the moment.
+
+
MrStonedOne updated:
+
+ - Fixed space/nograv movement not triggering when atoms moved twice quickly in space/nograv
+
+
Nanotrasen Stress Relief Board updated:
+
+ - Latecomers to highlander can now join in on the fun.
+ - The crew are encouraged to less pacifistic during highlander. Failing to shed blood will result in your soul being devoured. Have a nice day.
+
+
Nicho1010 updated:
+
+ - Fixed lattices appearing after exploding lava
+
+
Screemonster updated:
+
+ - Abandoned crates no longer accept impossible guesses.
+ - Lets players know that all the digits in the code must be unique.
+ - Reads the last guess back on the multitool along with the correct/incorrect guess readout.
+ - multitool output on crates no longer returns nonsense values.
+
+
XDTM updated:
+
+ - Positive viruses are now recognized by medical HUDs with a special icon.
+ - fully_heal no longer removes nonharmful viruses. This affects legion souls, staffs of healing, and changeling's revive.
+ - Canisters of any type of gas are now orderable in cargo. Dangerous experimental gases will require Research Director approval.
+
+
Yackemflam updated:
+
+ - The syndicate has learned on how to give their agents a true syndicate ninja experience.
+
+
chickenboy10 updated:
+
+ - Added a Experimental Limb Grower to the medbay department, now medical stuff can grow synthetic limbs using Synthflesh to help crew that suffer any work related accidents. There may also be a limb that can be grown with a special card...
+
+
feemjmeem updated:
+
+ - You can now disassemble meatspike frames with a welding tool.
+
+
phil235 updated:
+
+ - adds a talk button next to the crafting button. Clicking it makes a "wheel" appear around you with short predetermined messages that you click to say them. This lets you say common responses without having to type in the chat bar. Current messages available are: "Hi", "Bye", "Thanks", "Come", "Help", "Stop", "Get out", "Yes", and "No". The talk button can be activated with the hotkey "H" or "CTRL+H"
+ - Wearing colored glasses colors your vision. This option can be enabled/disabled by alt-clicking any glasses with such feature.
+
+
17 September 2016
BoxcarRacer41 updated:
@@ -1056,47 +1120,6 @@
- Clockwork cultists may now have the "Escape" and "Silicon" objectives, requiring a certain amount of servants to escape on the shuttle and all silicons to be converted respectively.
- Ocular wardens are now forced to target bibles rather than the people holding them.
-
-
19 July 2016
-
Joan updated:
-
- - Cogscarabs can no longer pass mobs and have slightly less health.
- - The Gateway to the Celestial Derelict can now take damage from bombs.
-
-
RemieRichards updated:
-
- - Added VR Sleepers that allow users to enter a virtual body in a virtual world (Currently not mapped in ;_;)
-
-
Xhuis updated:
-
- - Added communication intercept texts for gamemodes that were missing them.
- - Changed all intercept texts and improved grammar for a lot of key game code.
- - The shuttle can now leave while a celestial gateway exists.
- - If the shuttle docks at Central Command while a celestial gateway exists, Ratvar's servants will win a minor victory. His arrival will still award a major victory.
- - The celestial gateway can now take damage from explosions.
-
-
-
18 July 2016
-
CoreOverload updated:
-
- - Sterilizine now reduces probability of step failure if you apply it after starting surgery. Useful while operating in less-than-perfect conditions.
- - Potent alcohol can be used as replacement for sterilizine.
-
-
Joan updated:
-
- - The Vanguard scripture no longer prevents you from using slabs while active, but you cannot reactivate it if it is currently active.
- - It now only lasts 20 seconds, instead of 30.
- - When Vanguard deactivates, it now stuns for half the time of all stuns absorbed, instead of all of them.
- - Invoking Sevtug is less potent at long ranges, and slightly more potent if extremely close.
- - Invoking Sevtug now requires 3 invokers instead of 1.
- - The Clockwork Slab now has action buttons for rapidly invoking Guvax and Vanguard.
- - Belligerent is now chanted more often.
- - Taunting Tirade now weakens nearby nonservants, but is now only invoked once every 6 seconds(1 second chant, 5 second flee time) and is only chanted five times.
-
-
lordpidey updated:
-
- - Flyswatters are now included in beekeeping crates, they are great at killing insects and flies of all sizes.
-
GoonStation 13 Development Team
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index f4c61eb52ee..845b084581f 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -7110,3 +7110,73 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
your active hand and talk normally.
- rscadd: Added new things
- imageadd: added some icons and images
+2016-09-20:
+ Ergovisavi:
+ - bugfix: fixed "friendly" xenobio mobs and mining drones attacking station drones
+ Joan:
+ - rscadd: Miners can now buy KA AoE damage mods from the mining vendor for 2000
+ points per mod.
+ - rscadd: 'Combined the Convert and Sacrifice runes into one rune. It''ll convert
+ targets that are alive and eligible, and attempt to sacrifice them otherwise.
+ The only changes to mechanics are that: Converting someone will heal them of
+ all brute and burn damage they had, and sacrificing anything will always produce
+ a soulstone(but will still only sometimes fill it)'
+ - tweak: You can no longer teleport to Teleport runes that have dense objects on
+ top of them.
+ - experiment: Wall runes will now activate other nearby wall runes when activated,
+ but will automatically disable after a minute and a half of continuous activity
+ and become unusable for 5 seconds.
+ - experiment: The Blood Boil rune no longer does all of its damage instantly or
+ stuns, but if you remain in range for the full duration you will be sent deep
+ into critical.
+ - experiment: Bubblegum has been seen reaching through blood. Try not to get hit.
+ - experiment: The Raise Dead rune no longer requires a noncultist corpse to revive
+ a cultist; instead, it will draw from the pool of all people sacrificed to power
+ the rune.
+ Mekhi:
+ - rscadd: Nanotrasen has been experimenting on cybernetics for a while, and rumors
+ are they have a few combat prototypes available...
+ - experiment: 'New arm implants: Energy-blade projector, implanted medical beamgun,
+ stun-arm implant (Like the borg version), flash implant that is automatically-regenerating
+ and doubles as a powerful flashlight. There is also one with all four items
+ in one. Also, a surgery toolkit implant. Adminspawn only for the moment.'
+ MrStonedOne:
+ - bugfix: Fixed space/nograv movement not triggering when atoms moved twice quickly
+ in space/nograv
+ Nanotrasen Stress Relief Board:
+ - rscadd: Latecomers to highlander can now join in on the fun.
+ - rscadd: The crew are encouraged to less pacifistic during highlander. Failing
+ to shed blood will result in your soul being devoured. Have a nice day.
+ Nicho1010:
+ - bugfix: Fixed lattices appearing after exploding lava
+ Screemonster:
+ - tweak: Abandoned crates no longer accept impossible guesses.
+ - tweak: Lets players know that all the digits in the code must be unique.
+ - tweak: Reads the last guess back on the multitool along with the correct/incorrect
+ guess readout.
+ - bugfix: multitool output on crates no longer returns nonsense values.
+ XDTM:
+ - rscadd: Positive viruses are now recognized by medical HUDs with a special icon.
+ - tweak: fully_heal no longer removes nonharmful viruses. This affects legion souls,
+ staffs of healing, and changeling's revive.
+ - rscadd: Canisters of any type of gas are now orderable in cargo. Dangerous experimental
+ gases will require Research Director approval.
+ Yackemflam:
+ - rscadd: The syndicate has learned on how to give their agents a true syndicate
+ ninja experience.
+ chickenboy10:
+ - rscadd: Added a Experimental Limb Grower to the medbay department, now medical
+ stuff can grow synthetic limbs using Synthflesh to help crew that suffer any
+ work related accidents. There may also be a limb that can be grown with a special
+ card...
+ feemjmeem:
+ - tweak: You can now disassemble meatspike frames with a welding tool.
+ phil235:
+ - experiment: 'adds a talk button next to the crafting button. Clicking it makes
+ a "wheel" appear around you with short predetermined messages that you click
+ to say them. This lets you say common responses without having to type in the
+ chat bar. Current messages available are: "Hi", "Bye", "Thanks", "Come", "Help",
+ "Stop", "Get out", "Yes", and "No". The talk button can be activated with the
+ hotkey "H" or "CTRL+H"'
+ - rscadd: Wearing colored glasses colors your vision. This option can be enabled/disabled
+ by alt-clicking any glasses with such feature.
diff --git a/html/changelogs/AutoChangeLog-pr-20430.yml b/html/changelogs/AutoChangeLog-pr-20430.yml
deleted file mode 100644
index e265a4797a5..00000000000
--- a/html/changelogs/AutoChangeLog-pr-20430.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Joan"
-delete-after: True
-changes:
- - rscadd: "Miners can now buy KA AoE damage mods from the mining vendor for 2000 points per mod."
diff --git a/html/changelogs/AutoChangeLog-pr-20499.yml b/html/changelogs/AutoChangeLog-pr-20499.yml
deleted file mode 100644
index 5d271b48595..00000000000
--- a/html/changelogs/AutoChangeLog-pr-20499.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "phil235"
-delete-after: True
-changes:
- - rscadd: "Wearing colored glasses colors your vision. This option can be enabled/disabled by alt-clicking any glasses with such feature."
diff --git a/html/changelogs/AutoChangeLog-pr-20512.yml b/html/changelogs/AutoChangeLog-pr-20512.yml
deleted file mode 100644
index 1f693d70690..00000000000
--- a/html/changelogs/AutoChangeLog-pr-20512.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Joan"
-delete-after: True
-changes:
- - rscadd: "Combined the Convert and Sacrifice runes into one rune. It'll convert targets that are alive and eligible, and attempt to sacrifice them otherwise. The only changes to mechanics are that: Converting someone will heal them of all brute and burn damage they had, and sacrificing anything will always produce a soulstone(but will still only sometimes fill it)"
- - tweak: "You can no longer teleport to Teleport runes that have dense objects on top of them."
- - experiment: "Wall runes will now activate other nearby wall runes when activated, but will automatically disable after a minute and a half of continuous activity and become unusable for 5 seconds."
- - experiment: "The Blood Boil rune no longer does all of its damage instantly or stuns, but if you remain in range for the full duration you will be sent deep into critical."
diff --git a/icons/effects/bubblegum.dmi b/icons/effects/bubblegum.dmi
new file mode 100644
index 00000000000..a53dd7d563a
Binary files /dev/null and b/icons/effects/bubblegum.dmi differ
diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi
index 2338f667955..0d61c44cbbd 100644
Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ
diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi
index b0a1dbcb168..256bd412b4f 100644
Binary files a/icons/mob/screen_gen.dmi and b/icons/mob/screen_gen.dmi differ
diff --git a/icons/mob/screen_midnight.dmi b/icons/mob/screen_midnight.dmi
index 4de01c73cc8..c25813197fe 100644
Binary files a/icons/mob/screen_midnight.dmi and b/icons/mob/screen_midnight.dmi differ
diff --git a/icons/mob/screen_operative.dmi b/icons/mob/screen_operative.dmi
index e1728959e6a..e6a65052c14 100644
Binary files a/icons/mob/screen_operative.dmi and b/icons/mob/screen_operative.dmi differ
diff --git a/icons/mob/screen_plasmafire.dmi b/icons/mob/screen_plasmafire.dmi
index c40a531d8a6..3d1846b3009 100644
Binary files a/icons/mob/screen_plasmafire.dmi and b/icons/mob/screen_plasmafire.dmi differ
diff --git a/icons/mob/screen_retro.dmi b/icons/mob/screen_retro.dmi
index 9c99dba486b..db87b592169 100644
Binary files a/icons/mob/screen_retro.dmi and b/icons/mob/screen_retro.dmi differ
diff --git a/icons/mob/screen_slimecore.dmi b/icons/mob/screen_slimecore.dmi
index 91e2d73abe2..8575fa037de 100644
Binary files a/icons/mob/screen_slimecore.dmi and b/icons/mob/screen_slimecore.dmi differ
diff --git a/icons/obj/machines/limbgrower.dmi b/icons/obj/machines/limbgrower.dmi
new file mode 100644
index 00000000000..7e26a9f7f24
Binary files /dev/null and b/icons/obj/machines/limbgrower.dmi differ
diff --git a/interface/skin.dmf b/interface/skin.dmf
index 335caf26118..27dca90bcc8 100644
--- a/interface/skin.dmf
+++ b/interface/skin.dmf
@@ -77,6 +77,9 @@ macro "default"
elem
name = "CTRL+G"
command = "a-intent right"
+ elem
+ name = "CTRL+H"
+ command = "talk-wheel"
elem
name = "CTRL+Q"
command = ".northwest"
@@ -238,6 +241,12 @@ macro "hotkeys"
elem
name = "CTRL+G"
command = "a-intent right"
+ elem
+ name = "H"
+ command = "talk-wheel"
+ elem
+ name = "CTRL+H"
+ command = "talk-wheel"
elem
name = "M"
command = "me"
diff --git a/tgstation.dme b/tgstation.dme
index c8e8b1e1b03..1f6697edf24 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -368,14 +368,6 @@
#include "code\game\gamemodes\gang\gang_datum.dm"
#include "code\game\gamemodes\gang\gang_pen.dm"
#include "code\game\gamemodes\gang\recaller.dm"
-#include "code\game\gamemodes\handofgod\_handofgod.dm"
-#include "code\game\gamemodes\handofgod\actions.dm"
-#include "code\game\gamemodes\handofgod\god.dm"
-#include "code\game\gamemodes\handofgod\items.dm"
-#include "code\game\gamemodes\handofgod\objectives.dm"
-#include "code\game\gamemodes\handofgod\powers.dm"
-#include "code\game\gamemodes\handofgod\structures.dm"
-#include "code\game\gamemodes\handofgod\traps.dm"
#include "code\game\gamemodes\malfunction\Malf_Modules.dm"
#include "code\game\gamemodes\meteor\meteor.dm"
#include "code\game\gamemodes\meteor\meteors.dm"
@@ -435,6 +427,7 @@
#include "code\game\machinery\igniter.dm"
#include "code\game\machinery\iv_drip.dm"
#include "code\game\machinery\lightswitch.dm"
+#include "code\game\machinery\limbgrower.dm"
#include "code\game\machinery\machinery.dm"
#include "code\game\machinery\magnet.dm"
#include "code\game\machinery\mass_driver.dm"
@@ -607,6 +600,7 @@
#include "code\game\objects\items\documents.dm"
#include "code\game\objects\items\latexballoon.dm"
#include "code\game\objects\items\nuke_tools.dm"
+#include "code\game\objects\items\religion.dm"
#include "code\game\objects\items\shooting_range.dm"
#include "code\game\objects\items\toys.dm"
#include "code\game\objects\items\trash.dm"
@@ -752,6 +746,7 @@
#include "code\game\objects\structures\bedsheet_bin.dm"
#include "code\game\objects\structures\destructible_structures.dm"
#include "code\game\objects\structures\displaycase.dm"
+#include "code\game\objects\structures\divine.dm"
#include "code\game\objects\structures\door_assembly.dm"
#include "code\game\objects\structures\dresser.dm"
#include "code\game\objects\structures\electricchair.dm"
@@ -787,6 +782,7 @@
#include "code\game\objects\structures\tables_racks.dm"
#include "code\game\objects\structures\tank_dispenser.dm"
#include "code\game\objects\structures\target_stake.dm"
+#include "code\game\objects\structures\traps.dm"
#include "code\game\objects\structures\watercloset.dm"
#include "code\game\objects\structures\windoor_assembly.dm"
#include "code\game\objects\structures\window.dm"
@@ -1771,6 +1767,7 @@
#include "code\modules\research\designs\biogenerator_designs.dm"
#include "code\modules\research\designs\comp_board_designs.dm"
#include "code\modules\research\designs\computer_part_designs.dm"
+#include "code\modules\research\designs\limbgrower_designs.dm"
#include "code\modules\research\designs\machine_designs.dm"
#include "code\modules\research\designs\mecha_designs.dm"
#include "code\modules\research\designs\mechfabricator_designs.dm"