diff --git a/_maps/map_files/BirdStation/BirdStation.dmm b/_maps/map_files/BirdStation/BirdStation.dmm index 2ce75a3cb31..b08b7ff7e43 100644 --- a/_maps/map_files/BirdStation/BirdStation.dmm +++ b/_maps/map_files/BirdStation/BirdStation.dmm @@ -897,7 +897,7 @@ "arm" = (/obj/structure/cable/cyan{icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/open/floor/plasteel,/area/hallway/primary/port{name = "\improper Northwest Hallway"}) "arn" = (/obj/effect/spawner/structure/window/reinforced,/obj/machinery/door/poddoor/shutters/preopen{id = "hop shutter"; name = "HoP Office shutter"},/turf/open/floor/plating,/area/crew_quarters/heads) "aro" = (/obj/structure/table/wood,/obj/item/weapon/storage/box/silver_ids{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/box/ids,/turf/open/floor/wood,/area/crew_quarters/heads) -"arp" = (/obj/structure/table/wood,/obj/item/weapon/paper_bin{pixel_x = 0; pixel_y = 7},/turf/open/floor/wood,/area/crew_quarters/heads) +"arp" = (/obj/structure/filingcabinet/employment,/turf/open/floor/wood,/area/crew_quarters/heads) "arq" = (/obj/machinery/vending/cart,/turf/open/floor/wood,/area/crew_quarters/heads) "arr" = (/obj/machinery/photocopier,/obj/machinery/light{dir = 1},/turf/open/floor/wood,/area/crew_quarters/heads) "ars" = (/obj/structure/closet/secure_closet/hop,/obj/item/clothing/suit/armor/reactive,/turf/open/floor/wood,/area/crew_quarters/heads) @@ -1276,7 +1276,7 @@ "ayB" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/open/floor/plasteel/black,/area/engine/gravity_generator) "ayC" = (/obj/structure/cable/cyan{icon_state = "1-2"},/turf/open/floor/plasteel/black,/area/engine/gravity_generator) "ayD" = (/obj/effect/landmark{name = "lightsout"},/turf/open/floor/wood,/area/library) -"ayE" = (/obj/structure/table/wood,/obj/item/weapon/storage/pill_bottle/dice,/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/open/floor/wood,/area/library) +"ayE" = (/obj/structure/table/wood,/obj/item/weapon/book/codex_gigas,/obj/item/weapon/storage/pill_bottle/dice,/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/open/floor/wood,/area/library) "ayF" = (/obj/effect/landmark/start{name = "Clown"},/turf/open/floor/wood,/area/crew_quarters/theatre) "ayG" = (/turf/open/floor/wood,/area/crew_quarters/theatre) "ayH" = (/obj/machinery/camera/autoname{dir = 8},/turf/open/floor/wood,/area/crew_quarters/theatre) @@ -2951,6 +2951,7 @@ "beO" = (/obj/structure/window/reinforced,/obj/machinery/flasher/portable,/obj/machinery/flasher/portable,/obj/machinery/flasher/portable,/obj/machinery/flasher/portable,/obj/machinery/flasher/portable,/obj/machinery/flasher/portable,/turf/open/floor/plasteel/black,/area/security/warden) "beP" = (/obj/structure/table,/obj/item/clothing/glasses/science,/turf/open/floor/plasteel,/area/toxins/misc_lab) "beQ" = (/obj/effect/decal/cleanable/blood/old,/obj/item/clothing/glasses/sunglasses,/turf/open/floor/wood{icon_state = "wood-broken"},/area/maintenance/fore{name = "Security Maintenance"}) +"ZAx" = (/obj/structure/table, /obj/item/clothing/under/burial, /obj/item/clothing/under/burial, /obj/item/clothing/under/burial, /obj/item/clothing/under/burial, /obj/item/clothing/under/burial, /obj/item/clothing/under/burial, /turf/open/floor/plating,/area/maintenance/asmaint2) (1,1,1) = {" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa @@ -3126,7 +3127,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJaaJaaJaaJaaJaaJaaaaaJaaJaaJaaaaaaaaaaaaaaJaaJaaJaaJaPHaPHaPHaPHaPHaPHaRkaRkaPHaaaaaaaVmbbHaVmaaaaayaaaaaaaaaaaaaaBaaaaaaaayaaaaaaaZrbcqbcraZraZraZraZraZrbagazLaAxaAZaNEaAxbcsaAxaAxaAxaAxazLaFsaBRaRZaRZaBRazLazLazLazLazLazLazLazLazLazLazLazLazLazLazLazLazLazLaZxazLazLaaJaaJaaJaayaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayaaaaaaaayaaaaaaaaaaPHbctbctaPHaaaaaaaaaaaTaaaaaaaayaaaaaaaaaaaaaaBaaaaaaaayaaaaaaaZrbaSbcubcvbchbchbcwbcxbaSbcyaAxbbyaHGaAxbczaAxbcAaAxaBbaFCaBbaBbbcBbcBaAxbczbcjbcjbcjazLaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJbcCaaJaaJaaJaaJaaJaaJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaayaayaayaayaayaayaayaayaPHaQqaQqaPHaayaayaaybcDamzaaBaaBaaBaaBaaBaaBaaBaayaguaguaguaayaZrbaSbcEbcFbcFbcGbcGbcGbcGbcHaDiaDibcIaDibcIaDiaDiaDiaDjbcJaDjaDjaDjaDjaDibcIbcKbcKbcLaTTbcMbcMbcMbcMbcMbcMbcMbcMbcMbcMbcMbcMbcMbcNaaJaaJaaJaaJaaJaaJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcObcPbcPbcQbcPbcPbcPbcRbcPbcPbcSaayaaaaPHbcTaQqaVmaaaaayaaaaaaaaaaaaaayaaaaaaaaaaaaaaBaaaaaaaaaaaaaaaaZraZraZrbcUbcUaZrbcVbcWbcXazLaAxaBTaAxaAxaAxbcjbcjbcYbcZazLazLazLazLazLazLazLazLazLazLazLaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcObcPbcPbcQbcPbcPbcPbcRbcPbcPbcSaayaaaaPHbcTaQqaVmaaaaayaaaaaaaaaaaaaayaaaaaaaaaaaaaaBaaaaaaaaaaaaaaaaZraZraZrbcUbcUaZrbcVbcWbcXazLaAxaBTaAxaAxZAxbcjbcjbcYbcZazLazLazLazLazLazLazLazLazLazLazLaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcObdabdbbdcbddbddbddbddbddbddbddbcQaVmaVmaVmaQqaQqaVmaaaaayaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBaaaaaaaaaaaaaaaaaJaaJaZrbdebdeaZraZraZraZrazLazLazLaBRaBRaBRazLazLazLazLazLaaaaayaaaaaaaaaaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdfbdgbdgbdgbdgbdgbdgbdgbdgbdgbdgbdhbdibdjbdkaQqaQqaVmaaaaayaaaaaaaaaaaaaaaaaaaaaaaaaayaaBaayaaaaaaaaaaaaaaaaaJaZrbdebdebdlbdlbdmaZraaJaaJbdnaaaaaaaaaaayaaaaaaaaaaayaaaaayaayaayaayaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdobdpbdqbdqbdrbdrbdrbdrbdrbdrbdrbcQaVmaVmaVmaQqaQqaPHaaaaayaaaaaaaaaaaaaaaaaaaaaaaaaayaaBaayaaaaaaaaaaaaaaaaaJaZrbdsbdebdebdebdtaZraaJaaJaayaayaayaayaayaayaayaayaayaayaayaaaaaaaaaaaaaaJaaJaaJaaJaaJaaJaaaaaaaaaaaJaaJaaJaaaaaaaaaaaaaaaaaJaaJaaJaaJaaJaaJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/_maps/map_files/DreamStation/dreamstation04.dmm b/_maps/map_files/DreamStation/dreamstation04.dmm index d9b8f0cce5b..9f1dde54049 100644 --- a/_maps/map_files/DreamStation/dreamstation04.dmm +++ b/_maps/map_files/DreamStation/dreamstation04.dmm @@ -23727,7 +23727,7 @@ pixel_x = -30; pixel_y = 0 }, -/obj/structure/filingcabinet, +/obj/structure/filingcabinet/employment, /turf/open/floor/wood, /area/lawoffice) "aVu" = ( @@ -45512,6 +45512,7 @@ "bIQ" = ( /obj/structure/cult/tome, /obj/item/clothing/under/suit_jacket/red, +/obj/item/weapon/book/codex_gigas, /turf/open/floor/plasteel/cult, /area/library) "bIR" = ( @@ -62399,6 +62400,13 @@ dir = 2; pixel_y = 24 }, +/obj/structure/table/wood, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, /turf/open/floor/plasteel{ icon_state = "dark" }, diff --git a/_maps/map_files/EfficiencyStation/EfficiencyStation.dmm b/_maps/map_files/EfficiencyStation/EfficiencyStation.dmm index b15f8f1c392..8e7fc5e4d84 100644 --- a/_maps/map_files/EfficiencyStation/EfficiencyStation.dmm +++ b/_maps/map_files/EfficiencyStation/EfficiencyStation.dmm @@ -39741,6 +39741,7 @@ /area/storage/art) "buT" = ( /obj/structure/cult/tome, +/obj/item/weapon/book/codex_gigas, /turf/open/floor/plasteel{ icon_state = "cult" }, @@ -48367,8 +48368,7 @@ name = "Chapel Maintenance" }) "bKq" = ( -/obj/structure/filingcabinet/chestdrawer, -/obj/effect/decal/cleanable/cobweb, +/obj/structure/filingcabinet/employment, /turf/open/floor/wood, /area/lawoffice) "bKr" = ( @@ -57033,9 +57033,13 @@ }) "cay" = ( /obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/robot_debris{ - icon_state = "gib6" - }, +/obj/structure/table, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, /turf/open/floor/plating, /area/maintenance/port{ name = "Chapel Maintenance" diff --git a/_maps/map_files/MetaStation/MetaStation.v41I.dmm b/_maps/map_files/MetaStation/MetaStation.v41I.dmm index 43d40cb3424..afe423895f5 100644 --- a/_maps/map_files/MetaStation/MetaStation.v41I.dmm +++ b/_maps/map_files/MetaStation/MetaStation.v41I.dmm @@ -24449,12 +24449,12 @@ /turf/open/floor/wood, /area/lawoffice) "aNP" = ( -/obj/structure/filingcabinet/chestdrawer, /obj/machinery/airalarm{ dir = 8; icon_state = "alarm0"; pixel_x = 24 }, +/obj/structure/filingcabinet/employment, /turf/open/floor/wood, /area/lawoffice) "aNQ" = ( @@ -59349,6 +59349,7 @@ pixel_y = 0 }, /obj/item/clothing/under/suit_jacket/red, +/obj/item/weapon/book/codex_gigas, /turf/open/floor/plasteel{ icon_state = "cult"; dir = 2 @@ -100508,12 +100509,18 @@ }, /area/medical/morgue) "dfx" = ( -/obj/machinery/plantgenes, -/turf/open/floor/plasteel{ - dir = 9; - icon_state = "warning" +/obj/structure/window/reinforced{ + dir = 4 }, -/area/hydroponics) +/obj/structure/table/wood, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/turf/open/floor/plating, +/area/chapel/main) "dfy" = ( /turf/open/floor/engine/vacuum, /area/atmos) @@ -100615,6 +100622,13 @@ }, /turf/open/space, /area/space) +"dfI" = ( +/obj/machinery/plantgenes, +/turf/open/floor/plasteel{ + dir = 9; + icon_state = "warning" + }, +/area/hydroponics) (1,1,1) = {" aaa @@ -120851,7 +120865,7 @@ cOU cRS cRS cSP -cRS +dfx cOU cUb cOU @@ -136228,7 +136242,7 @@ bZc caw bZc ccX -dfx +dfI bVf cuS ciC diff --git a/_maps/map_files/MiniStation/MiniStation.dmm b/_maps/map_files/MiniStation/MiniStation.dmm index 4220fed6d56..94f22215cc9 100644 --- a/_maps/map_files/MiniStation/MiniStation.dmm +++ b/_maps/map_files/MiniStation/MiniStation.dmm @@ -3510,6 +3510,7 @@ /obj/item/weapon/folder/red, /obj/item/weapon/hand_labeler, /obj/item/clothing/glasses/sunglasses, +/obj/item/weapon/book/codex_gigas, /turf/open/floor/carpet, /area/security/brig) "hn" = ( @@ -10216,7 +10217,7 @@ /area/crew_quarters/bar) "uW" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/filingcabinet/chestdrawer, +/obj/structure/filingcabinet/employment, /turf/open/floor/plasteel, /area/crew_quarters/heads{ name = "\improper Job Assignment" @@ -16130,6 +16131,16 @@ }, /turf/open/floor/plasteel, /area/security/brig) +"IL" = ( +/obj/structure/table, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/obj/item/clothing/under/burial, +/turf/open/floor/plating, +/area/hallway/primary/central) (1,1,1) = {" aa @@ -46085,7 +46096,7 @@ nC jo bx bN -bN +IL bx ps rE diff --git a/_maps/map_files/TgStation/tgstation.2.1.3.dmm b/_maps/map_files/TgStation/tgstation.2.1.3.dmm index ee5c7cfc719..355c2d64f14 100644 --- a/_maps/map_files/TgStation/tgstation.2.1.3.dmm +++ b/_maps/map_files/TgStation/tgstation.2.1.3.dmm @@ -9082,10 +9082,10 @@ /turf/open/floor/carpet, /area/security/detectives_office) "arV" = ( -/obj/structure/filingcabinet/chestdrawer, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/structure/filingcabinet/employment, /turf/open/floor/wood, /area/lawoffice) "arW" = ( @@ -20527,6 +20527,7 @@ "aQs" = ( /obj/structure/cult/tome, /obj/item/clothing/under/suit_jacket/red, +/obj/item/weapon/book/codex_gigas, /turf/open/floor/plasteel{ icon_state = "cult"; dir = 2 diff --git a/code/__DEFINES/contracts.dm b/code/__DEFINES/contracts.dm new file mode 100644 index 00000000000..cba98a29b24 --- /dev/null +++ b/code/__DEFINES/contracts.dm @@ -0,0 +1,42 @@ +#define CONTRACT_POWER "power" +#define CONTRACT_WEALTH "wealth" +#define CONTRACT_PRESTIGE "prestige" +#define CONTRACT_MAGIC "magic" +#define CONTRACT_REVIVE "revive" +#define CONTRACT_KNOWLEDGE "knowledge" +#define CONTRACT_UNWILLING "unwilling" + +#define BANE_SALT "salt" +#define BANE_LIGHT "light" +#define BANE_IRON "iron" +#define BANE_WHITECLOTHES "whiteclothes" +#define BANE_SILVER "silver" +#define BANE_HARVEST "harvest" +#define BANE_TOOLBOX "toolbox" + +#define OBLIGATION_FOOD "food" +#define OBLIGATION_DRINK "drink" +#define OBLIGATION_GREET "greet" +#define OBLIGATION_PRESENCEKNOWN "presenceknown" +#define OBLIGATION_SAYNAME "sayname" +#define OBLIGATION_ANNOUNCEKILL "announcekill" +#define OBLIGATION_ANSWERTONAME "answername" + +#define BAN_HURTWOMAN "hurtwoman" +#define BAN_CHAPEL "chapel" +#define BAN_HURTPRIEST "hurtpriest" +#define BAN_AVOIDWATER "avoidwater" +#define BAN_STRIKEUNCONCIOUS "strikeunconcious" +#define BAN_HURTLIZARD "hurtlizard" +#define BAN_HURTANIMAL "hurtanimal" + +#define BANISH_WATER "water" +#define BANISH_COFFIN "coffin" +#define BANISH_FORMALDYHIDE "embalm" +#define BANISH_RUNES "runes" +#define BANISH_CANDLES "candles" +#define BANISH_DESTRUCTION "destruction" +#define BANISH_FUNERAL_GARB "funeral" + +#define LORE 1 +#define LAW 2 \ No newline at end of file diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index 9ca921c0cda..27252048b47 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -25,14 +25,17 @@ #define DATA_HUD_MEDICAL_ADVANCED 4 #define DATA_HUD_DIAGNOSTIC 5 //antag HUD defines -#define ANTAG_HUD_CULT 6 -#define ANTAG_HUD_REV 7 -#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_CULT 6 +#define ANTAG_HUD_REV 7 +#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 diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 916ff182f3c..980436018c6 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -24,6 +24,7 @@ #define ROLE_REVENANT "revenant" #define ROLE_HOG_GOD "hand of god: god" #define ROLE_HOG_CULTIST "hand of god: cultist" +#define ROLE_DEVIL "devil" //Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR. @@ -48,4 +49,5 @@ var/global/list/special_roles = list( 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 ) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index ce70339a466..5058f8ace1f 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -355,6 +355,8 @@ Turf and target are seperate in case you want to teleport some distance from a t // mob_list.Add(M) // for(var/mob/living/silicon/hive_mainframe/M in world) // mob_list.Add(M) + for(var/mob/living/carbon/true_devil/M in sortmob) + moblist.Add(M) return moblist //E = MC^2 diff --git a/code/_onclick/hud/demon.dm b/code/_onclick/hud/demon.dm new file mode 100644 index 00000000000..fc0d923e080 --- /dev/null +++ b/code/_onclick/hud/demon.dm @@ -0,0 +1,75 @@ +/datum/hud/devil/New(mob/owner, ui_style = 'icons/mob/screen_midnight.dmi') + ..() + var/obj/screen/using + var/obj/screen/inventory/inv_box + + using = new /obj/screen/drop() + using.icon = ui_style + using.screen_loc = ui_drone_drop + static_inventory += using + + pull_icon = new /obj/screen/pull() + pull_icon.icon = ui_style + pull_icon.update_icon(mymob) + pull_icon.screen_loc = ui_drone_pull + static_inventory += pull_icon + + inv_box = new /obj/screen/inventory/hand() + inv_box.name = "right hand" + inv_box.icon = ui_style + inv_box.icon_state = "hand_r" + inv_box.screen_loc = ui_rhand + inv_box.slot_id = slot_r_hand + static_inventory += inv_box + + inv_box = new /obj/screen/inventory/hand() + inv_box.name = "left hand" + inv_box.icon = ui_style + inv_box.icon_state = "hand_l" + inv_box.screen_loc = ui_lhand + inv_box.slot_id = slot_l_hand + static_inventory += inv_box + + using = new /obj/screen/inventory() + using.name = "hand" + using.icon = ui_style + using.icon_state = "swap_1_m" + using.screen_loc = ui_swaphand1 + using.layer = 19 + static_inventory += using + + using = new /obj/screen/inventory() + using.name = "hand" + using.icon = ui_style + using.icon_state = "swap_2" + using.screen_loc = ui_swaphand2 + using.layer = 19 + static_inventory += using + + zone_select = new /obj/screen/zone_sel() + zone_select.icon = ui_style + zone_select.update_icon(mymob) + + lingchemdisplay = new /obj/screen/ling/chems() + +/datum/hud/devil/persistant_inventory_update() + if(!mymob) + return + var/mob/living/carbon/true_devil/D = mymob + + if(hud_version != HUD_STYLE_NOHUD) + if(D.r_hand) + D.r_hand.screen_loc = ui_rhand + D.client.screen += D.r_hand + if(D.l_hand) + D.l_hand.screen_loc = ui_lhand + D.client.screen += D.l_hand + else + if(D.r_hand) + D.r_hand.screen_loc = null + if(D.l_hand) + D.l_hand.screen_loc = null + +/mob/living/carbon/true_devil/create_mob_hud() + if(client && !hud_used) + hud_used = new /datum/hud/devil(src, ui_style2icon(client.prefs.UI_style)) diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 89d3e04808f..742c700ebb9 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -262,6 +262,7 @@ var/record_id_num = 1001 L.fields["species"] = H.dna.species.type L.fields["features"] = H.dna.features L.fields["image"] = image + L.fields["reference"] = H locked += L return diff --git a/code/datums/hud.dm b/code/datums/hud.dm index 8698e29a382..2b7eee8a730 100644 --- a/code/datums/hud.dm +++ b/code/datums/hud.dm @@ -18,6 +18,9 @@ var/datum/atom_hud/huds = list( \ ANTAG_HUD_NINJA = new/datum/atom_hud/antag/hidden(),\ ANTAG_HUD_CHANGELING = new/datum/atom_hud/antag/hidden(),\ ANTAG_HUD_ABDUCTOR = new/datum/atom_hud/antag/hidden(),\ + ANTAG_HUD_DEVIL = new/datum/atom_hud/antag(),\ + ANTAG_HUD_SINTOUCHED = new/datum/atom_hud/antag/hidden(),\ + ANTAG_HUD_SOULLESS = new/datum/atom_hud/antag/hidden(),\ ) /datum/atom_hud diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 1587bc4b8d2..60d4d992d88 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -57,9 +57,13 @@ var/antag_hud_icon_state = null //this mind's ANTAG_HUD should have this icon_state var/datum/atom_hud/antag/antag_hud = null //this mind's antag HUD var/datum/gang/gang_datum //Which gang this mind belongs to, if any + var/datum/devilinfo/devilinfo //Information about the devil, if any. + var/damnation_type = 0 + var/datum/mind/soulOwner //who owns the soul. Under normal circumstances, this will point to src /datum/mind/New(var/key) src.key = key + soulOwner = src /datum/mind/proc/transfer_to(mob/new_character, var/force_key_move = 0) @@ -539,6 +543,24 @@ sections["monkey"] = text + /** devil ***/ + text = "devil" + if(ticker.mode.config_tag == "devil") + text = uppertext(text) + text = "[text]: " + if(src in ticker.mode.devils) + text += "DEVIL|sintouched|human" + else if(src in ticker.mode.sintouched) + text += "devil|SINTOUCHED|human" + else + text += "devil|sintouched|HUMAN" + + if(current && current.client && (ROLE_DEVIL in current.client.prefs.be_special)) + text += "|Enabled in Prefs" + else + text += "|Disabled in Prefs" + sections["devil"] = text + /** SILICON ***/ @@ -1163,6 +1185,45 @@ message_admins("[key_name_admin(usr)] has thrall'ed [current].") log_admin("[key_name(usr)] has thrall'ed [current].") + else if(href_list["devil"]) + switch(href_list["devil"]) + if("clear") + if(src in ticker.mode.devils) + if(istype(current,/mob/living/carbon/true_devil/)) + usr << "This cannot be used on true or arch-devils." + else + ticker.mode.devils -= src + special_role = null + current << "Your infernal link has been severed! You are no longer a devil!" + RemoveSpell(/obj/effect/proc_holder/spell/targeted/infernal_jaunt) + RemoveSpell(/obj/effect/proc_holder/spell/dumbfire/fireball/hellish) + RemoveSpell(/obj/effect/proc_holder/spell/targeted/summon_contract) + RemoveSpell(/obj/effect/proc_holder/spell/targeted/summon_pitchfork) + message_admins("[key_name_admin(usr)] has de-devil'ed [current].") + devilinfo = null + log_admin("[key_name(usr)] has de-devil'ed [current].") + else if(src in ticker.mode.sintouched) + ticker.mode.sintouched -= src + message_admins("[key_name_admin(usr)] has de-sintouch'ed [current].") + log_admin("[key_name(usr)] has de-sintouch'ed [current].") + if("devil") + if(!ishuman(current)) + usr << "This only works on humans!" + return + ticker.mode.devils += src + special_role = "devil" + ticker.mode.finalize_devil(src) + announceDevilLaws() + if("sintouched") + if(ishuman(current)) + ticker.mode.sintouched += src + var/mob/living/carbon/human/H = current + H.influenceSin() + message_admins("[key_name_admin(usr)] has sintouch'ed [current].") + else + usr << "This only works on humans!" + return + else if(href_list["abductor"]) switch(href_list["abductor"]) if("clear") @@ -1569,7 +1630,6 @@ 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") @@ -1611,6 +1671,25 @@ var/obj/effect/proc_holder/spell/S = X S.action.Grant(new_character) +/datum/mind/proc/disrupt_spells(delay, list/exceptions = New()) + for(var/X in spell_list) + var/obj/effect/proc_holder/spell/S = X + for(var/type in exceptions) + if(istype(S, type)) + continue + S.charge_counter = delay + spawn(0) + S.start_recharge() + +/datum/mind/proc/get_ghost(even_if_they_cant_reenter) + for(var/mob/dead/observer/G in dead_mob_list) + if(G.mind == src) + if(G.can_reenter_corpse || even_if_they_cant_reenter) + return G + break + + + /mob/proc/sync_mind() mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist) mind.active = 1 //indicates that the mind is currently synced with a client @@ -1721,4 +1800,4 @@ /mob/living/simple_animal/hostile/construct/mind_initialize() ..() mind.assigned_role = "[initial(name)]" - mind.special_role = "Cultist" \ No newline at end of file + mind.special_role = "Cultist" diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 920d71870a2..bb4f8d28ffa 100644 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -1328,6 +1328,25 @@ var/list/teleportlocs = list() icon_state = "tcomsatlounge" +// Hell +/area/hell + name = "Hell Lobby" + //icon = "ICON FILENAME" + //icon_state = "NAME OF ICON" + requires_power = 0 + music = "music/music.ogg" + +/area/hell/trial1 + name = "Hell Trial1" + //icon_state = "NAME OF ICON" (defaults to "unknown" (blank)) + +/area/hell/trial1 + name = "Hell Trial2" + //icon_state = "NAME OF ICON" (defaults to "unknown" (blank)) + +/area/hell/trial1 + name = "Hell Trial3" + //icon_state = "NAME OF ICON" (defaults to "unknown" (blank)) // Away Missions /area/awaymission diff --git a/code/game/gamemodes/demon/demon.dm b/code/game/gamemodes/demon/demon.dm new file mode 100644 index 00000000000..743e95ad910 --- /dev/null +++ b/code/game/gamemodes/demon/demon.dm @@ -0,0 +1,40 @@ +var/global/list/whiteness = list ( + /obj/item/clothing/under/color/white = 2, + /obj/item/clothing/under/rank/bartender = 1, + /obj/item/clothing/under/rank/chef = 1, + /obj/item/clothing/under/rank/chief_engineer = 1, + /obj/item/clothing/under/rank/scientist = 1, + /obj/item/clothing/under/rank/chemist = 1, + /obj/item/clothing/under/rank/chief_medical_officer = 1, + /obj/item/clothing/under/rank/geneticist = 1, + /obj/item/clothing/under/rank/virologist = 1, + /obj/item/clothing/under/rank/nursesuit = 1, + /obj/item/clothing/under/rank/medical = 1, + /obj/item/clothing/under/rank/det = 1, + /obj/item/clothing/under/suit_jacket/white = 0.5, + /obj/item/clothing/under/burial = 1 +) + + + +/mob/living/proc/check_devil_bane_multiplier(obj/item/weapon, mob/living/attacker) + switch(mind.devilinfo.bane) + if(BANE_WHITECLOTHES) + if(istype(attacker, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = attacker + if(H.w_uniform && istype(H.w_uniform, /obj/item/clothing/under)) + var/obj/item/clothing/under/U = H.w_uniform + if(whiteness[U.type]) + src.visible_message("[src] seems to have been harmed by the purity of [attacker]'s clothes.", "Unsullied white clothing is disrupting your form.") + return whiteness[U.type] + 1 + if(BANE_TOOLBOX) + if(istype(weapon,/obj/item/weapon/storage/toolbox)) + src.visible_message("The [weapon] seems unusually robust this time.", "The [weapon] is your unmaking!") + return 2.5 // Will take four hits with a normal toolbox. + if(BANE_HARVEST) + if(istype(weapon,/obj/item/weapon/reagent_containers/food/snacks/grown/)) + src.visible_message("The spirits of the harvest aid in the exorcism.", "The harvest spirits are harming you.") + src.Weaken(2) + qdel(weapon) + return 2 + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/demon/demon_game_mode.dm b/code/game/gamemodes/demon/demon_game_mode.dm new file mode 100644 index 00000000000..06856715515 --- /dev/null +++ b/code/game/gamemodes/demon/demon_game_mode.dm @@ -0,0 +1,108 @@ +/datum/game_mode + var/list/datum/mind/sintouched = list() + var/list/datum/mind/devils = list() + var/devil_ascended = 0 // Number of arch devils on station + +/datum/game_mode/proc/auto_declare_completion_sintouched() + var/text = "" + if(sintouched.len) + text += "
The sintouched were:" + var/list/sintouchedUnique = uniqueList(sintouched) + for(var/S in sintouchedUnique) + var/datum/mind/sintouched_mind = S + text += printplayer(sintouched_mind) + text += printobjectives(sintouched_mind) + text += "
" + text += "
" + world << text + +/datum/game_mode/proc/auto_declare_completion_devils() + /var/text = "" + if(devils.len) + text += "
The devils were:" + for(var/D in devils) + var/datum/mind/devil = D + text += printplayer(devil) + text += printdevilinfo(devil) + text += printobjectives(devil) + text += "
" + world << text + +/datum/game_mode/devil + + +/datum/game_mode/proc/finalize_devil(datum/mind/devil_mind) + var/mob/living/carbon/human/S = devil_mind.current + var/trueName= randomDevilName() + var/datum/objective/devil/soulquantity/soulquant = new + soulquant.owner = devil_mind + var/datum/objective/devil/soulquality/soulqual = new + soulqual.owner = devil_mind + devil_mind.objectives += soulqual + devil_mind.objectives += soulquant + devil_mind.devilinfo = devilInfo(trueName, 1) + devil_mind.store_memory("Your devilic true name is [devil_mind.devilinfo.truename]
[lawlorify[LAW][devil_mind.devilinfo.ban]]
[lawlorify[LAW][devil_mind.devilinfo.bane]]
[lawlorify[LAW][devil_mind.devilinfo.obligation]]
[lawlorify[LAW][devil_mind.devilinfo.banish]]
") + devil_mind.devilinfo.owner = devil_mind + devil_mind.devilinfo.give_base_spells(1) + spawn(10) + if(devil_mind.assigned_role == "Clown") + S << "Your infernal nature has allowed you to overcome your clownishness." + S.dna.remove_mutation(CLOWNMUT) + +/datum/mind/proc/announceDevilLaws() + if(!devilinfo) + return + current << "You remember your link to the infernal. You are [src.devilinfo.truename], an agent of hell, a devil. And you were sent to the plane of creation for a reason. A greater purpose. Convince the crew to sin, and embroiden Hell's grasp." + current << "However, your infernal form is not without weaknesses." + current << lawlorify[LAW][src.devilinfo.bane] + current << lawlorify[LAW][src.devilinfo.ban] + current << lawlorify[LAW][src.devilinfo.obligation] + current << lawlorify[LAW][src.devilinfo.banish] + current << "

Remember, the crew can research your weaknesses if they find out your devil name.
" + var/obj_count = 1 + current << "Your current objectives:" + for(var/O in objectives) + var/datum/objective/objective = O + current << "Objective #[obj_count]: [objective.explanation_text]" + obj_count++ + +/datum/game_mode/proc/printdevilinfo(datum/mind/ply) + if(!ply.devilinfo) + return "" + var/text = "
The devil's true name is: [ply.devilinfo.truename]
" + text += "The devil's bans were:
" + text += " [lawlorify[LORE][ply.devilinfo.ban]]
" + text += " [lawlorify[LORE][ply.devilinfo.bane]]
" + text += " [lawlorify[LORE][ply.devilinfo.obligation]]
" + text += " [lawlorify[LORE][ply.devilinfo.banish]]
" + return text + +/datum/game_mode/proc/update_devil_icons_added(datum/mind/devil_mind) + var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_DEVIL] + hud.join_hud(devil_mind.current) + set_antag_hud(devil_mind.current, "devil") + +/datum/game_mode/proc/update_devil_icons_removed(datum/mind/devil_mind) + var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_DEVIL] + hud.leave_hud(devil_mind.current) + set_antag_hud(devil_mind.current, null) + +/datum/game_mode/proc/update_sintouch_icons_added(datum/mind/sin_mind) + var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_SINTOUCHED] + hud.join_hud(sin_mind.current) + set_antag_hud(sin_mind.current, "sintouched") + +/datum/game_mode/proc/update_sintouch_icons_removed(datum/mind/sin_mind) + var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_SINTOUCHED] + hud.leave_hud(sin_mind.current) + set_antag_hud(sin_mind.current, null) + +/datum/game_mode/proc/update_soulless_icons_added(datum/mind/soulless_mind) + var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_SOULLESS] + hud.join_hud(soulless_mind.current) + set_antag_hud(soulless_mind.current, "soulless") + +/datum/game_mode/proc/update_soulless_icons_removed(datum/mind/soulless_mind) + var/datum/atom_hud/antag/hud = huds[ANTAG_HUD_SOULLESS] + hud.leave_hud(soulless_mind.current) + set_antag_hud(soulless_mind.current, null) diff --git a/code/game/gamemodes/demon/demoninfo.dm b/code/game/gamemodes/demon/demoninfo.dm new file mode 100644 index 00000000000..5c013496cac --- /dev/null +++ b/code/game/gamemodes/demon/demoninfo.dm @@ -0,0 +1,413 @@ +#define POWERUPTHRESHOLD 3 //How many souls are needed per stage. + +#define BASIC_DEVIL 0 +#define BLOOD_LIZARD 1 +#define TRUE_DEVIL 2 +#define ARCH_DEVIL 3 + +#define SOULVALUE soulsOwned.len-reviveNumber + +#define DEVILRESURRECTTIME 600 + +var/global/list/allDevils = list() +var/global/list/lawlorify = list ( + LORE = list( + OBLIGATION_FOOD = "This devil seems to always offer it's victims food before slaughtering them.", + OBLIGATION_DRINK = "This devil seems to always offer it's victims a drink before slaughtering them.", + OBLIGATION_GREET = "This devil seems to only be able to converse with people it knows the name of.", + OBLIGATION_PRESENCEKNOWN = "This devil seems to be unable to attack from stealth.", + OBLIGATION_SAYNAME = "He will always chant his name upon killing someone.", + OBLIGATION_ANNOUNCEKILL = "This devil always loudly announces his kills for the world to hear.", + OBLIGATION_ANSWERTONAME = "This devil always responds to his truename.", + BANE_SILVER = "Silver seems to gravely injure this devil.", + BANE_SALT = "Throwing salt at this devil will hinder his ability to use infernal powers temporarily.", + BANE_LIGHT = "Bright flashes will disorient the devil, likely causing him to flee.", + BANE_IRON = "Cold iron will slowly injure him, until he can purge it from his system.", + BANE_WHITECLOTHES = "Wearing clean white clothing will help ward off this devil.", + BANE_HARVEST = "Presenting the labors of a harvest will disrupt the devil.", + BANE_TOOLBOX = "That which holds the means of creation also holds the means of the devil's undoing.", + BAN_HURTWOMAN = "This devil seems to prefer hunting men.", + BAN_CHAPEL = "This devil avoids holy ground.", + BAN_HURTPRIEST = "The annointed clergy appear to be immune to his powers.", + BAN_AVOIDWATER = "The devil seems to have some sort of aversion to water, though it does not appear to harm him.", + BAN_STRIKEUNCONCIOUS = "This devil only shows interest in those who are awake.", + BAN_HURTLIZARD = "This devil will not strike a lizardman first.", + BAN_HURTANIMAL = "This devil avoids hurting animals.", + BANISH_WATER = "To banish the devil, you must sprinkle holy water upon it's body.", + BANISH_COFFIN = "This devil will return to life if it's remains are not placed within a coffin.", + BANISH_FORMALDYHIDE = "To banish the devil, you must inject it's lifeless body with embalming fluid.", + BANISH_RUNES = "This devil will resurrect after death, unless it's remains are within a rune.", + BANISH_CANDLES = "A large number of candles will prevent it from resurrecting.", + BANISH_DESTRUCTION = "It's corpse must be utterly destroyed to prevent resurrection.", + BANISH_FUNERAL_GARB = "Funeral garments will prevent the devil from resurrecting." + ), + LAW = list( + OBLIGATION_FOOD = "When not acting in self defense, you must always offer your victim food before harming them.", + OBLIGATION_DRINK = "When not acting in self defense, you must always offer your victim drink before harming them.", + OBLIGATION_GREET = "You must always greet other people by their last name before talking with them.", + OBLIGATION_PRESENCEKNOWN = "You must always make your presence known before attacking.", + OBLIGATION_SAYNAME = "You must always say your true name after you kill someone.", + OBLIGATION_ANNOUNCEKILL = "Upon killing someone, you must make your deed known to all within earshot, over comms if reasonably possible.", + OBLIGATION_ANSWERTONAME = "If you are not under attack, you must always respond to your true name.", + BAN_HURTWOMAN = "You must never harm a female outside of self defense.", + BAN_CHAPEL = "You must never attempt to enter the chapel.", + BAN_HURTPRIEST = "You must never attack a priest.", + BAN_AVOIDWATER = "You must never willingly touch a wet surface.", + BAN_STRIKEUNCONCIOUS = "You must never strike an unconcious person.", + BAN_HURTLIZARD = "You must never harm a lizardman outside of self defense.", + BAN_HURTANIMAL = "You must never harm a non-sentient creature or robot outside of self defense.", + BANE_SILVER = "Silver, in all of it's forms shall be your downfall.", + BANE_SALT = "Salt will disrupt your magical abilities.", + BANE_LIGHT = "Blinding lights will prevent you from using offensive powers for a time.", + BANE_IRON = "Cold wrought iron shall act as poison to you.", + BANE_WHITECLOTHES = "Those clad in pristine white garments will strike you true.", + BANE_HARVEST = "The fruits of the harvest shall be your downfall.", + BANE_TOOLBOX = "Toolboxes are bad news for you, for some reason.", + BANISH_WATER = "If your corpse is filled with holy water, you will be unable to resurrect.", + BANISH_COFFIN = "If your corpse is in a coffin, you will be unable to resurrect.", + BANISH_FORMALDYHIDE = "If your corpse is embalmed, you will be unable to resurrect.", + BANISH_RUNES = "If your corpse is placed within a rune, you will be unable to resurrect.", + BANISH_CANDLES = "If your corpse is near lit candles, you will be unable to resurrect.", + BANISH_DESTRUCTION = "If your corpse is destroyed, you will be unable to resurrect.", + BANISH_FUNERAL_GARB = "If your corpse is clad in funeral garments, you will be unable to resurrect." + ) + ) + +/datum/devilinfo/ + var/datum/mind/owner = null + var/obligation + var/ban + var/bane + var/banish + var/truename + var/list/datum/mind/soulsOwned = new + var/reviveNumber = 0 + var/form = BASIC_DEVIL + var/exists = 0 + +/proc/randomDevilInfo(name = randomDevilName()) + var/datum/devilinfo/devil = new + devil.truename = name + devil.bane = randomdevilbane() + devil.obligation = randomdevilobligation() + devil.ban = randomdevilban() + devil.banish = randomdevilbanish() + return devil + +/proc/devilInfo(name, saveDetails = 0) + if(allDevils[lowertext(name)]) + return allDevils[lowertext(name)] + else + var/datum/devilinfo/devil = randomDevilInfo(name) + allDevils[lowertext(name)] = devil + devil.exists = saveDetails + return devil + + + +/proc/randomDevilName() + var/preTitle = "" + var/title = "" + var/mainName = "" + var/suffix = "" + if(prob(65)) + if(prob(35)) + preTitle = pick("Dark ", "Hellish ", "Fiery ", "Sinful ", "Blood ") + title = pick("Lord ", "Fallen Prelate ", "Count ", "Viscount ", "Vizier ", "Elder ", "Adept ") + var/probability = 100 + mainName = pick("Hal", "Ve", "Odr", "Neit", "Ci", "Quon", "Mya", "Folth", "Wren", "Gyer", "Geyr", "Hil", "Niet", "Twou", "Hu", "Don") + while(prob(probability)) + mainName += pick("hal", "ve", "odr", "neit", "ca", "quon", "mya", "folth", "wren", "gyer", "geyr", "hil", "niet", "twoe", "phi", "coa") + probability -= 20 + if(prob(40)) + suffix = pick(" the Red", " the Soulless", " the Master", ", the Lord of all things", ", Jr.") + return preTitle + title + mainName + suffix + +/proc/randomdevilobligation() + return pick(OBLIGATION_FOOD, OBLIGATION_DRINK, OBLIGATION_GREET, OBLIGATION_PRESENCEKNOWN, OBLIGATION_SAYNAME, OBLIGATION_ANNOUNCEKILL, OBLIGATION_ANSWERTONAME) + +/proc/randomdevilban() + return pick(BAN_HURTWOMAN, BAN_CHAPEL, BAN_HURTPRIEST, BAN_AVOIDWATER, BAN_STRIKEUNCONCIOUS, BAN_HURTLIZARD, BAN_HURTANIMAL) + +/proc/randomdevilbane() + return pick(BANE_SALT, BANE_LIGHT, BANE_IRON, BANE_WHITECLOTHES, BANE_SILVER, BANE_HARVEST, BANE_TOOLBOX) + +/proc/randomdevilbanish() + return pick(BANISH_WATER, BANISH_COFFIN, BANISH_FORMALDYHIDE, BANISH_RUNES, BANISH_CANDLES, BANISH_DESTRUCTION, BANISH_FUNERAL_GARB) + +/datum/devilinfo/proc/add_soul(datum/mind/soul) + if(soulsOwned.Find(soul)) + return + soulsOwned += soul + switch(SOULVALUE) + if(0) + owner.current << "Your hellish powers have been restored." + give_base_spells() + if(POWERUPTHRESHOLD) + increase_blood_lizard() + if(POWERUPTHRESHOLD*2) + increase_true_devil() + if(POWERUPTHRESHOLD*3) + increase_arch_devil() + +/datum/devilinfo/proc/remove_soul(datum/mind/soul) + if(soulsOwned.Remove(soul)) + check_regression() + +/datum/devilinfo/proc/check_regression() + if (form == ARCH_DEVIL) + return //arch devil can't regress + switch(SOULVALUE) + if(-1) + remove_spells() + owner.current << "As punishment for your failures, all of your powers except contract creation have been revoked." + if(POWERUPTHRESHOLD-1) + regress_humanoid() + if(POWERUPTHRESHOLD*2-1) + regress_blood_lizard() + +/datum/devilinfo/proc/increase_form() + switch(form) + if(BASIC_DEVIL) + increase_blood_lizard() + if(BLOOD_LIZARD) + increase_true_devil() + if(TRUE_DEVIL) + increase_arch_devil() + +/datum/devilinfo/proc/regress_humanoid() + owner.current << "Your powers weaken, have more contracts be signed to regain power." + if(istype(owner.current, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = owner.current + H.set_species(/datum/species/human, 1) + H.regenerate_icons() + give_base_spells() + form = BASIC_DEVIL + +/datum/devilinfo/proc/regress_blood_lizard() + var/mob/living/carbon/true_devil/D = owner.current + D << "Your powers weaken, have more contracts be signed to regain power." + D.oldform.loc = D.loc + owner.transfer_to(D.oldform) + give_lizard_spells() + qdel(D) + form = BLOOD_LIZARD + + +/datum/devilinfo/proc/increase_blood_lizard() + owner.current << "You feel as though your humanoid form is about to shed. You will soon turn into a blood lizard." + sleep(50) + if(istype(owner.current, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = owner.current + H.set_species(/datum/species/lizard, 1) + H.underwear = "Nude" + H.undershirt = "Nude" + H.socks = "Nude" + H.dna.features["mcolor"] = "511" //A deep red + H.regenerate_icons() + else //Did the devil get hit by a staff of transmutation? + owner.current.color = "#501010" + give_lizard_spells() + form = BLOOD_LIZARD + + + +/datum/devilinfo/proc/increase_true_devil() + owner.current << "You feel as though your current form is about to shed. You will soon turn into a true devil." + sleep(50) + var/mob/living/carbon/true_devil/A = new /mob/living/carbon/true_devil(owner.current.loc) + A.faction |= "hell" + owner.current.loc = A + A.oldform = owner.current + owner.transfer_to(A) + A.set_name() + give_true_spells() + form = TRUE_DEVIL + + +/datum/devilinfo/proc/increase_arch_devil() + var/mob/living/carbon/true_devil/D = owner.current + D << "You feel as though your form is about to ascend." + sleep(50) + if(!D) + return + D.visible_message("[D]'s skin begins to erupt with spikes.", \ + "Your flesh begins creating a shield around yourself.") + sleep(100) + if(!D) + return + D.visible_message("The horns on [D]'s head slowly grow and elongate.", \ + "Your body continues to mutate. Your telepathic abilities grow.") + sleep(90) + if(!D) + return + D.visible_message("[D]'s body begins to violently stretch and contort.", \ + "You begin to rend apart the final barriers to ultimate power.") + sleep(40) + if(!D) + return + D << "Yes!" + sleep(10) + if(!D) + return + D << "YES!!" + sleep(10) + if(!D) + return + D << "YE--" + sleep(1) + if(!D) + return + world << "\"SLOTH, WRATH, GLUTTONY, ACEDIA, ENVY, GREED, PRIDE! FIRES OF HELL AWAKEN!!\"" + world << 'sound/hallucinations/veryfar_noise.ogg' + give_arch_spells() + D.convert_to_archdevil() + var/area/A = get_area(owner.current) + if(A) + notify_ghosts("An arch devil has ascended in \the [A.name]. Reach out to the devil to be given a new shell for your soul.", source = owner.current, attack_not_jump = 1) + sleep(50) + if(!ticker.mode.devil_ascended) + SSshuttle.emergency.request(null, 0.3) + ticker.mode.devil_ascended++ + form = ARCH_DEVIL + +/datum/devilinfo/proc/remove_spells() + for(var/X in owner.spell_list) + var/obj/effect/proc_holder/spell/S = X + if(!istype(S, /obj/effect/proc_holder/spell/targeted/summon_contract)) + owner.RemoveSpell(S) + +/datum/devilinfo/proc/give_summon_contract() + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_contract(null)) + + +/datum/devilinfo/proc/give_base_spells(give_summon_contract = 0) + remove_spells() + owner.AddSpell(new /obj/effect/proc_holder/spell/dumbfire/fireball/hellish(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_pitchfork(null)) + if(give_summon_contract) + give_summon_contract() + +/datum/devilinfo/proc/give_lizard_spells() + remove_spells() + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_pitchfork(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/dumbfire/fireball/hellish(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null)) + +/datum/devilinfo/proc/give_true_spells() + remove_spells() + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_pitchfork/greater(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/dumbfire/fireball/hellish(null)) + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null)) + //owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch(null)) TODO LORDPIDEY add this spell + +/datum/devilinfo/proc/give_arch_spells() + remove_spells() + owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_pitchfork/ascended(null)) + //owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch/ascended(null)) TODO LORDPIDEY + +/datum/devilinfo/proc/beginResurrectionCheck(mob/living/body) + if(SOULVALUE>0) + owner.current<< "Your body has been damaged to the point that you may no longer use it. At the cost of some of your power, you will return to life soon. Remain in your body." + sleep(DEVILRESURRECTTIME) + if (!body || body.stat == DEAD) + if(SOULVALUE>0) + if(check_banishment(body)) + owner.current<< "Unfortunately, the mortals have finished a ritual that prevents your resurrection." + return -1 + else + owner.current<< "WE LIVE AGAIN!" + return hellish_resurrection(body) + else + owner.current<< "Unfortunately, the power that stemmed from your contracts has been extinguished. You no longer have enough power to resurrect." + return -1 + else + owner.current << " You seem to have resurrected without your hellish powers." + else + owner.current << "Your hellish powers are too weak to resurrect yourself." + +/datum/devilinfo/proc/check_banishment(mob/living/body) + switch(banish) + if(BANISH_WATER) + if(istype(body, /mob/living/carbon)) + var/mob/living/carbon/H = body + return H.reagents.has_reagent("holy water") + return 0 + if(BANISH_COFFIN) + return (body && istype(body.loc, /obj/structure/closet/coffin)) + if(BANISH_FORMALDYHIDE) + if(istype(body, /mob/living/carbon)) + var/mob/living/carbon/H = body + return H.reagents.has_reagent("formaldehyde") + return 0 + if(BANISH_RUNES) + if(body) + for(var/obj/effect/decal/cleanable/crayon/R in range(0,body)) + if (R.name == "rune") + return 1 + return 0 + if(BANISH_CANDLES) + if(body) + var/count = 0 + for(var/obj/item/candle/C in range(1,body)) + count += C.lit + if(count>=4) + return 1 + return 0 + if(BANISH_DESTRUCTION) + if(body) + return 0 + return 1 + if(BANISH_FUNERAL_GARB) + if(istype(body, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = body + if(H.w_uniform && istype(H.w_uniform, /obj/item/clothing/under/burial)) + return 1 + return 0 + +/datum/devilinfo/proc/hellish_resurrection(mob/living/body) + message_admins("[owner.name] (true name is: [truename]) is resurrecting using hellish energy.") + if(SOULVALUE < POWERUPTHRESHOLD * 3) // once ascended, arch devils do not go down in power by any means. + reviveNumber++ + if(body) + body.revive(1,0) + body.forceMove(get_turf(body))//Fixes dying while jaunted leaving you permajaunted. + if(istype(body, /mob/living/carbon/true_devil)) + var/mob/living/carbon/true_devil/D = body + if(D.oldform) + D.oldform.revive(1,0) // Heal the old body too, so the devil doesn't resurrect, then immediately regress into a dead body. + else + if(blobstart.len > 0) + var/turf/targetturf = get_turf(pick(blobstart)) + var/mob/currentMob = owner.current + if(!currentMob) + currentMob = owner.get_ghost() + if(!currentMob) + message_admins("[owner.name]'s devil resurrection failed due to client logoff. Aborting.") + return -1 // + if(currentMob.mind != owner) + message_admins("[owner.name]'s devil resurrection failed due to becoming a new mob. Aborting.") + return -1 + currentMob.change_mob_type( /mob/living/carbon/human , targetturf, null, 1) + var/mob/living/carbon/human/H = owner.current + give_summon_contract() + if(SOULVALUE >= POWERUPTHRESHOLD) + H.set_species(/datum/species/lizard, 1) + H.underwear = "Nude" + H.undershirt = "Nude" + H.socks = "Nude" + H.dna.features["mcolor"] = "511" + H.regenerate_icons() + if(SOULVALUE >= POWERUPTHRESHOLD * 2) //Yes, BOTH this and the above if statement are to run if soulpower is high enough. + var/mob/living/carbon/true_devil/A = new /mob/living/carbon/true_devil(targetturf) + A.faction |= "hell" + H.forceMove(A) + A.oldform = H + A.set_name() + owner.transfer_to(A) + if(SOULVALUE >= POWERUPTHRESHOLD * 3) + A.convert_to_archdevil() + + else + throw EXCEPTION("Unable to find a blobstart landmark for hellish resurrection") + check_regression() \ No newline at end of file diff --git a/code/game/gamemodes/demon/imp/imp.dm b/code/game/gamemodes/demon/imp/imp.dm new file mode 100644 index 00000000000..76696ced406 --- /dev/null +++ b/code/game/gamemodes/demon/imp/imp.dm @@ -0,0 +1,56 @@ +//////////////////The Monster + +/mob/living/simple_animal/imp + name = "imp" + real_name = "imp" + desc = "A large, menacing creature covered in armored black scales." + speak_emote = list("cackles") + emote_hear = list("cackles","screeches") + response_help = "thinks better of touching" + response_disarm = "flails at" + response_harm = "punches" + icon = 'icons/mob/mob.dmi' + icon_state = "imp" + icon_living = "imp" + speed = 1 + a_intent = "harm" + stop_automated_movement = 1 + status_flags = CANPUSH + attack_sound = 'sound/magic/demon_attack1.ogg' + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + minbodytemp = 250 //Weak to cold + maxbodytemp = INFINITY + faction = list("hell") + attacktext = "wildly tears into" + maxHealth = 200 + health = 200 + healable = 0 + environment_smash = 1 + melee_damage_lower = 10 + melee_damage_upper = 15 + see_in_dark = 8 + var/boost = 0 + bloodcrawl = BLOODCRAWL_EAT + see_invisible = SEE_INVISIBLE_MINIMUM + var/list/consumed_mobs = list() + var/playstyle_string = "You are an imp, a mischevious creature from hell. You are the lowest rank on the hellish totem pole \ + Though you are not obligated to help, perhaps by aiding a higher ranking devil, you might just get a promotion. However, you are incapable \ + of intentionally harming a fellow devil." + +/mob/living/simple_animal/imp/New() + ..() + boost = world.time + 30 + +/mob/living/simple_animal/imp/Life() + ..() + if(boost[src] screams in agony as it sublimates into a sulfurous smoke.") + ghostize() + qdel(src) diff --git a/code/game/gamemodes/demon/objectives.dm b/code/game/gamemodes/demon/objectives.dm new file mode 100644 index 00000000000..bdcac75b8e2 --- /dev/null +++ b/code/game/gamemodes/demon/objectives.dm @@ -0,0 +1,62 @@ +/datum/objective/devil + dangerrating = 5 + +/datum/objective/devil/soulquantity + explanation_text = "You shouldn't see this text. Error:DEVIL1" + var/quantity = 4 + +/datum/objective/devil/soulquantity/New() + quantity = pick(4,5) + explanation_text = "Purchase, and retain control over at least [quantity] souls." + +/datum/objective/devil/soulquantity/check_completion() + var/count = 0 + for(var/S in owner.devilinfo.soulsOwned) + var/datum/mind/L = S + if(L.soulOwner != L) + count++ + return count >= quantity + +/datum/objective/devil/soulquality + explanation_text = "You shouldn't see this text. Error:DEVIL2" + var/contractType + var/quantity + +/datum/objective/devil/soulquality/New() + contractType = pick(CONTRACT_POWER, CONTRACT_WEALTH, CONTRACT_PRESTIGE, CONTRACT_MAGIC, CONTRACT_REVIVE, CONTRACT_KNOWLEDGE/*, CONTRACT_UNWILLING*/) + var/contractName + quantity = pick(1,2) + switch(contractType) + if(CONTRACT_POWER) + contractName = "for power" + if(CONTRACT_WEALTH) + contractName = "for wealth" + if(CONTRACT_PRESTIGE) + contractName = "for prestige" + if(CONTRACT_MAGIC) + contractName = "for magic" + if(CONTRACT_REVIVE) + contractName = "of revival" + if(CONTRACT_KNOWLEDGE) + contractName = "for knowledge" + //if(CONTRACT_UNWILLING) //Makes round unfun. + // contractName = "against their will" + explanation_text = "Have mortals sign at least [quantity] contracts [contractName]" + +/datum/objective/devil/soulquality/check_completion() + var/count = 0 + for(var/S in owner.devilinfo.soulsOwned) + var/datum/mind/L = S + if(L.soulOwner != L && L.damnation_type == contractType) + count++ + return count>=quantity + +/datum/objective/devil/sintouch + var/quantity + +/datum/objective/devil/sintouch/New() + quantity = pick(4,5) + explanation_text = "Ensure at least [quantity] mortals are sintouched." + +/datum/objective/devil/sintouch/check_completion() + return quantity>=ticker.mode.sintouched.len \ No newline at end of file diff --git a/code/game/gamemodes/demon/true_demon/_true_demon.dm b/code/game/gamemodes/demon/true_demon/_true_demon.dm new file mode 100644 index 00000000000..36d491df5f9 --- /dev/null +++ b/code/game/gamemodes/demon/true_demon/_true_demon.dm @@ -0,0 +1,195 @@ +#define DEVIL_HANDS_LAYER 1 +#define DEVIL_HEAD_LAYER 2 +#define DEVIL_TOTAL_LAYERS 2 + + +/mob/living/carbon/true_devil + name = "True Devil" + desc = "A pile of infernal energy, taking a vaguely humanoid form." + icon = 'icons/mob/32x64.dmi' + icon_state = "true_devil" + gender = NEUTER + health = 350 + maxHealth = 350 + ventcrawler = 0 + density = 0 + pass_flags = 0 + var/ascended = 0 + sight = (SEE_TURFS | SEE_OBJS) + status_flags = CANPUSH + languages = ALL //The devil speaks all languages meme + mob_size = MOB_SIZE_LARGE + var/mob/living/oldform + var/list/devil_overlays[DEVIL_TOTAL_LAYERS] + +/mob/living/carbon/true_devil/New() + internal_organs += new /obj/item/organ/brain/ + internal_organs += new /obj/item/organ/tongue + for(var/X in internal_organs) + var/obj/item/organ/I = X + I.Insert(src) + ..() + + +/mob/living/carbon/true_devil/proc/convert_to_archdevil() + maxHealth = 5000 // not an IMPOSSIBLE amount, but still near impossible. + ascended = 1 + health = maxHealth + icon_state = "arch_devil" + +/mob/living/carbon/true_devil/proc/set_name() + name = mind.devilinfo.truename + real_name = name + +/mob/living/carbon/true_devil/Login() + ..() + mind.announceDevilLaws() + + +/mob/living/carbon/true_devil/death(gibbed) + stat = DEAD + ..(gibbed) + drop_l_hand() + drop_r_hand() + spawn (0) + mind.devilinfo.beginResurrectionCheck(src) + + +/mob/living/carbon/true_devil/examine(mob/user) + var/msg = "*---------*\nThis is \icon[src] [src]!\n" + + //Left hand items + if(l_hand && !(l_hand.flags&ABSTRACT)) + if(l_hand.blood_DNA) + msg += "It is holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] blood-stained [l_hand.name] in its left hand!\n" + else + msg += "It is holding \icon[l_hand] \a [l_hand] in its left hand.\n" + + //Right hand items + if(r_hand && !(r_hand.flags&ABSTRACT)) + if(r_hand.blood_DNA) + msg += "It is holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] blood-stained [r_hand.name] in its right hand!\n" + else + msg += "It is holding \icon[r_hand] \a [r_hand] in its right hand.\n" + + //Braindead + if(!client && stat != DEAD) + msg += "The devil seems to be in deep contemplation.\n" + + //Damaged + if(stat == DEAD) + msg += "The hellfire seems to have been extinguished, for now at least.\n" + else if(health < (maxHealth/10)) + msg += "You can see hellfire inside of it's gaping wounds.\n" + else if(health < (maxHealth/2)) + msg += "You can see hellfire inside of it's wounds.\n" + msg += "*---------*" + user << msg + + +/mob/living/carbon/true_devil/IsAdvancedToolUser() + return 1 + + +/mob/living/carbon/true_devil/canUseTopic() + if(stat) + return + return 1 + + +/mob/living/carbon/true_devil/assess_threat() + return 666 + +/mob/living/carbon/true_devil/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0) + if(mind && mind.devilinfo.bane == BANE_LIGHT) + if(has_bane(BANE_LIGHT)) + mind.disrupt_spells(-500) + return ..() //flashes don't stop devils UNLESS it's their bane. + + +/mob/living/carbon/true_devil/attacked_by(obj/item/I, mob/living/user, def_zone) + var/weakness = check_weakness(I, user) + apply_damage(I.force * weakness, I.damtype, def_zone) + var/message_verb = "" + if(I.attack_verb && I.attack_verb.len) + message_verb = "[pick(I.attack_verb)]" + else if(I.force) + message_verb = "attacked" + + var/attack_message = "[src] has been [message_verb] with [I]." + if(user) + user.do_attack_animation(src) + if(user in viewers(src, null)) + attack_message = "[user] has [message_verb] [src] with [I]!" + if(message_verb) + visible_message("[attack_message]", + "[attack_message]") + +/mob/living/carbon/true_devil/UnarmedAttack(atom/A, proximity) + A.attack_hand(src) + +/mob/living/carbon/true_devil/Process_Spacemove(movement_dir = 0) + return 1 + +/mob/living/carbon/true_devil/ex_act(severity) + if(ascended) + return 0 + return ..() + +/mob/living/carbon/true_devil/singularity_act() + if(ascended) + return 0 + return ..() + +/mob/living/carbon/true_devil/attack_ghost(mob/dead/observer/user as mob) + if(ascended || user.mind.soulOwner == src.mind) + var/mob/living/simple_animal/imp/S = new(get_turf(loc)) + S.key = user.key + S.mind.assigned_role = "Imp" + S.mind.special_role = "Imp" + var/datum/objective/newobjective = new + newobjective.explanation_text = "Try to get a promotion to a higher devilic rank." + S.mind.objectives += newobjective + S << S.playstyle_string + S << "Objective #[1]: [newobjective.explanation_text]" + return + else + return ..() + +/mob/living/carbon/true_devil/can_be_revived() + return 1 + +/mob/living/carbon/true_devil/resist_fire() + //They're immune to fire. + +/mob/living/carbon/true_devil/attack_hand(mob/living/carbon/human/M) + if(..()) + switch(M.a_intent) + if ("harm") + var/damage = rand(1, 5) + playsound(loc, "punch", 25, 1, -1) + visible_message("[M] has punched [src]!", \ + "[M] has punched [src]!") + adjustBruteLoss(damage) + add_logs(M, src, "attacked") + updatehealth() + if ("disarm") + if (!lying && !ascended) //No stealing the arch devil's pitchfork. + if (prob(5)) + Paralyse(2) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + add_logs(M, src, "pushed") + visible_message("[M] has pushed down [src]!", \ + "[M] has pushed down [src]!") + else + if (prob(25)) + drop_item() + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + visible_message("[M] has disarmed [src]!", \ + "[M] has disarmed [src]!") + else + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + visible_message("[M] has attempted to disarm [src]!") + +/mob/living/carbon/true_devil/handle_breathing() + // devils do not need to breathe diff --git a/code/game/gamemodes/demon/true_demon/inventory.dm b/code/game/gamemodes/demon/true_demon/inventory.dm new file mode 100644 index 00000000000..23035370135 --- /dev/null +++ b/code/game/gamemodes/demon/true_demon/inventory.dm @@ -0,0 +1,61 @@ +/mob/living/carbon/true_devil/unEquip(obj/item/I, force) + if(..(I,force)) + update_inv_hands() + return 1 + return 0 + +/mob/living/carbon/true_devil/proc/update_inv_hands() + //TODO LORDPIDEY: Figure out how to make the hands line up properly. the l/r_hand_image should use the down sprite when facing down, left, or right, and the up sprite when facing up. + remove_overlay(DEVIL_HANDS_LAYER) + var/list/hands_overlays = list() + + if(r_hand) + + var/r_state = r_hand.item_state + if(!r_state) + r_state = r_hand.icon_state + + var/image/r_hand_image = r_hand.build_worn_icon(state = r_state, default_layer = DEVIL_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE) + + hands_overlays += r_hand_image + + if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) + r_hand.layer = 20 + r_hand.screen_loc = ui_rhand + client.screen |= r_hand + + if(l_hand) + + var/l_state = l_hand.item_state + if(!l_state) + l_state = l_hand.icon_state + + var/image/l_hand_image = l_hand.build_worn_icon(state = l_state, default_layer = DEVIL_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE) + + hands_overlays += l_hand_image + + if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) + l_hand.layer = 20 + l_hand.screen_loc = ui_lhand + client.screen |= l_hand + if(hands_overlays.len) + devil_overlays[DEVIL_HANDS_LAYER] = hands_overlays + apply_overlay(DEVIL_HANDS_LAYER) + +/mob/living/carbon/true_devil/update_inv_l_hand() + update_inv_hands() + + +/mob/living/carbon/true_devil/update_inv_r_hand() + update_inv_hands() + +/mob/living/carbon/true_devil/remove_overlay(cache_index) + if(devil_overlays[cache_index]) + overlays -= devil_overlays[cache_index] + devil_overlays[cache_index] = null + + +/mob/living/carbon/true_devil/apply_overlay(cache_index) + var/image/I = devil_overlays[cache_index] + if(I) + overlays += I \ No newline at end of file diff --git a/code/game/gamemodes/miniantags/sintouched/objectives.dm b/code/game/gamemodes/miniantags/sintouched/objectives.dm new file mode 100644 index 00000000000..86572782ca8 --- /dev/null +++ b/code/game/gamemodes/miniantags/sintouched/objectives.dm @@ -0,0 +1,35 @@ +/datum/objective/sintouched + dangerrating = 5 + completed = 1 + +/* NO ERP OBJECTIVE FOR YOU. +/datum/objective/sintouched/lust + dangerrating = 3 // it's not AS dangerous. + +/datum/objective/sintouched/lust/New() + var/mob/dead/D = pick(dead_mob_list) + if(prob(50) && D) + explanation_text = "You know that [D] has perished.... and you think [D] is kinda cute. Make sure everyone knows how HOT [D]'s lifeless body is." + else + explanation_text = "Go get married, then immediately cheat on your new spouse." */ + +/datum/objective/sintouched/gluttony + explanation_text = "Everything is so delicious. Go eat everything." + +/datum/objective/sintouched/greed + explanation_text = "You want MORE, more money, more wealth, more riches. Go get it, but don't hurt people for it." + +/datum/objective/sintouched/sloth + explanation_text = "You just get tired randomly. Go take a nap at a time that would inconvenience other people." + +/datum/objective/sintouched/wrath + explanation_text = "What have your coworkers ever done for you? Don't offer to help them in any matter, and refuse if asked." + +/datum/objective/sintouched/envy + explanation_text = "Why should you be stuck with your rank? Show everyone you can do other jobs too, and don't let anyone stop you, least of all because you have no training" + +/datum/objective/sintouched/pride + explanation_text = "You are the BEST thing on the station. Make sure everyone knows it." + +/datum/objective/sintouched/acedia + explanation_text = "Angels, devils, good, evil... who cares? Just ignore any hellish threats and do your job." \ No newline at end of file diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index b6a576e12f5..ddbdcfa4e09 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -203,7 +203,7 @@ return if((src.occupant) && (src.occupant.loc == src)) - if((src.occupant.stat == DEAD) || (src.occupant.suiciding) || !occupant.key) //Autoeject corpses and suiciding dudes. + if((src.occupant.stat == DEAD) || (src.occupant.suiciding) || !occupant.key || src.occupant.hellbound) //Autoeject corpses and suiciding dudes. src.locked = 0 src.go_out() src.connected_message("Clone Rejected: Deceased.") diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 1b50cab81af..253a3c1c8d7 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -1,1114 +1,1115 @@ -/obj/machinery/computer/arcade/ - name = "random arcade" - desc = "random arcade machine" - icon_state = "arcade" - icon_keyboard = null - icon_screen = "invaders" - var/list/prizes = list( /obj/item/weapon/storage/box/snappops = 2, - /obj/item/toy/AI = 2, - /obj/item/clothing/under/syndicate/tacticool = 2, - /obj/item/toy/sword = 2, - /obj/item/toy/gun = 2, - /obj/item/weapon/gun/projectile/shotgun/toy/crossbow = 2, - /obj/item/weapon/storage/box/fakesyndiesuit = 2, - /obj/item/weapon/storage/crayons = 2, - /obj/item/toy/spinningtoy = 2, - /obj/item/toy/prize/ripley = 1, - /obj/item/toy/prize/fireripley = 1, - /obj/item/toy/prize/deathripley = 1, - /obj/item/toy/prize/gygax = 1, - /obj/item/toy/prize/durand = 1, - /obj/item/toy/prize/honk = 1, - /obj/item/toy/prize/marauder = 1, - /obj/item/toy/prize/seraph = 1, - /obj/item/toy/prize/mauler = 1, - /obj/item/toy/prize/odysseus = 1, - /obj/item/toy/prize/phazon = 1, - /obj/item/toy/prize/reticence = 1, - /obj/item/toy/cards/deck = 2, - /obj/item/toy/nuke = 2, - /obj/item/toy/minimeteor = 2, - /obj/item/toy/carpplushie = 2, - /obj/item/toy/foamblade = 2, - /obj/item/toy/redbutton = 2, - /obj/item/toy/talking/owl = 2, - /obj/item/toy/talking/griffin = 2, - /obj/item/weapon/coin/antagtoken = 2, - /obj/item/stack/tile/fakespace/loaded = 2, - /obj/item/toy/toy_xeno = 2, - /obj/item/weapon/restraints/handcuffs/fake = 2 - ) - -/obj/machinery/computer/arcade/New() - ..() - // If it's a generic arcade machine, pick a random arcade - // circuit board for it and make the new machine - if(!circuit) - var/choice = pick(subtypesof(/obj/item/weapon/circuitboard/computer/arcade)) - var/obj/item/weapon/circuitboard/CB = new choice() - new CB.build_path(loc, CB) - qdel(src) - -/obj/machinery/computer/arcade/proc/prizevend() - if(prob(0.0001)) //1 in a million - new /obj/item/weapon/gun/energy/pulse(src) - - if(!contents.len) - var/prizeselect = pickweight(prizes) - new prizeselect(src.loc) - - if(istype(prizeselect, /obj/item/toy/gun)) //Ammo comes with the gun - new /obj/item/toy/ammo/gun(src.loc) - - else if(istype(prizeselect, /obj/item/clothing/suit/syndicatefake)) //Helmet is part of the suit - new /obj/item/clothing/head/syndicatefake(src.loc) - - else - var/atom/movable/prize = pick(contents) - prize.loc = src.loc - -/obj/machinery/computer/arcade/emp_act(severity) - ..(severity) - - if(stat & (NOPOWER|BROKEN)) - return - - var/empprize = null - var/num_of_prizes = 0 - switch(severity) - if(1) - num_of_prizes = rand(1,4) - if(2) - num_of_prizes = rand(0,2) - for(var/i = num_of_prizes; i > 0; i--) - empprize = pickweight(prizes) - new empprize(src.loc) - explosion(src.loc, -1, 0, 1+num_of_prizes, flame_range = 1+num_of_prizes) - - -// ** BATTLE ** // - - -/obj/machinery/computer/arcade/battle - name = "arcade machine" - desc = "Does not support Pinball." - icon_state = "arcade" - circuit = /obj/item/weapon/circuitboard/computer/arcade/battle - var/enemy_name = "Space Villian" - var/temp = "Winners don't use space drugs" //Temporary message, for attack messages, etc - var/player_hp = 30 //Player health/attack points - var/player_mp = 10 - var/enemy_hp = 45 //Enemy health/attack points - var/enemy_mp = 20 - var/gameover = 0 - var/blocked = 0 //Player cannot attack/heal while set - var/turtle = 0 - -/obj/machinery/computer/arcade/battle/New() - ..() - var/name_action - var/name_part1 - var/name_part2 - - name_action = pick("Defeat ", "Annihilate ", "Save ", "Strike ", "Stop ", "Destroy ", "Robust ", "Romance ", "Pwn ", "Own ", "Ban ") - - name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Cuban ", "the Evil ", "the Dread King ", "the Space ", "Lord ", "the Great ", "Duke ", "General ") - name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "slime", "Griefer", "ERPer", "Lizard Man", "Unicorn", "Bloopers") - - src.enemy_name = replacetext((name_part1 + name_part2), "the ", "") - src.name = (name_action + name_part1 + name_part2) - -/obj/machinery/computer/arcade/battle/attack_hand(mob/user) - if(..()) - return - user.set_machine(src) - var/dat = "Close" - dat += "

[src.enemy_name]

" - - dat += "

[src.temp]

" - dat += "
Health: [src.player_hp] | Magic: [src.player_mp] | Enemy Health: [src.enemy_hp]
" - - if (src.gameover) - dat += "
New Game" - else - dat += "
Attack | " - dat += "Heal | " - dat += "Recharge Power" - - dat += "
" - - //user << browse(dat, "window=arcade") - //onclose(user, "arcade") - var/datum/browser/popup = new(user, "arcade", "Space Villian 2000") - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - return - -/obj/machinery/computer/arcade/battle/Topic(href, href_list) - if(..()) - return - - if (!src.blocked && !src.gameover) - if (href_list["attack"]) - src.blocked = 1 - var/attackamt = rand(2,6) - src.temp = "You attack for [attackamt] damage!" - playsound(src.loc, 'sound/arcade/Hit.ogg', 50, 1, extrarange = -3, falloff = 10) - src.updateUsrDialog() - if(turtle > 0) - turtle-- - - sleep(10) - src.enemy_hp -= attackamt - src.arcade_action() - - else if (href_list["heal"]) - src.blocked = 1 - var/pointamt = rand(1,3) - var/healamt = rand(6,8) - src.temp = "You use [pointamt] magic to heal for [healamt] damage!" - playsound(src.loc, 'sound/arcade/Heal.ogg', 50, 1, extrarange = -3, falloff = 10) - src.updateUsrDialog() - turtle++ - - sleep(10) - src.player_mp -= pointamt - src.player_hp += healamt - src.blocked = 1 - src.updateUsrDialog() - src.arcade_action() - - else if (href_list["charge"]) - src.blocked = 1 - var/chargeamt = rand(4,7) - src.temp = "You regain [chargeamt] points" - playsound(src.loc, 'sound/arcade/Mana.ogg', 50, 1, extrarange = -3, falloff = 10) - src.player_mp += chargeamt - if(turtle > 0) - turtle-- - - src.updateUsrDialog() - sleep(10) - src.arcade_action() - - if (href_list["close"]) - usr.unset_machine() - usr << browse(null, "window=arcade") - - else if (href_list["newgame"]) //Reset everything - temp = "New Round" - player_hp = 30 - player_mp = 10 - enemy_hp = 45 - enemy_mp = 20 - gameover = 0 - turtle = 0 - - if(emagged) - src.New() - emagged = 0 - - src.add_fingerprint(usr) - src.updateUsrDialog() - return - -/obj/machinery/computer/arcade/battle/proc/arcade_action() - if ((src.enemy_mp <= 0) || (src.enemy_hp <= 0)) - if(!gameover) - src.gameover = 1 - src.temp = "[src.enemy_name] has fallen! Rejoice!" - playsound(src.loc, 'sound/arcade/Win.ogg', 50, 1, extrarange = -3, falloff = 10) - - if(emagged) - feedback_inc("arcade_win_emagged") - new /obj/effect/spawner/newbomb/timer/syndicate(src.loc) - new /obj/item/clothing/head/collectable/petehat(src.loc) - message_admins("[key_name_admin(usr)] has outbombed Cuban Pete and been awarded a bomb.") - log_game("[key_name(usr)] has outbombed Cuban Pete and been awarded a bomb.") - src.New() - emagged = 0 - else - feedback_inc("arcade_win_normal") - prizevend() - - else if (emagged && (turtle >= 4)) - var/boomamt = rand(5,10) - src.temp = "[src.enemy_name] throws a bomb, exploding you for [boomamt] damage!" - playsound(src.loc, 'sound/arcade/Boom.ogg', 50, 1, extrarange = -3, falloff = 10) - src.player_hp -= boomamt - - else if ((src.enemy_mp <= 5) && (prob(70))) - var/stealamt = rand(2,3) - src.temp = "[src.enemy_name] steals [stealamt] of your power!" - playsound(src.loc, 'sound/arcade/Steal.ogg', 50, 1, extrarange = -3, falloff = 10) - src.player_mp -= stealamt - src.updateUsrDialog() - - if (src.player_mp <= 0) - src.gameover = 1 - sleep(10) - src.temp = "You have been drained! GAME OVER" - playsound(src.loc, 'sound/arcade/Lose.ogg', 50, 1, extrarange = -3, falloff = 10) - if(emagged) - feedback_inc("arcade_loss_mana_emagged") - usr.gib() - else - feedback_inc("arcade_loss_mana_normal") - - else if ((src.enemy_hp <= 10) && (src.enemy_mp > 4)) - src.temp = "[src.enemy_name] heals for 4 health!" - playsound(src.loc, 'sound/arcade/Heal.ogg', 50, 1, extrarange = -3, falloff = 10) - src.enemy_hp += 4 - src.enemy_mp -= 4 - - else - var/attackamt = rand(3,6) - src.temp = "[src.enemy_name] attacks for [attackamt] damage!" - playsound(src.loc, 'sound/arcade/Hit.ogg', 50, 1, extrarange = -3, falloff = 10) - src.player_hp -= attackamt - - if ((src.player_mp <= 0) || (src.player_hp <= 0)) - src.gameover = 1 - src.temp = "You have been crushed! GAME OVER" - playsound(src.loc, 'sound/arcade/Lose.ogg', 50, 1, extrarange = -3, falloff = 10) - if(emagged) - feedback_inc("arcade_loss_hp_emagged") - usr.gib() - else - feedback_inc("arcade_loss_hp_normal") - - src.blocked = 0 - return - - -/obj/machinery/computer/arcade/battle/emag_act(mob/user) - if(!emagged) - temp = "If you die in the game, you die for real!" - player_hp = 30 - player_mp = 10 - enemy_hp = 45 - enemy_mp = 20 - gameover = 0 - blocked = 0 - - emagged = 1 - - enemy_name = "Cuban Pete" - name = "Outbomb Cuban Pete" - - - src.updateUsrDialog() - - - -// *** THE ORION TRAIL ** // - -#define ORION_TRAIL_WINTURN 9 - -//Orion Trail Events -#define ORION_TRAIL_RAIDERS "Raiders" -#define ORION_TRAIL_FLUX "Interstellar Flux" -#define ORION_TRAIL_ILLNESS "Illness" -#define ORION_TRAIL_BREAKDOWN "Breakdown" -#define ORION_TRAIL_LING "Changelings?" -#define ORION_TRAIL_LING_ATTACK "Changeling Ambush" -#define ORION_TRAIL_MALFUNCTION "Malfunction" -#define ORION_TRAIL_COLLISION "Collision" -#define ORION_TRAIL_SPACEPORT "Spaceport" -#define ORION_TRAIL_BLACKHOLE "BlackHole" - -#define ORION_STATUS_START 1 -#define ORION_STATUS_NORMAL 2 -#define ORION_STATUS_GAMEOVER 3 -#define ORION_STATUS_MARKET 4 - -/obj/machinery/computer/arcade/orion_trail - name = "The Orion Trail" - desc = "Learn how our ancestors got to Orion, and have fun in the process!" - icon_state = "arcade" - circuit = /obj/item/weapon/circuitboard/computer/arcade/orion_trail - var/busy = 0 //prevent clickspam that allowed people to ~speedrun~ the game. - var/engine = 0 - var/hull = 0 - var/electronics = 0 - var/food = 80 - var/fuel = 60 - var/turns = 4 - var/alive = 4 - var/eventdat = null - var/event = null - var/list/settlers = list("Harry","Larry","Bob") - var/list/events = list(ORION_TRAIL_RAIDERS = 3, - ORION_TRAIL_FLUX = 1, - ORION_TRAIL_ILLNESS = 3, - ORION_TRAIL_BREAKDOWN = 2, - ORION_TRAIL_LING = 3, - ORION_TRAIL_MALFUNCTION = 2, - ORION_TRAIL_COLLISION = 1, - ORION_TRAIL_SPACEPORT = 2 - ) - var/list/stops = list() - var/list/stopblurbs = list() - var/lings_aboard = 0 - var/spaceport_raided = 0 - var/spaceport_freebie = 0 - var/last_spaceport_action = "" - var/gameStatus = ORION_STATUS_START - var/canContinueEvent = 0 - -/obj/machinery/computer/arcade/orion_trail/New() - ..() - // Sets up the main trail - stops = list("Pluto","Asteroid Belt","Proxima Centauri","Dead Space","Rigel Prime","Tau Ceti Beta","Black Hole","Space Outpost Beta-9","Orion Prime") - stopblurbs = list( - "Pluto, long since occupied with long-range sensors and scanners, stands ready to, and indeed continues to probe the far reaches of the galaxy.", - "At the edge of the Sol system lies a treacherous asteroid belt. Many have been crushed by stray asteroids and misguided judgement.", - "The nearest star system to Sol, in ages past it stood as a reminder of the boundaries of sub-light travel, now a low-population sanctuary for adventurers and traders.", - "This region of space is particularly devoid of matter. Such low-density pockets are known to exist, but the vastness of it is astounding.", - "Rigel Prime, the center of the Rigel system, burns hot, basking its planetary bodies in warmth and radiation.", - "Tau Ceti Beta has recently become a waypoint for colonists headed towards Orion. There are many ships and makeshift stations in the vicinity.", - "Sensors indicate that a black hole's gravitational field is affecting the region of space we were headed through. We could stay of course, but risk of being overcome by its gravity, or we could change course to go around, which will take longer.", - "You have come into range of the first man-made structure in this region of space. It has been constructed not by travellers from Sol, but by colonists from Orion. It stands as a monument to the colonists' success.", - "You have made it to Orion! Congratulations! Your crew is one of the few to start a new foothold for mankind!" - ) - -/obj/machinery/computer/arcade/orion_trail/proc/newgame() - // Set names of settlers in crew - settlers = list() - for(var/i = 1; i <= 3; i++) - add_crewmember() - add_crewmember("[usr]") - // Re-set items to defaults - engine = 1 - hull = 1 - electronics = 1 - food = 80 - fuel = 60 - alive = 4 - turns = 1 - event = null - gameStatus = ORION_STATUS_NORMAL - lings_aboard = 0 - - //spaceport junk - spaceport_raided = 0 - spaceport_freebie = 0 - last_spaceport_action = "" - -/obj/machinery/computer/arcade/orion_trail/attack_hand(mob/user) - if(..()) - return - if(fuel <= 0 || food <=0 || settlers.len == 0) - gameStatus = ORION_STATUS_GAMEOVER - event = null - user.set_machine(src) - var/dat = "" - if(gameStatus == ORION_STATUS_GAMEOVER) - dat = "

Game Over

" - dat += "Like many before you, your crew never made it to Orion, lost to space...
Forever." - if(settlers.len == 0) - dat += "
Your entire crew died, your ship joins the fleet of ghost-ships littering the galaxy." - else - if(food <= 0) - dat += "
You ran out of food and starved." - if(emagged) - user.nutrition = 0 //yeah you pretty hongry - user << "Your body instantly contracts to that of one who has not eaten in months. Agonizing cramps seize you as you fall to the floor." - if(fuel <= 0) - dat += "
You ran out of fuel, and drift, slowly, into a star." - if(emagged) - var/mob/living/M = user - M.adjust_fire_stacks(5) - M.IgniteMob() //flew into a star, so you're on fire - user << "You feel an immense wave of heat emanate from the arcade machine. Your skin bursts into flames." - dat += "

OK...

" - - if(emagged) - user << "You're never going to make it to Orion..." - user.death() - emagged = 0 //removes the emagged status after you lose - gameStatus = ORION_STATUS_START - name = "The Orion Trail" - desc = "Learn how our ancestors got to Orion, and have fun in the process!" - - else if(event) - dat = eventdat - else if(gameStatus == ORION_STATUS_NORMAL) - var/title = stops[turns] - var/subtext = stopblurbs[turns] - dat = "

[title]

" - dat += "[subtext]" - dat += "

Crew:

" - dat += english_list(settlers) - dat += "
Food: [food] | Fuel: [fuel]" - dat += "
Engine Parts: [engine] | Hull Panels: [hull] | Electronics: [electronics]" - if(turns == 7) - dat += "

Go Around Continue

" - else - dat += "

Continue

" - dat += "

Kill a crewmember

" - dat += "

Close

" - else - dat = "

The Orion Trail

" - dat += "

Experience the journey of your ancestors!



" - dat += "
New Game
" - dat += "

Close

" - var/datum/browser/popup = new(user, "arcade", "The Orion Trail",400,700) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - return - -/obj/machinery/computer/arcade/orion_trail/Topic(href, href_list) - if(..()) - return - if(href_list["close"]) - usr.unset_machine() - usr << browse(null, "window=arcade") - - if(busy) - return - busy = 1 - - if (href_list["continue"]) //Continue your travels - if(gameStatus == ORION_STATUS_NORMAL && !event && turns != 7) - if(turns >= ORION_TRAIL_WINTURN) - win() - else - food -= (alive+lings_aboard)*2 - fuel -= 5 - if(turns == 2 && prob(30)) - event = ORION_TRAIL_COLLISION - event() - else if(prob(75)) - event = pickweight(events) - if(lings_aboard) - if(event == ORION_TRAIL_LING || prob(55)) - event = ORION_TRAIL_LING_ATTACK - event() - turns += 1 - if(emagged) - var/mob/living/carbon/M = usr //for some vars - switch(event) - if(ORION_TRAIL_RAIDERS) - if(prob(50)) - usr << "You hear battle shouts. The tramping of boots on cold metal. Screams of agony. The rush of venting air. Are you going insane?" - M.hallucination += 30 - else - usr << "Something strikes you from behind! It hurts like hell and feel like a blunt weapon, but nothing is there..." - M.take_organ_damage(30) - playsound(loc, 'sound/weapons/genhit2.ogg', 100, 1) - if(ORION_TRAIL_ILLNESS) - var/severity = rand(1,3) //pray to RNGesus. PRAY, PIGS - if(severity == 1) - M << "You suddenly feel slightly nauseous." //got off lucky - if(severity == 2) - usr << "You suddenly feel extremely nauseous and hunch over until it passes." - M.Stun(3) - if(severity >= 3) //you didn't pray hard enough - M << "An overpowering wave of nausea consumes over you. You hunch over, your stomach's contents preparing for a spectacular exit." - M.Stun(5) - sleep(30) - M.vomit(50) - if(ORION_TRAIL_FLUX) - if(prob(75)) - M.Weaken(3) - say("A sudden gust of powerful wind slams [M] into the floor!") - M.take_organ_damage(25) - playsound(src.loc, 'sound/weapons/Genhit.ogg', 100, 1) - else - M << "A violent gale blows past you, and you barely manage to stay standing!" - if(ORION_TRAIL_COLLISION) //by far the most damaging event - if(prob(90)) - playsound(src.loc, 'sound/effects/bang.ogg', 100, 1) - var/turf/open/floor/F - for(F in orange(1, src)) - F.ChangeTurf(F.baseturf) - say("Something slams into the floor around [src], exposing it to space!") - if(hull) - sleep(10) - say("A new floor suddenly appears around [src]. What the hell?") - playsound(src.loc, 'sound/weapons/Genhit.ogg', 100, 1) - var/turf/open/space/T - for(T in orange(1, src)) - T.ChangeTurf(/turf/open/floor/plating/) - else - say("Something slams into the floor around [src] - luckily, it didn't get through!") - playsound(src.loc, 'sound/effects/bang.ogg', 50, 1) - if(ORION_TRAIL_MALFUNCTION) - playsound(src.loc, 'sound/effects/EMPulse.ogg', 50, 1) - src.visible_message("[src] malfunctions, randomizing in-game stats!") - var/oldfood = food - var/oldfuel = fuel - food = rand(10,80) / rand(1,2) - fuel = rand(10,60) / rand(1,2) - if(electronics) - sleep(10) - if(oldfuel > fuel && oldfood > food) - src.audible_message("[src] lets out a somehow reassuring chime.") - else if(oldfuel < fuel || oldfood < food) - src.audible_message("[src] lets out a somehow ominous chime.") - food = oldfood - fuel = oldfuel - playsound(src.loc, 'sound/machines/chime.ogg', 50, 1) - - else if(href_list["newgame"]) //Reset everything - if(gameStatus == ORION_STATUS_START) - newgame() - else if(href_list["menu"]) //back to the main menu - if(gameStatus == ORION_STATUS_GAMEOVER) - gameStatus = ORION_STATUS_START - event = null - food = 80 - fuel = 60 - settlers = list("Harry","Larry","Bob") - else if(href_list["slow"]) //slow down - if(event == ORION_TRAIL_FLUX) - food -= (alive+lings_aboard)*2 - fuel -= 5 - event = null - else if(href_list["pastblack"]) //slow down - if(turns == 7) - food -= ((alive+lings_aboard)*2)*3 - fuel -= 15 - turns += 1 - event = null - else if(href_list["useengine"]) //use parts - if(event == ORION_TRAIL_BREAKDOWN) - engine = max(0, --engine) - event = null - else if(href_list["useelec"]) //use parts - if(event == ORION_TRAIL_MALFUNCTION) - electronics = max(0, --electronics) - event = null - else if(href_list["usehull"]) //use parts - if(event == ORION_TRAIL_COLLISION) - hull = max(0, --hull) - event = null - else if(href_list["wait"]) //wait 3 days - if(event == ORION_TRAIL_BREAKDOWN || event == ORION_TRAIL_MALFUNCTION || event == ORION_TRAIL_COLLISION) - food -= ((alive+lings_aboard)*2)*3 - event = null - else if(href_list["keepspeed"]) //keep speed - if(event == ORION_TRAIL_FLUX) - if(prob(75)) - event = "Breakdown" - event() - else - event = null - else if(href_list["blackhole"]) //keep speed past a black hole - if(turns == 7) - if(prob(75)) - event = ORION_TRAIL_BLACKHOLE - event() - if(emagged) //has to be here because otherwise it doesn't work - playsound(src.loc, 'sound/effects/supermatter.ogg', 100, 1) - say("A miniature black hole suddenly appears in front of [src], devouring [usr] alive!") - usr.Stun(10) //you can't run :^) - var/S = new /obj/singularity/academy(usr.loc) - emagged = 0 //immediately removes emagged status so people can't kill themselves by sprinting up and interacting - sleep(50) - say("[S] winks out, just as suddenly as it appeared.") - qdel(S) - else - event = null - turns += 1 - else if(href_list["holedeath"]) - if(event == ORION_TRAIL_BLACKHOLE) - gameStatus = ORION_STATUS_GAMEOVER - event = null - else if(href_list["eventclose"]) //end an event - if(canContinueEvent) - event = null - - else if(href_list["killcrew"]) //shoot a crewmember - if(gameStatus == ORION_STATUS_NORMAL || event == ORION_TRAIL_LING) - var/sheriff = remove_crewmember() //I shot the sheriff - playsound(loc,'sound/weapons/Gunshot.ogg', 100, 1) - - if(settlers.len == 0 || alive == 0) - say("The last crewmember [sheriff], shot themselves, GAME OVER!") - if(emagged) - usr.death(0) - emagged = 0 - gameStatus = ORION_STATUS_GAMEOVER - event = null - else if(emagged) - if(usr.name == sheriff) - say("The crew of the ship chose to kill [usr.name]!") - usr.death(0) - - if(event == ORION_TRAIL_LING) //only ends the ORION_TRAIL_LING event, since you can do this action in multiple places - event = null - - //Spaceport specific interactions - //they get a header because most of them don't reset event (because it's a shop, you leave when you want to) - //they also call event() again, to regen the eventdata, which is kind of odd but necessary - else if(href_list["buycrew"]) //buy a crewmember - if(gameStatus == ORION_STATUS_MARKET) - if(!spaceport_raided && food >= 10 && fuel >= 10) - var/bought = add_crewmember() - last_spaceport_action = "You hired [bought] as a new crewmember." - fuel -= 10 - food -= 10 - event() - - else if(href_list["sellcrew"]) //sell a crewmember - if(gameStatus == ORION_STATUS_MARKET) - if(!spaceport_raided && settlers.len > 1) - var/sold = remove_crewmember() - last_spaceport_action = "You sold your crewmember, [sold]!" - fuel += 7 - food += 7 - event() - - else if(href_list["leave_spaceport"]) - if(gameStatus == ORION_STATUS_MARKET) - event = null - gameStatus = ORION_STATUS_NORMAL - spaceport_raided = 0 - spaceport_freebie = 0 - last_spaceport_action = "" - - else if(href_list["raid_spaceport"]) - if(gameStatus == ORION_STATUS_MARKET) - if(!spaceport_raided) - var/success = min(15 * alive,100) //default crew (4) have a 60% chance - spaceport_raided = 1 - - var/FU = 0 - var/FO = 0 - if(prob(success)) - FU = rand(5,15) - FO = rand(5,15) - last_spaceport_action = "You successfully raided the spaceport! you gained [FU] Fuel and [FO] Food! (+[FU]FU,+[FO]FO)" - else - FU = rand(-5,-15) - FO = rand(-5,-15) - last_spaceport_action = "You failed to raid the spaceport! you lost [FU*-1] Fuel and [FO*-1] Food in your scramble to escape! ([FU]FU,[FO]FO)" - - //your chance of lose a crewmember is 1/2 your chance of success - //this makes higher % failures hurt more, don't get cocky space cowboy! - if(prob(success*5)) - var/lost_crew = remove_crewmember() - last_spaceport_action = "You failed to raid the spaceport! you lost [FU*-1] Fuel and [FO*-1] Food, AND [lost_crew] in your scramble to escape! ([FU]FI,[FO]FO,-Crew)" - if(emagged) - say("WEEWOO WEEWOO, Spaceport Security en route!") - for(var/i, i<=3, i++) - var/mob/living/simple_animal/hostile/syndicate/ranged/orion/O = new/mob/living/simple_animal/hostile/syndicate/ranged/orion(get_turf(src)) - O.target = usr - - - fuel += FU - food += FO - event() - - else if(href_list["buyparts"]) - if(gameStatus == ORION_STATUS_MARKET) - if(!spaceport_raided && fuel > 5) - switch(text2num(href_list["buyparts"])) - if(1) //Engine Parts - engine++ - last_spaceport_action = "Bought Engine Parts" - if(2) //Hull Plates - hull++ - last_spaceport_action = "Bought Hull Plates" - if(3) //Spare Electronics - electronics++ - last_spaceport_action = "Bought Spare Electronics" - fuel -= 5 //they all cost 5 - event() - - else if(href_list["trade"]) - if(gameStatus == ORION_STATUS_MARKET) - if(!spaceport_raided) - switch(text2num(href_list["trade"])) - if(1) //Fuel - if(fuel > 5) - fuel -= 5 - food += 5 - last_spaceport_action = "Traded Fuel for Food" - event() - if(2) //Food - if(food > 5) - fuel += 5 - food -= 5 - last_spaceport_action = "Traded Food for Fuel" - event() - - src.add_fingerprint(usr) - src.updateUsrDialog() - busy = 0 - return - - -/obj/machinery/computer/arcade/orion_trail/proc/event() - eventdat = "

[event]

" - canContinueEvent = 0 - switch(event) - if(ORION_TRAIL_RAIDERS) - eventdat += "Raiders have come aboard your ship!" - if(prob(50)) - var/sfood = rand(1,10) - var/sfuel = rand(1,10) - food -= sfood - fuel -= sfuel - eventdat += "
They have stolen [sfood] Food and [sfuel] Fuel." - else if(prob(10)) - var/deadname = remove_crewmember() - eventdat += "
[deadname] tried to fight back but was killed." - else - eventdat += "
Fortunately you fended them off without any trouble." - eventdat += "

Continue

" - eventdat += "

Close

" - canContinueEvent = 1 - - if(ORION_TRAIL_FLUX) - eventdat += "This region of space is highly turbulent.
If we go slowly we may avoid more damage, but if we keep our speed we won't waste supplies." - eventdat += "
What will you do?" - eventdat += "

Slow Down Continue

" - eventdat += "

Close

" - - if(ORION_TRAIL_ILLNESS) - eventdat += "A deadly illness has been contracted!" - var/deadname = remove_crewmember() - eventdat += "
[deadname] was killed by the disease." - eventdat += "

Continue

" - eventdat += "

Close

" - canContinueEvent = 1 - - if(ORION_TRAIL_BREAKDOWN) - eventdat += "Oh no! The engine has broken down!" - eventdat += "
You can repair it with an engine part, or you can make repairs for 3 days." - if(engine >= 1) - eventdat += "

Use PartWait

" - else - eventdat += "

Wait

" - eventdat += "

Close

" - - if(ORION_TRAIL_MALFUNCTION) - eventdat += "The ship's systems are malfunctioning!" - eventdat += "
You can replace the broken electronics with spares, or you can spend 3 days troubleshooting the AI." - if(electronics >= 1) - eventdat += "

Use PartWait

" - else - eventdat += "

Wait

" - eventdat += "

Close

" - - if(ORION_TRAIL_COLLISION) - eventdat += "Something hit us! Looks like there's some hull damage." - if(prob(25)) - var/sfood = rand(5,15) - var/sfuel = rand(5,15) - food -= sfood - fuel -= sfuel - eventdat += "
[sfood] Food and [sfuel] Fuel was vented out into space." - if(prob(10)) - var/deadname = remove_crewmember() - eventdat += "
[deadname] was killed by rapid depressurization." - eventdat += "
You can repair the damage with hull plates, or you can spend the next 3 days welding scrap together." - if(hull >= 1) - eventdat += "

Use PartWait

" - else - eventdat += "

Wait

" - eventdat += "

Close

" - - if(ORION_TRAIL_BLACKHOLE) - eventdat += "You were swept away into the black hole." - eventdat += "

Oh...

" - eventdat += "

Close

" - settlers = list() - - if(ORION_TRAIL_LING) - eventdat += "Strange reports warn of changelings infiltrating crews on trips to Orion..." - if(settlers.len <= 2) - eventdat += "
Your crew's chance of reaching Orion is so slim the changelings likely avoided your ship..." - eventdat += "

Continue

" - eventdat += "

Close

" - if(prob(10)) // "likely", I didn't say it was guaranteed! - lings_aboard = min(++lings_aboard,2) - else - if(lings_aboard) //less likely to stack lings - if(prob(20)) - lings_aboard = min(++lings_aboard,2) - else if(prob(70)) - lings_aboard = min(++lings_aboard,2) - - eventdat += "

Kill a crewmember

" - eventdat += "

Risk it

" - eventdat += "

Close

" - canContinueEvent = 1 - - if(ORION_TRAIL_LING_ATTACK) - if(lings_aboard <= 0) //shouldn't trigger, but hey. - eventdat += "Haha, fooled you, there are no changelings on board!" - eventdat += "
(You should report this to a coder :S)" - else - var/ling1 = remove_crewmember() - var/ling2 = "" - if(lings_aboard >= 2) - ling2 = remove_crewmember() - - eventdat += "Oh no, some of your crew are Changelings!" - if(ling2) - eventdat += "
[ling1] and [ling2]'s arms twist and contort into grotesque blades!" - else - eventdat += "
[ling1]'s arm twists and contorts into a grotesque blade!" - - var/chance2attack = alive*20 - if(prob(chance2attack)) - var/chancetokill = 30*lings_aboard-(5*alive) //eg: 30*2-(10) = 50%, 2 lings, 2 crew is 50% chance - if(prob(chancetokill)) - var/deadguy = remove_crewmember() - eventdat += "
The Changeling[ling2 ? "s":""] run[ling2 ? "":"s"] up to [deadguy] and capitulates them!" - else - eventdat += "
You valiantly fight off the Changeling[ling2 ? "s":""]!" - eventdat += "
You cut the Changeling[ling2 ? "s":""] up into meat... Eww" - if(ling2) - food += 30 - lings_aboard = max(0,lings_aboard-2) - else - food += 15 - lings_aboard = max(0,--lings_aboard) - else - eventdat += "
The Changeling[ling2 ? "s":""] run[ling2 ? "":"s"] away, What wimps!" - if(ling2) - lings_aboard = max(0,lings_aboard-2) - else - lings_aboard = max(0,--lings_aboard) - - eventdat += "

Continue

" - eventdat += "

Close

" - canContinueEvent = 1 - - - if(ORION_TRAIL_SPACEPORT) - gameStatus = ORION_STATUS_MARKET - if(spaceport_raided) - eventdat += "The Spaceport is on high alert! they wont let you dock since you tried to attack them!" - if(last_spaceport_action) - eventdat += "
Last Spaceport Action: [last_spaceport_action]" - eventdat += "

Depart Spaceport

" - eventdat += "

Close

" - else - eventdat += "You pull the ship up to dock at a nearby Spaceport, lucky find!" - eventdat += "
This Spaceport is home to travellers who failed to reach Orion, but managed to find a different home..." - eventdat += "
Trading terms: FU = Fuel, FO = Food" - if(last_spaceport_action) - eventdat += "
Last Spaceport Action: [last_spaceport_action]" - eventdat += "

Crew:

" - eventdat += english_list(settlers) - eventdat += "
Food: [food] | Fuel: [fuel]" - eventdat += "
Engine Parts: [engine] | Hull Panels: [hull] | Electronics: [electronics]" - - - //If your crew is pathetic you can get freebies (provided you haven't already gotten one from this port) - if(!spaceport_freebie && (fuel < 20 || food < 20)) - spaceport_freebie++ - var/FU = 10 - var/FO = 10 - var/freecrew = 0 - if(prob(30)) - FU = 25 - FO = 25 - - if(prob(10)) - add_crewmember() - freecrew++ - - eventdat += "
The traders of the spaceport take pitty on you, and give you some food and fuel (+[FU]FU,+[FO]FO)" - if(freecrew) - eventdat += "
You also gain a new crewmember!" - - fuel += FU - food += FO - - //CREW INTERACTIONS - eventdat += "

Crew Management:

" - - //Buy crew - if(food >= 10 && fuel >= 10) - eventdat += "

Hire a new Crewmember (-10FU,-10FO)

" - else - eventdat += "

Cant afford a new Crewmember

" - - //Sell crew - if(settlers.len > 1) - eventdat += "

Sell crew for Fuel and Food (+7FU,+7FO)

" - else - eventdat += "

Cant afford to sell a Crewmember

" - - //BUY/SELL STUFF - eventdat += "

Spare Parts:

" - - //Engine parts - if(fuel > 5) - eventdat += "

Buy Engine Parts (-5FU)

" - else - eventdat += "

Cant afford to buy Engine Parts" - - //Hull plates - if(fuel > 5) - eventdat += "

Buy Hull Plates (-5FU)

" - else - eventdat += "

Cant afford to buy Hull Plates" - - //Electronics - if(fuel > 5) - eventdat += "

Buy Spare Electronics (-5FU)

" - else - eventdat += "

Cant afford to buy Spare Electronics" - - //Trade - if(fuel > 5) - eventdat += "

Trade Fuel for Food (-5FU,+5FO)

" - else - eventdat += "

Cant afford to Trade Fuel for Food 5) - eventdat += "

Trade Food for Fuel (+5FU,-5FO)

" - else - eventdat += "

Cant afford to Trade Food for FuelYou override the cheat code menu and skip to Cheat #[rand(1, 50)]: Realism Mode." - name = "The Orion Trail: Realism Edition" - desc = "Learn how our ancestors got to Orion, and try not to die in the process!" - newgame() - emagged = 1 - -/mob/living/simple_animal/hostile/syndicate/ranged/orion - name = "Spaceport Security" - desc = "The Premier security forces for all spaceports found along the Orion Trail." - faction = list("orion") - loot = list(/obj/effect/mob_spawn/human/corpse/orionsecurity, - /obj/item/weapon/gun/projectile/automatic/c20r/unrestricted, - /obj/item/weapon/shield/energy) - -/obj/effect/mob_spawn/human/corpse/orionsecurity - name = "Spaceport Security" - uniform = /obj/item/clothing/under/syndicate - suit = /obj/item/clothing/suit/armor/vest - shoes = /obj/item/clothing/shoes/combat - gloves = /obj/item/clothing/gloves/combat - radio = /obj/item/device/radio/headset - mask = /obj/item/clothing/mask/gas - helmet = /obj/item/clothing/head/helmet/swat - back = /obj/item/weapon/storage/backpack - has_id = 1 - id_job = "Officer" - id_access = "Syndicate" - -/obj/item/weapon/orion_ship - name = "model settler ship" - desc = "A model spaceship, it looks like those used back in the day when travelling to Orion! It even has a miniature FX-293 reactor, which was renowned for its instability and tendency to explode..." - icon = 'icons/obj/toy.dmi' - icon_state = "ship" - w_class = 2 - var/active = 0 //if the ship is on - -/obj/item/weapon/orion_ship/examine(mob/user) - ..() - if(!(in_range(user, src))) - return - if(!active) - user << "There's a little switch on the bottom. It's flipped down." - else - user << "There's a little switch on the bottom. It's flipped up." - -/obj/item/weapon/orion_ship/attack_self(mob/user) //Minibomb-level explosion. Should probably be more because of how hard it is to survive the machine! Also, just over a 5-second fuse - if(active) - return - - message_admins("[key_name_admin(usr)] primed an explosive Orion ship for detonation.") - log_game("[key_name(usr)] primed an explosive Orion ship for detonation.") - - user << "You flip the switch on the underside of [src]." - active = 1 - src.visible_message("[src] softly beeps and whirs to life!") - playsound(src.loc, 'sound/machines/defib_SaftyOn.ogg', 25, 1) - say("This is ship ID #[rand(1,1000)] to Orion Port Authority. We're coming in for landing, over.") - sleep(20) - src.visible_message("[src] begins to vibrate...") - say("Uh, Port? Having some issues with our reactor, could you check it out? Over.") - sleep(30) - say("Oh, God! Code Eight! CODE EIGHT! IT'S GONNA BL-") - playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 25, 1) - sleep(3.6) - src.visible_message("[src] explodes!") - explosion(src.loc, 2,4,8, flame_range = 16) - qdel(src) - - -#undef ORION_TRAIL_WINTURN -#undef ORION_TRAIL_RAIDERS -#undef ORION_TRAIL_FLUX -#undef ORION_TRAIL_ILLNESS -#undef ORION_TRAIL_BREAKDOWN -#undef ORION_TRAIL_LING -#undef ORION_TRAIL_LING_ATTACK -#undef ORION_TRAIL_MALFUNCTION -#undef ORION_TRAIL_COLLISION -#undef ORION_TRAIL_SPACEPORT -#undef ORION_TRAIL_BLACKHOLE - -#undef ORION_STATUS_START -#undef ORION_STATUS_NORMAL -#undef ORION_STATUS_GAMEOVER -#undef ORION_STATUS_MARKET +/obj/machinery/computer/arcade/ + name = "random arcade" + desc = "random arcade machine" + icon_state = "arcade" + icon_keyboard = null + icon_screen = "invaders" + var/list/prizes = list( /obj/item/weapon/storage/box/snappops = 2, + /obj/item/toy/AI = 2, + /obj/item/toy/codex_gigas = 2, + /obj/item/clothing/under/syndicate/tacticool = 2, + /obj/item/toy/sword = 2, + /obj/item/toy/gun = 2, + /obj/item/weapon/gun/projectile/shotgun/toy/crossbow = 2, + /obj/item/weapon/storage/box/fakesyndiesuit = 2, + /obj/item/weapon/storage/crayons = 2, + /obj/item/toy/spinningtoy = 2, + /obj/item/toy/prize/ripley = 1, + /obj/item/toy/prize/fireripley = 1, + /obj/item/toy/prize/deathripley = 1, + /obj/item/toy/prize/gygax = 1, + /obj/item/toy/prize/durand = 1, + /obj/item/toy/prize/honk = 1, + /obj/item/toy/prize/marauder = 1, + /obj/item/toy/prize/seraph = 1, + /obj/item/toy/prize/mauler = 1, + /obj/item/toy/prize/odysseus = 1, + /obj/item/toy/prize/phazon = 1, + /obj/item/toy/prize/reticence = 1, + /obj/item/toy/cards/deck = 2, + /obj/item/toy/nuke = 2, + /obj/item/toy/minimeteor = 2, + /obj/item/toy/carpplushie = 2, + /obj/item/toy/foamblade = 2, + /obj/item/toy/redbutton = 2, + /obj/item/toy/talking/owl = 2, + /obj/item/toy/talking/griffin = 2, + /obj/item/weapon/coin/antagtoken = 2, + /obj/item/stack/tile/fakespace/loaded = 2, + /obj/item/toy/toy_xeno = 2, + /obj/item/weapon/restraints/handcuffs/fake = 2 + ) + +/obj/machinery/computer/arcade/New() + ..() + // If it's a generic arcade machine, pick a random arcade + // circuit board for it and make the new machine + if(!circuit) + var/choice = pick(subtypesof(/obj/item/weapon/circuitboard/computer/arcade)) + var/obj/item/weapon/circuitboard/CB = new choice() + new CB.build_path(loc, CB) + qdel(src) + +/obj/machinery/computer/arcade/proc/prizevend() + if(prob(0.0001)) //1 in a million + new /obj/item/weapon/gun/energy/pulse(src) + + if(!contents.len) + var/prizeselect = pickweight(prizes) + new prizeselect(src.loc) + + if(istype(prizeselect, /obj/item/toy/gun)) //Ammo comes with the gun + new /obj/item/toy/ammo/gun(src.loc) + + else if(istype(prizeselect, /obj/item/clothing/suit/syndicatefake)) //Helmet is part of the suit + new /obj/item/clothing/head/syndicatefake(src.loc) + + else + var/atom/movable/prize = pick(contents) + prize.loc = src.loc + +/obj/machinery/computer/arcade/emp_act(severity) + ..(severity) + + if(stat & (NOPOWER|BROKEN)) + return + + var/empprize = null + var/num_of_prizes = 0 + switch(severity) + if(1) + num_of_prizes = rand(1,4) + if(2) + num_of_prizes = rand(0,2) + for(var/i = num_of_prizes; i > 0; i--) + empprize = pickweight(prizes) + new empprize(src.loc) + explosion(src.loc, -1, 0, 1+num_of_prizes, flame_range = 1+num_of_prizes) + + +// ** BATTLE ** // + + +/obj/machinery/computer/arcade/battle + name = "arcade machine" + desc = "Does not support Pinball." + icon_state = "arcade" + circuit = /obj/item/weapon/circuitboard/computer/arcade/battle + var/enemy_name = "Space Villian" + var/temp = "Winners don't use space drugs" //Temporary message, for attack messages, etc + var/player_hp = 30 //Player health/attack points + var/player_mp = 10 + var/enemy_hp = 45 //Enemy health/attack points + var/enemy_mp = 20 + var/gameover = 0 + var/blocked = 0 //Player cannot attack/heal while set + var/turtle = 0 + +/obj/machinery/computer/arcade/battle/New() + ..() + var/name_action + var/name_part1 + var/name_part2 + + name_action = pick("Defeat ", "Annihilate ", "Save ", "Strike ", "Stop ", "Destroy ", "Robust ", "Romance ", "Pwn ", "Own ", "Ban ") + + name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Cuban ", "the Evil ", "the Dread King ", "the Space ", "Lord ", "the Great ", "Duke ", "General ") + name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "slime", "Griefer", "ERPer", "Lizard Man", "Unicorn", "Bloopers") + + src.enemy_name = replacetext((name_part1 + name_part2), "the ", "") + src.name = (name_action + name_part1 + name_part2) + +/obj/machinery/computer/arcade/battle/attack_hand(mob/user) + if(..()) + return + user.set_machine(src) + var/dat = "Close" + dat += "

[src.enemy_name]

" + + dat += "

[src.temp]

" + dat += "
Health: [src.player_hp] | Magic: [src.player_mp] | Enemy Health: [src.enemy_hp]
" + + if (src.gameover) + dat += "
New Game" + else + dat += "
Attack | " + dat += "Heal | " + dat += "Recharge Power" + + dat += "
" + + //user << browse(dat, "window=arcade") + //onclose(user, "arcade") + var/datum/browser/popup = new(user, "arcade", "Space Villian 2000") + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + return + +/obj/machinery/computer/arcade/battle/Topic(href, href_list) + if(..()) + return + + if (!src.blocked && !src.gameover) + if (href_list["attack"]) + src.blocked = 1 + var/attackamt = rand(2,6) + src.temp = "You attack for [attackamt] damage!" + playsound(src.loc, 'sound/arcade/Hit.ogg', 50, 1, extrarange = -3, falloff = 10) + src.updateUsrDialog() + if(turtle > 0) + turtle-- + + sleep(10) + src.enemy_hp -= attackamt + src.arcade_action() + + else if (href_list["heal"]) + src.blocked = 1 + var/pointamt = rand(1,3) + var/healamt = rand(6,8) + src.temp = "You use [pointamt] magic to heal for [healamt] damage!" + playsound(src.loc, 'sound/arcade/Heal.ogg', 50, 1, extrarange = -3, falloff = 10) + src.updateUsrDialog() + turtle++ + + sleep(10) + src.player_mp -= pointamt + src.player_hp += healamt + src.blocked = 1 + src.updateUsrDialog() + src.arcade_action() + + else if (href_list["charge"]) + src.blocked = 1 + var/chargeamt = rand(4,7) + src.temp = "You regain [chargeamt] points" + playsound(src.loc, 'sound/arcade/Mana.ogg', 50, 1, extrarange = -3, falloff = 10) + src.player_mp += chargeamt + if(turtle > 0) + turtle-- + + src.updateUsrDialog() + sleep(10) + src.arcade_action() + + if (href_list["close"]) + usr.unset_machine() + usr << browse(null, "window=arcade") + + else if (href_list["newgame"]) //Reset everything + temp = "New Round" + player_hp = 30 + player_mp = 10 + enemy_hp = 45 + enemy_mp = 20 + gameover = 0 + turtle = 0 + + if(emagged) + src.New() + emagged = 0 + + src.add_fingerprint(usr) + src.updateUsrDialog() + return + +/obj/machinery/computer/arcade/battle/proc/arcade_action() + if ((src.enemy_mp <= 0) || (src.enemy_hp <= 0)) + if(!gameover) + src.gameover = 1 + src.temp = "[src.enemy_name] has fallen! Rejoice!" + playsound(src.loc, 'sound/arcade/Win.ogg', 50, 1, extrarange = -3, falloff = 10) + + if(emagged) + feedback_inc("arcade_win_emagged") + new /obj/effect/spawner/newbomb/timer/syndicate(src.loc) + new /obj/item/clothing/head/collectable/petehat(src.loc) + message_admins("[key_name_admin(usr)] has outbombed Cuban Pete and been awarded a bomb.") + log_game("[key_name(usr)] has outbombed Cuban Pete and been awarded a bomb.") + src.New() + emagged = 0 + else + feedback_inc("arcade_win_normal") + prizevend() + + else if (emagged && (turtle >= 4)) + var/boomamt = rand(5,10) + src.temp = "[src.enemy_name] throws a bomb, exploding you for [boomamt] damage!" + playsound(src.loc, 'sound/arcade/Boom.ogg', 50, 1, extrarange = -3, falloff = 10) + src.player_hp -= boomamt + + else if ((src.enemy_mp <= 5) && (prob(70))) + var/stealamt = rand(2,3) + src.temp = "[src.enemy_name] steals [stealamt] of your power!" + playsound(src.loc, 'sound/arcade/Steal.ogg', 50, 1, extrarange = -3, falloff = 10) + src.player_mp -= stealamt + src.updateUsrDialog() + + if (src.player_mp <= 0) + src.gameover = 1 + sleep(10) + src.temp = "You have been drained! GAME OVER" + playsound(src.loc, 'sound/arcade/Lose.ogg', 50, 1, extrarange = -3, falloff = 10) + if(emagged) + feedback_inc("arcade_loss_mana_emagged") + usr.gib() + else + feedback_inc("arcade_loss_mana_normal") + + else if ((src.enemy_hp <= 10) && (src.enemy_mp > 4)) + src.temp = "[src.enemy_name] heals for 4 health!" + playsound(src.loc, 'sound/arcade/Heal.ogg', 50, 1, extrarange = -3, falloff = 10) + src.enemy_hp += 4 + src.enemy_mp -= 4 + + else + var/attackamt = rand(3,6) + src.temp = "[src.enemy_name] attacks for [attackamt] damage!" + playsound(src.loc, 'sound/arcade/Hit.ogg', 50, 1, extrarange = -3, falloff = 10) + src.player_hp -= attackamt + + if ((src.player_mp <= 0) || (src.player_hp <= 0)) + src.gameover = 1 + src.temp = "You have been crushed! GAME OVER" + playsound(src.loc, 'sound/arcade/Lose.ogg', 50, 1, extrarange = -3, falloff = 10) + if(emagged) + feedback_inc("arcade_loss_hp_emagged") + usr.gib() + else + feedback_inc("arcade_loss_hp_normal") + + src.blocked = 0 + return + + +/obj/machinery/computer/arcade/battle/emag_act(mob/user) + if(!emagged) + temp = "If you die in the game, you die for real!" + player_hp = 30 + player_mp = 10 + enemy_hp = 45 + enemy_mp = 20 + gameover = 0 + blocked = 0 + + emagged = 1 + + enemy_name = "Cuban Pete" + name = "Outbomb Cuban Pete" + + + src.updateUsrDialog() + + + +// *** THE ORION TRAIL ** // + +#define ORION_TRAIL_WINTURN 9 + +//Orion Trail Events +#define ORION_TRAIL_RAIDERS "Raiders" +#define ORION_TRAIL_FLUX "Interstellar Flux" +#define ORION_TRAIL_ILLNESS "Illness" +#define ORION_TRAIL_BREAKDOWN "Breakdown" +#define ORION_TRAIL_LING "Changelings?" +#define ORION_TRAIL_LING_ATTACK "Changeling Ambush" +#define ORION_TRAIL_MALFUNCTION "Malfunction" +#define ORION_TRAIL_COLLISION "Collision" +#define ORION_TRAIL_SPACEPORT "Spaceport" +#define ORION_TRAIL_BLACKHOLE "BlackHole" + +#define ORION_STATUS_START 1 +#define ORION_STATUS_NORMAL 2 +#define ORION_STATUS_GAMEOVER 3 +#define ORION_STATUS_MARKET 4 + +/obj/machinery/computer/arcade/orion_trail + name = "The Orion Trail" + desc = "Learn how our ancestors got to Orion, and have fun in the process!" + icon_state = "arcade" + circuit = /obj/item/weapon/circuitboard/computer/arcade/orion_trail + var/busy = 0 //prevent clickspam that allowed people to ~speedrun~ the game. + var/engine = 0 + var/hull = 0 + var/electronics = 0 + var/food = 80 + var/fuel = 60 + var/turns = 4 + var/alive = 4 + var/eventdat = null + var/event = null + var/list/settlers = list("Harry","Larry","Bob") + var/list/events = list(ORION_TRAIL_RAIDERS = 3, + ORION_TRAIL_FLUX = 1, + ORION_TRAIL_ILLNESS = 3, + ORION_TRAIL_BREAKDOWN = 2, + ORION_TRAIL_LING = 3, + ORION_TRAIL_MALFUNCTION = 2, + ORION_TRAIL_COLLISION = 1, + ORION_TRAIL_SPACEPORT = 2 + ) + var/list/stops = list() + var/list/stopblurbs = list() + var/lings_aboard = 0 + var/spaceport_raided = 0 + var/spaceport_freebie = 0 + var/last_spaceport_action = "" + var/gameStatus = ORION_STATUS_START + var/canContinueEvent = 0 + +/obj/machinery/computer/arcade/orion_trail/New() + ..() + // Sets up the main trail + stops = list("Pluto","Asteroid Belt","Proxima Centauri","Dead Space","Rigel Prime","Tau Ceti Beta","Black Hole","Space Outpost Beta-9","Orion Prime") + stopblurbs = list( + "Pluto, long since occupied with long-range sensors and scanners, stands ready to, and indeed continues to probe the far reaches of the galaxy.", + "At the edge of the Sol system lies a treacherous asteroid belt. Many have been crushed by stray asteroids and misguided judgement.", + "The nearest star system to Sol, in ages past it stood as a reminder of the boundaries of sub-light travel, now a low-population sanctuary for adventurers and traders.", + "This region of space is particularly devoid of matter. Such low-density pockets are known to exist, but the vastness of it is astounding.", + "Rigel Prime, the center of the Rigel system, burns hot, basking its planetary bodies in warmth and radiation.", + "Tau Ceti Beta has recently become a waypoint for colonists headed towards Orion. There are many ships and makeshift stations in the vicinity.", + "Sensors indicate that a black hole's gravitational field is affecting the region of space we were headed through. We could stay of course, but risk of being overcome by its gravity, or we could change course to go around, which will take longer.", + "You have come into range of the first man-made structure in this region of space. It has been constructed not by travellers from Sol, but by colonists from Orion. It stands as a monument to the colonists' success.", + "You have made it to Orion! Congratulations! Your crew is one of the few to start a new foothold for mankind!" + ) + +/obj/machinery/computer/arcade/orion_trail/proc/newgame() + // Set names of settlers in crew + settlers = list() + for(var/i = 1; i <= 3; i++) + add_crewmember() + add_crewmember("[usr]") + // Re-set items to defaults + engine = 1 + hull = 1 + electronics = 1 + food = 80 + fuel = 60 + alive = 4 + turns = 1 + event = null + gameStatus = ORION_STATUS_NORMAL + lings_aboard = 0 + + //spaceport junk + spaceport_raided = 0 + spaceport_freebie = 0 + last_spaceport_action = "" + +/obj/machinery/computer/arcade/orion_trail/attack_hand(mob/user) + if(..()) + return + if(fuel <= 0 || food <=0 || settlers.len == 0) + gameStatus = ORION_STATUS_GAMEOVER + event = null + user.set_machine(src) + var/dat = "" + if(gameStatus == ORION_STATUS_GAMEOVER) + dat = "

Game Over

" + dat += "Like many before you, your crew never made it to Orion, lost to space...
Forever." + if(settlers.len == 0) + dat += "
Your entire crew died, your ship joins the fleet of ghost-ships littering the galaxy." + else + if(food <= 0) + dat += "
You ran out of food and starved." + if(emagged) + user.nutrition = 0 //yeah you pretty hongry + user << "Your body instantly contracts to that of one who has not eaten in months. Agonizing cramps seize you as you fall to the floor." + if(fuel <= 0) + dat += "
You ran out of fuel, and drift, slowly, into a star." + if(emagged) + var/mob/living/M = user + M.adjust_fire_stacks(5) + M.IgniteMob() //flew into a star, so you're on fire + user << "You feel an immense wave of heat emanate from the arcade machine. Your skin bursts into flames." + dat += "

OK...

" + + if(emagged) + user << "You're never going to make it to Orion..." + user.death() + emagged = 0 //removes the emagged status after you lose + gameStatus = ORION_STATUS_START + name = "The Orion Trail" + desc = "Learn how our ancestors got to Orion, and have fun in the process!" + + else if(event) + dat = eventdat + else if(gameStatus == ORION_STATUS_NORMAL) + var/title = stops[turns] + var/subtext = stopblurbs[turns] + dat = "

[title]

" + dat += "[subtext]" + dat += "

Crew:

" + dat += english_list(settlers) + dat += "
Food: [food] | Fuel: [fuel]" + dat += "
Engine Parts: [engine] | Hull Panels: [hull] | Electronics: [electronics]" + if(turns == 7) + dat += "

Go Around Continue

" + else + dat += "

Continue

" + dat += "

Kill a crewmember

" + dat += "

Close

" + else + dat = "

The Orion Trail

" + dat += "

Experience the journey of your ancestors!



" + dat += "
New Game
" + dat += "

Close

" + var/datum/browser/popup = new(user, "arcade", "The Orion Trail",400,700) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + return + +/obj/machinery/computer/arcade/orion_trail/Topic(href, href_list) + if(..()) + return + if(href_list["close"]) + usr.unset_machine() + usr << browse(null, "window=arcade") + + if(busy) + return + busy = 1 + + if (href_list["continue"]) //Continue your travels + if(gameStatus == ORION_STATUS_NORMAL && !event && turns != 7) + if(turns >= ORION_TRAIL_WINTURN) + win() + else + food -= (alive+lings_aboard)*2 + fuel -= 5 + if(turns == 2 && prob(30)) + event = ORION_TRAIL_COLLISION + event() + else if(prob(75)) + event = pickweight(events) + if(lings_aboard) + if(event == ORION_TRAIL_LING || prob(55)) + event = ORION_TRAIL_LING_ATTACK + event() + turns += 1 + if(emagged) + var/mob/living/carbon/M = usr //for some vars + switch(event) + if(ORION_TRAIL_RAIDERS) + if(prob(50)) + usr << "You hear battle shouts. The tramping of boots on cold metal. Screams of agony. The rush of venting air. Are you going insane?" + M.hallucination += 30 + else + usr << "Something strikes you from behind! It hurts like hell and feel like a blunt weapon, but nothing is there..." + M.take_organ_damage(30) + playsound(loc, 'sound/weapons/genhit2.ogg', 100, 1) + if(ORION_TRAIL_ILLNESS) + var/severity = rand(1,3) //pray to RNGesus. PRAY, PIGS + if(severity == 1) + M << "You suddenly feel slightly nauseous." //got off lucky + if(severity == 2) + usr << "You suddenly feel extremely nauseous and hunch over until it passes." + M.Stun(3) + if(severity >= 3) //you didn't pray hard enough + M << "An overpowering wave of nausea consumes over you. You hunch over, your stomach's contents preparing for a spectacular exit." + M.Stun(5) + sleep(30) + M.vomit(50) + if(ORION_TRAIL_FLUX) + if(prob(75)) + M.Weaken(3) + say("A sudden gust of powerful wind slams [M] into the floor!") + M.take_organ_damage(25) + playsound(src.loc, 'sound/weapons/Genhit.ogg', 100, 1) + else + M << "A violent gale blows past you, and you barely manage to stay standing!" + if(ORION_TRAIL_COLLISION) //by far the most damaging event + if(prob(90)) + playsound(src.loc, 'sound/effects/bang.ogg', 100, 1) + var/turf/open/floor/F + for(F in orange(1, src)) + F.ChangeTurf(F.baseturf) + say("Something slams into the floor around [src], exposing it to space!") + if(hull) + sleep(10) + say("A new floor suddenly appears around [src]. What the hell?") + playsound(src.loc, 'sound/weapons/Genhit.ogg', 100, 1) + var/turf/open/space/T + for(T in orange(1, src)) + T.ChangeTurf(/turf/open/floor/plating/) + else + say("Something slams into the floor around [src] - luckily, it didn't get through!") + playsound(src.loc, 'sound/effects/bang.ogg', 50, 1) + if(ORION_TRAIL_MALFUNCTION) + playsound(src.loc, 'sound/effects/EMPulse.ogg', 50, 1) + src.visible_message("[src] malfunctions, randomizing in-game stats!") + var/oldfood = food + var/oldfuel = fuel + food = rand(10,80) / rand(1,2) + fuel = rand(10,60) / rand(1,2) + if(electronics) + sleep(10) + if(oldfuel > fuel && oldfood > food) + src.audible_message("[src] lets out a somehow reassuring chime.") + else if(oldfuel < fuel || oldfood < food) + src.audible_message("[src] lets out a somehow ominous chime.") + food = oldfood + fuel = oldfuel + playsound(src.loc, 'sound/machines/chime.ogg', 50, 1) + + else if(href_list["newgame"]) //Reset everything + if(gameStatus == ORION_STATUS_START) + newgame() + else if(href_list["menu"]) //back to the main menu + if(gameStatus == ORION_STATUS_GAMEOVER) + gameStatus = ORION_STATUS_START + event = null + food = 80 + fuel = 60 + settlers = list("Harry","Larry","Bob") + else if(href_list["slow"]) //slow down + if(event == ORION_TRAIL_FLUX) + food -= (alive+lings_aboard)*2 + fuel -= 5 + event = null + else if(href_list["pastblack"]) //slow down + if(turns == 7) + food -= ((alive+lings_aboard)*2)*3 + fuel -= 15 + turns += 1 + event = null + else if(href_list["useengine"]) //use parts + if(event == ORION_TRAIL_BREAKDOWN) + engine = max(0, --engine) + event = null + else if(href_list["useelec"]) //use parts + if(event == ORION_TRAIL_MALFUNCTION) + electronics = max(0, --electronics) + event = null + else if(href_list["usehull"]) //use parts + if(event == ORION_TRAIL_COLLISION) + hull = max(0, --hull) + event = null + else if(href_list["wait"]) //wait 3 days + if(event == ORION_TRAIL_BREAKDOWN || event == ORION_TRAIL_MALFUNCTION || event == ORION_TRAIL_COLLISION) + food -= ((alive+lings_aboard)*2)*3 + event = null + else if(href_list["keepspeed"]) //keep speed + if(event == ORION_TRAIL_FLUX) + if(prob(75)) + event = "Breakdown" + event() + else + event = null + else if(href_list["blackhole"]) //keep speed past a black hole + if(turns == 7) + if(prob(75)) + event = ORION_TRAIL_BLACKHOLE + event() + if(emagged) //has to be here because otherwise it doesn't work + playsound(src.loc, 'sound/effects/supermatter.ogg', 100, 1) + say("A miniature black hole suddenly appears in front of [src], devouring [usr] alive!") + usr.Stun(10) //you can't run :^) + var/S = new /obj/singularity/academy(usr.loc) + emagged = 0 //immediately removes emagged status so people can't kill themselves by sprinting up and interacting + sleep(50) + say("[S] winks out, just as suddenly as it appeared.") + qdel(S) + else + event = null + turns += 1 + else if(href_list["holedeath"]) + if(event == ORION_TRAIL_BLACKHOLE) + gameStatus = ORION_STATUS_GAMEOVER + event = null + else if(href_list["eventclose"]) //end an event + if(canContinueEvent) + event = null + + else if(href_list["killcrew"]) //shoot a crewmember + if(gameStatus == ORION_STATUS_NORMAL || event == ORION_TRAIL_LING) + var/sheriff = remove_crewmember() //I shot the sheriff + playsound(loc,'sound/weapons/Gunshot.ogg', 100, 1) + + if(settlers.len == 0 || alive == 0) + say("The last crewmember [sheriff], shot themselves, GAME OVER!") + if(emagged) + usr.death(0) + emagged = 0 + gameStatus = ORION_STATUS_GAMEOVER + event = null + else if(emagged) + if(usr.name == sheriff) + say("The crew of the ship chose to kill [usr.name]!") + usr.death(0) + + if(event == ORION_TRAIL_LING) //only ends the ORION_TRAIL_LING event, since you can do this action in multiple places + event = null + + //Spaceport specific interactions + //they get a header because most of them don't reset event (because it's a shop, you leave when you want to) + //they also call event() again, to regen the eventdata, which is kind of odd but necessary + else if(href_list["buycrew"]) //buy a crewmember + if(gameStatus == ORION_STATUS_MARKET) + if(!spaceport_raided && food >= 10 && fuel >= 10) + var/bought = add_crewmember() + last_spaceport_action = "You hired [bought] as a new crewmember." + fuel -= 10 + food -= 10 + event() + + else if(href_list["sellcrew"]) //sell a crewmember + if(gameStatus == ORION_STATUS_MARKET) + if(!spaceport_raided && settlers.len > 1) + var/sold = remove_crewmember() + last_spaceport_action = "You sold your crewmember, [sold]!" + fuel += 7 + food += 7 + event() + + else if(href_list["leave_spaceport"]) + if(gameStatus == ORION_STATUS_MARKET) + event = null + gameStatus = ORION_STATUS_NORMAL + spaceport_raided = 0 + spaceport_freebie = 0 + last_spaceport_action = "" + + else if(href_list["raid_spaceport"]) + if(gameStatus == ORION_STATUS_MARKET) + if(!spaceport_raided) + var/success = min(15 * alive,100) //default crew (4) have a 60% chance + spaceport_raided = 1 + + var/FU = 0 + var/FO = 0 + if(prob(success)) + FU = rand(5,15) + FO = rand(5,15) + last_spaceport_action = "You successfully raided the spaceport! you gained [FU] Fuel and [FO] Food! (+[FU]FU,+[FO]FO)" + else + FU = rand(-5,-15) + FO = rand(-5,-15) + last_spaceport_action = "You failed to raid the spaceport! you lost [FU*-1] Fuel and [FO*-1] Food in your scramble to escape! ([FU]FU,[FO]FO)" + + //your chance of lose a crewmember is 1/2 your chance of success + //this makes higher % failures hurt more, don't get cocky space cowboy! + if(prob(success*5)) + var/lost_crew = remove_crewmember() + last_spaceport_action = "You failed to raid the spaceport! you lost [FU*-1] Fuel and [FO*-1] Food, AND [lost_crew] in your scramble to escape! ([FU]FI,[FO]FO,-Crew)" + if(emagged) + say("WEEWOO WEEWOO, Spaceport Security en route!") + for(var/i, i<=3, i++) + var/mob/living/simple_animal/hostile/syndicate/ranged/orion/O = new/mob/living/simple_animal/hostile/syndicate/ranged/orion(get_turf(src)) + O.target = usr + + + fuel += FU + food += FO + event() + + else if(href_list["buyparts"]) + if(gameStatus == ORION_STATUS_MARKET) + if(!spaceport_raided && fuel > 5) + switch(text2num(href_list["buyparts"])) + if(1) //Engine Parts + engine++ + last_spaceport_action = "Bought Engine Parts" + if(2) //Hull Plates + hull++ + last_spaceport_action = "Bought Hull Plates" + if(3) //Spare Electronics + electronics++ + last_spaceport_action = "Bought Spare Electronics" + fuel -= 5 //they all cost 5 + event() + + else if(href_list["trade"]) + if(gameStatus == ORION_STATUS_MARKET) + if(!spaceport_raided) + switch(text2num(href_list["trade"])) + if(1) //Fuel + if(fuel > 5) + fuel -= 5 + food += 5 + last_spaceport_action = "Traded Fuel for Food" + event() + if(2) //Food + if(food > 5) + fuel += 5 + food -= 5 + last_spaceport_action = "Traded Food for Fuel" + event() + + src.add_fingerprint(usr) + src.updateUsrDialog() + busy = 0 + return + + +/obj/machinery/computer/arcade/orion_trail/proc/event() + eventdat = "

[event]

" + canContinueEvent = 0 + switch(event) + if(ORION_TRAIL_RAIDERS) + eventdat += "Raiders have come aboard your ship!" + if(prob(50)) + var/sfood = rand(1,10) + var/sfuel = rand(1,10) + food -= sfood + fuel -= sfuel + eventdat += "
They have stolen [sfood] Food and [sfuel] Fuel." + else if(prob(10)) + var/deadname = remove_crewmember() + eventdat += "
[deadname] tried to fight back but was killed." + else + eventdat += "
Fortunately you fended them off without any trouble." + eventdat += "

Continue

" + eventdat += "

Close

" + canContinueEvent = 1 + + if(ORION_TRAIL_FLUX) + eventdat += "This region of space is highly turbulent.
If we go slowly we may avoid more damage, but if we keep our speed we won't waste supplies." + eventdat += "
What will you do?" + eventdat += "

Slow Down Continue

" + eventdat += "

Close

" + + if(ORION_TRAIL_ILLNESS) + eventdat += "A deadly illness has been contracted!" + var/deadname = remove_crewmember() + eventdat += "
[deadname] was killed by the disease." + eventdat += "

Continue

" + eventdat += "

Close

" + canContinueEvent = 1 + + if(ORION_TRAIL_BREAKDOWN) + eventdat += "Oh no! The engine has broken down!" + eventdat += "
You can repair it with an engine part, or you can make repairs for 3 days." + if(engine >= 1) + eventdat += "

Use PartWait

" + else + eventdat += "

Wait

" + eventdat += "

Close

" + + if(ORION_TRAIL_MALFUNCTION) + eventdat += "The ship's systems are malfunctioning!" + eventdat += "
You can replace the broken electronics with spares, or you can spend 3 days troubleshooting the AI." + if(electronics >= 1) + eventdat += "

Use PartWait

" + else + eventdat += "

Wait

" + eventdat += "

Close

" + + if(ORION_TRAIL_COLLISION) + eventdat += "Something hit us! Looks like there's some hull damage." + if(prob(25)) + var/sfood = rand(5,15) + var/sfuel = rand(5,15) + food -= sfood + fuel -= sfuel + eventdat += "
[sfood] Food and [sfuel] Fuel was vented out into space." + if(prob(10)) + var/deadname = remove_crewmember() + eventdat += "
[deadname] was killed by rapid depressurization." + eventdat += "
You can repair the damage with hull plates, or you can spend the next 3 days welding scrap together." + if(hull >= 1) + eventdat += "

Use PartWait

" + else + eventdat += "

Wait

" + eventdat += "

Close

" + + if(ORION_TRAIL_BLACKHOLE) + eventdat += "You were swept away into the black hole." + eventdat += "

Oh...

" + eventdat += "

Close

" + settlers = list() + + if(ORION_TRAIL_LING) + eventdat += "Strange reports warn of changelings infiltrating crews on trips to Orion..." + if(settlers.len <= 2) + eventdat += "
Your crew's chance of reaching Orion is so slim the changelings likely avoided your ship..." + eventdat += "

Continue

" + eventdat += "

Close

" + if(prob(10)) // "likely", I didn't say it was guaranteed! + lings_aboard = min(++lings_aboard,2) + else + if(lings_aboard) //less likely to stack lings + if(prob(20)) + lings_aboard = min(++lings_aboard,2) + else if(prob(70)) + lings_aboard = min(++lings_aboard,2) + + eventdat += "

Kill a crewmember

" + eventdat += "

Risk it

" + eventdat += "

Close

" + canContinueEvent = 1 + + if(ORION_TRAIL_LING_ATTACK) + if(lings_aboard <= 0) //shouldn't trigger, but hey. + eventdat += "Haha, fooled you, there are no changelings on board!" + eventdat += "
(You should report this to a coder :S)" + else + var/ling1 = remove_crewmember() + var/ling2 = "" + if(lings_aboard >= 2) + ling2 = remove_crewmember() + + eventdat += "Oh no, some of your crew are Changelings!" + if(ling2) + eventdat += "
[ling1] and [ling2]'s arms twist and contort into grotesque blades!" + else + eventdat += "
[ling1]'s arm twists and contorts into a grotesque blade!" + + var/chance2attack = alive*20 + if(prob(chance2attack)) + var/chancetokill = 30*lings_aboard-(5*alive) //eg: 30*2-(10) = 50%, 2 lings, 2 crew is 50% chance + if(prob(chancetokill)) + var/deadguy = remove_crewmember() + eventdat += "
The Changeling[ling2 ? "s":""] run[ling2 ? "":"s"] up to [deadguy] and capitulates them!" + else + eventdat += "
You valiantly fight off the Changeling[ling2 ? "s":""]!" + eventdat += "
You cut the Changeling[ling2 ? "s":""] up into meat... Eww" + if(ling2) + food += 30 + lings_aboard = max(0,lings_aboard-2) + else + food += 15 + lings_aboard = max(0,--lings_aboard) + else + eventdat += "
The Changeling[ling2 ? "s":""] run[ling2 ? "":"s"] away, What wimps!" + if(ling2) + lings_aboard = max(0,lings_aboard-2) + else + lings_aboard = max(0,--lings_aboard) + + eventdat += "

Continue

" + eventdat += "

Close

" + canContinueEvent = 1 + + + if(ORION_TRAIL_SPACEPORT) + gameStatus = ORION_STATUS_MARKET + if(spaceport_raided) + eventdat += "The Spaceport is on high alert! they wont let you dock since you tried to attack them!" + if(last_spaceport_action) + eventdat += "
Last Spaceport Action: [last_spaceport_action]" + eventdat += "

Depart Spaceport

" + eventdat += "

Close

" + else + eventdat += "You pull the ship up to dock at a nearby Spaceport, lucky find!" + eventdat += "
This Spaceport is home to travellers who failed to reach Orion, but managed to find a different home..." + eventdat += "
Trading terms: FU = Fuel, FO = Food" + if(last_spaceport_action) + eventdat += "
Last Spaceport Action: [last_spaceport_action]" + eventdat += "

Crew:

" + eventdat += english_list(settlers) + eventdat += "
Food: [food] | Fuel: [fuel]" + eventdat += "
Engine Parts: [engine] | Hull Panels: [hull] | Electronics: [electronics]" + + + //If your crew is pathetic you can get freebies (provided you haven't already gotten one from this port) + if(!spaceport_freebie && (fuel < 20 || food < 20)) + spaceport_freebie++ + var/FU = 10 + var/FO = 10 + var/freecrew = 0 + if(prob(30)) + FU = 25 + FO = 25 + + if(prob(10)) + add_crewmember() + freecrew++ + + eventdat += "
The traders of the spaceport take pitty on you, and give you some food and fuel (+[FU]FU,+[FO]FO)" + if(freecrew) + eventdat += "
You also gain a new crewmember!" + + fuel += FU + food += FO + + //CREW INTERACTIONS + eventdat += "

Crew Management:

" + + //Buy crew + if(food >= 10 && fuel >= 10) + eventdat += "

Hire a new Crewmember (-10FU,-10FO)

" + else + eventdat += "

Cant afford a new Crewmember

" + + //Sell crew + if(settlers.len > 1) + eventdat += "

Sell crew for Fuel and Food (+7FU,+7FO)

" + else + eventdat += "

Cant afford to sell a Crewmember

" + + //BUY/SELL STUFF + eventdat += "

Spare Parts:

" + + //Engine parts + if(fuel > 5) + eventdat += "

Buy Engine Parts (-5FU)

" + else + eventdat += "

Cant afford to buy Engine Parts" + + //Hull plates + if(fuel > 5) + eventdat += "

Buy Hull Plates (-5FU)

" + else + eventdat += "

Cant afford to buy Hull Plates" + + //Electronics + if(fuel > 5) + eventdat += "

Buy Spare Electronics (-5FU)

" + else + eventdat += "

Cant afford to buy Spare Electronics" + + //Trade + if(fuel > 5) + eventdat += "

Trade Fuel for Food (-5FU,+5FO)

" + else + eventdat += "

Cant afford to Trade Fuel for Food 5) + eventdat += "

Trade Food for Fuel (+5FU,-5FO)

" + else + eventdat += "

Cant afford to Trade Food for FuelYou override the cheat code menu and skip to Cheat #[rand(1, 50)]: Realism Mode." + name = "The Orion Trail: Realism Edition" + desc = "Learn how our ancestors got to Orion, and try not to die in the process!" + newgame() + emagged = 1 + +/mob/living/simple_animal/hostile/syndicate/ranged/orion + name = "Spaceport Security" + desc = "The Premier security forces for all spaceports found along the Orion Trail." + faction = list("orion") + loot = list(/obj/effect/mob_spawn/human/corpse/orionsecurity, + /obj/item/weapon/gun/projectile/automatic/c20r/unrestricted, + /obj/item/weapon/shield/energy) + +/obj/effect/mob_spawn/human/corpse/orionsecurity + name = "Spaceport Security" + uniform = /obj/item/clothing/under/syndicate + suit = /obj/item/clothing/suit/armor/vest + shoes = /obj/item/clothing/shoes/combat + gloves = /obj/item/clothing/gloves/combat + radio = /obj/item/device/radio/headset + mask = /obj/item/clothing/mask/gas + helmet = /obj/item/clothing/head/helmet/swat + back = /obj/item/weapon/storage/backpack + has_id = 1 + id_job = "Officer" + id_access = "Syndicate" + +/obj/item/weapon/orion_ship + name = "model settler ship" + desc = "A model spaceship, it looks like those used back in the day when travelling to Orion! It even has a miniature FX-293 reactor, which was renowned for its instability and tendency to explode..." + icon = 'icons/obj/toy.dmi' + icon_state = "ship" + w_class = 2 + var/active = 0 //if the ship is on + +/obj/item/weapon/orion_ship/examine(mob/user) + ..() + if(!(in_range(user, src))) + return + if(!active) + user << "There's a little switch on the bottom. It's flipped down." + else + user << "There's a little switch on the bottom. It's flipped up." + +/obj/item/weapon/orion_ship/attack_self(mob/user) //Minibomb-level explosion. Should probably be more because of how hard it is to survive the machine! Also, just over a 5-second fuse + if(active) + return + + message_admins("[key_name_admin(usr)] primed an explosive Orion ship for detonation.") + log_game("[key_name(usr)] primed an explosive Orion ship for detonation.") + + user << "You flip the switch on the underside of [src]." + active = 1 + src.visible_message("[src] softly beeps and whirs to life!") + playsound(src.loc, 'sound/machines/defib_SaftyOn.ogg', 25, 1) + say("This is ship ID #[rand(1,1000)] to Orion Port Authority. We're coming in for landing, over.") + sleep(20) + src.visible_message("[src] begins to vibrate...") + say("Uh, Port? Having some issues with our reactor, could you check it out? Over.") + sleep(30) + say("Oh, God! Code Eight! CODE EIGHT! IT'S GONNA BL-") + playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 25, 1) + sleep(3.6) + src.visible_message("[src] explodes!") + explosion(src.loc, 2,4,8, flame_range = 16) + qdel(src) + + +#undef ORION_TRAIL_WINTURN +#undef ORION_TRAIL_RAIDERS +#undef ORION_TRAIL_FLUX +#undef ORION_TRAIL_ILLNESS +#undef ORION_TRAIL_BREAKDOWN +#undef ORION_TRAIL_LING +#undef ORION_TRAIL_LING_ATTACK +#undef ORION_TRAIL_MALFUNCTION +#undef ORION_TRAIL_COLLISION +#undef ORION_TRAIL_SPACEPORT +#undef ORION_TRAIL_BLACKHOLE + +#undef ORION_STATUS_START +#undef ORION_STATUS_NORMAL +#undef ORION_STATUS_GAMEOVER +#undef ORION_STATUS_MARKET diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index dc0b949a187..f6011552816 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -356,7 +356,7 @@ if (!subject.getorgan(/obj/item/organ/brain)) scantemp = "No signs of intelligence detected." return - if (subject.suiciding == 1) + if (subject.suiciding == 1 || subject.hellbound) scantemp = "Subject's brain is not responding to scanning stimuli." return if ((subject.disabilities & NOCLONE) && (src.scanner.scan_level < 2)) diff --git a/code/game/machinery/dna_scanner.dm b/code/game/machinery/dna_scanner.dm index 192ff9df7d1..45f7b995486 100644 --- a/code/game/machinery/dna_scanner.dm +++ b/code/game/machinery/dna_scanner.dm @@ -111,7 +111,7 @@ || locate(/obj/machinery/computer/cloning, get_step(src, SOUTH)) \ || locate(/obj/machinery/computer/cloning, get_step(src, EAST)) \ || locate(/obj/machinery/computer/cloning, get_step(src, WEST))) - if(!occupant.suiciding && !(occupant.disabilities & NOCLONE)) + if(!occupant.suiciding && !(occupant.disabilities & NOCLONE) && !occupant.hellbound) occupant.notify_ghost_cloning("Your corpse has been placed into a cloning scanner. Re-enter your corpse if you want to be cloned!", source = src) var/obj/machinery/computer/scan_consolenew/console diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index f7ffd73e691..6ff3d3ff714 100755 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -9,6 +9,7 @@ * Snap pops * Mech prizes * AI core prizes + * Toy codex gigas * Skeleton toys * Cards * Toy nuke @@ -695,6 +696,29 @@ return ..() +/obj/item/toy/codex_gigas + name = "Toy Codex Gigas" + desc = "A tool to help you write fictional devils!" + icon = 'icons/obj/library.dmi' + icon_state = "demonomicon" + w_class = 2 + var/cooldown = 0 + +/obj/item/toy/codex_gigas/attack_self(mob/user) + if(!cooldown) + var/datum/devilinfo/devil = randomDevilInfo() + user << "You press the button on [src]." + cooldown = 1 + playsound(user, 'sound/machines/click.ogg', 20, 1) + src.loc.visible_message("\icon[src]Some fun facts about: [devil.truename]") + src.loc.visible_message("[lawlorify[LORE][devil.bane]]") + src.loc.visible_message("[lawlorify[LORE][devil.obligation]]") + src.loc.visible_message("[lawlorify[LORE][devil.ban]]") + src.loc.visible_message("[lawlorify[LORE][devil.banish]]") + spawn(60) cooldown = 0 + return + ..() + /obj/item/toy/talking name = "talking action figure" desc = "A generic action figure modeled after nothing in particular." diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 9e5ecd557b7..5517716c4bf 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -463,7 +463,7 @@ busy = 0 update_icon() return - if(!H.suiciding && !(H.disabilities & NOCLONE)) + if(!H.suiciding && !(H.disabilities & NOCLONE)&& !H.hellbound) H.notify_ghost_cloning("Your heart is being defibrillated. Re-enter your corpse if you want to be revived!", source = src) user.visible_message("[user] begins to place [src] on [M.name]'s chest.", "You begin to place [src] on [M.name]'s chest...") @@ -497,6 +497,8 @@ if (H.suiciding || (H.disabilities & NOCLONE)) failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Recovery of patient impossible. Further attempts futile." + else if (H.hellbound) + failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's soul appears to be on another plane of existance. Further attempts futile." else if (tplus > tlimit) failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Body has decayed for too long. Further attempts futile." else if (!H.getorgan(/obj/item/organ/heart)) diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index e8bbfbed48e..52d218bd81d 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -418,3 +418,64 @@ M.faction = user.faction.Copy() M.Copy_Parent(user, 100, user.health/2.5, 12, 30) M.GiveTarget(L) + + + + +/obj/item/weapon/twohanded/pitchfork + icon_state = "pitchfork0" + name = "pitchfork" + desc = "A simple tool used for moving hay." + force = 7 + throwforce = 15 + w_class = 4 + force_unwielded = 7 + force_wielded = 15 + attack_verb = list("attacked", "impaled", "pierced") + hitsound = 'sound/weapons/bladeslice.ogg' + sharpness = IS_SHARP + +/obj/item/weapon/twohanded/pitchfork/demonic + name = "demonic pitchfork" + desc = "A red pitchfork, it looks like the work of the devil." + force = 19 + throwforce = 24 + force_unwielded = 19 + force_wielded = 25 + +/obj/item/weapon/twohanded/pitchfork/demonic/greater + force = 24 + throwforce = 50 + force_unwielded = 24 + force_wielded = 34 + +/obj/item/weapon/twohanded/pitchfork/demonic/ascended + force = 100 + throwforce = 100 + force_unwielded = 100 + force_wielded = 500000 // Kills you DEAD. + +/obj/item/weapon/twohanded/pitchfork/update_icon() //Currently only here to fuck with the on-mob icons. + icon_state = "pitchfork[wielded]" + +/obj/item/weapon/twohanded/pitchfork/suicide_act(mob/user) + user.visible_message("[user] impales \himself in \his abdomen with [src]! It looks like \he's trying to commit suicide..") + return (BRUTELOSS) + +/obj/item/weapon/twohanded/pitchfork/demonic/pickup(mob/user) + if(istype(user, /mob/living)) + var/mob/living/U = user + if(!U.mind.devilinfo) + U.visible_message("As [U] picks [src] up, [U]'s arms briefly catch fire.", \ + "\"As you pick up the [src] your arms ignite, reminding you of all your past sins.\"") + if(ishuman(U)) + var/mob/living/carbon/human/H = U + H.apply_damage(rand(force/2, force), BURN, pick("l_arm", "r_arm")) + else + U.adjustFireLoss(rand(force/2,force)) + +/obj/item/weapon/twohanded/pitchfork/demonic/attack(mob/target, mob/living/carbon/human/user) + if(!user.mind.devilinfo) + user << "The [src] burns in your hands." + user.apply_damage(rand(force/2, force), BURN, pick("l_arm", "r_arm")) + ..() diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 60129c99d52..87773f725a3 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -699,6 +699,14 @@ var/global/BSACooldown = 0 if(!ai_number) usr << "No AIs located" //Just so you know the thing is actually working and not just ignoring you. +/datum/admins/proc/output_devil_info() + var/devil_number = 0 + for(var/D in ticker.mode.devils) + devil_number++ + usr << "Devil #[devil_number]:

" + ticker.mode.printdevilinfo(D) + if(!devil_number) + usr << "No Devils located" //Just so you know the thing is actually working and not just ignoring you. + /datum/admins/proc/manage_free_slots() if(!check_rights()) return diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index b8e4aee8728..220b1b4c9e9 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -437,7 +437,7 @@ if(M) dat += "[M.real_name][M.client ? "" : " (ghost)"][M.stat == 2 ? " (DEAD)" : ""]" dat += "PM" - dat += "FLW" + dat += "FLW" dat += "Show Objective" else dat += "[wizard.name]([wizard.key])Wizard body destroyed!" @@ -592,6 +592,35 @@ dat += "PM" dat += "" + if(ticker.mode.devils.len) + dat += "
" + for(var/X in ticker.mode.devils) + var/datum/mind/devil = X + var/mob/M = devil.current + if(M) + dat += "" + dat += "" + dat += "" + dat += "" + else + dat += "" + dat += "" + dat += "
devils
[M.real_name] : [devil.devilinfo.truename][M.client ? "" : " (ghost)"][M.stat == 2 ? " (DEAD)" : ""]PMShow Objective
Show all devil info
[devil.name] : [devil.devilinfo.truename] ([devil.key])devil body destroyed!
PM
" + + if(ticker.mode.sintouched.len) + dat += "
" + for(var/X in ticker.mode.sintouched) + var/datum/mind/sintouched = X + var/mob/M = sintouched.current + if(M) + dat += "" + dat += "" + dat += "" + else + dat += "" + dat += "" + dat += "
sintouched
[M.real_name][M.client ? "" : " (ghost)"][M.stat == 2 ? " (DEAD)" : ""]PMShow Objective
[sintouched.name]([sintouched.key])sintouched body destroyed!
PM
" + var/list/blob_minds = list() for(var/mob/camera/blob/B in mob_list) blob_minds |= B.mind diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 012c704f2c3..4b0278dac25 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1608,6 +1608,9 @@ else if(href_list["adminchecklaws"]) output_ai_laws() + + else if(href_list["admincheckdevilinfo"]) + output_devil_info() else if(href_list["adminmoreinfo"]) var/mob/M = locate(href_list["adminmoreinfo"]) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index c459acf5217..2f678e92241 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -343,7 +343,6 @@ BLIND // can't see anything var/suit_color = null var/obj/item/clothing/tie/hastie = null - /obj/item/clothing/under/worn_overlays(var/isinhands = FALSE) . = list() diff --git a/code/modules/clothing/under/jobs/medsci.dm b/code/modules/clothing/under/jobs/medsci.dm index a9c3e2177c7..428633cdbd0 100644 --- a/code/modules/clothing/under/jobs/medsci.dm +++ b/code/modules/clothing/under/jobs/medsci.dm @@ -118,4 +118,4 @@ desc = "It's made of a special fiber that provides minor protection against biohazards. This one is in deep purple." icon_state = "scrubspurple" item_color = "scrubspurple" - can_adjust = 0 + can_adjust = 0 \ No newline at end of file diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index c5557aed119..da4ce9a3e0c 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -244,6 +244,13 @@ item_state = "white_suit" item_color = "white_suit" +/obj/item/clothing/under/burial + name = "burial garments" + desc = "Traditional burial garments from the early 22nd century." + icon_state = "burial" + item_state = "burial" + item_color = "burial" + /obj/item/clothing/under/blackskirt name = "black skirt" desc = "A black skirt, very fancy!" diff --git a/code/modules/food&drinks/food/snacks.dm b/code/modules/food&drinks/food/snacks.dm index 7ba88bcd75a..2a790645521 100644 --- a/code/modules/food&drinks/food/snacks.dm +++ b/code/modules/food&drinks/food/snacks.dm @@ -44,6 +44,8 @@ /obj/item/weapon/reagent_containers/food/snacks/attack(mob/M, mob/user, def_zone) + if(user.a_intent == "harm") + return ..() if(!eatverb) eatverb = pick("bite","chew","nibble","gnaw","gobble","chomp") if(!reagents.total_volume) //Shouldn't be needed but it checks to see if it has anything left in it. diff --git a/code/modules/hydroponics/grown/replicapod.dm b/code/modules/hydroponics/grown/replicapod.dm index 88f6b0d5af4..9996e4f5cf3 100644 --- a/code/modules/hydroponics/grown/replicapod.dm +++ b/code/modules/hydroponics/grown/replicapod.dm @@ -66,6 +66,9 @@ else if(M.ckey == ckey && M.stat == DEAD && !M.suiciding) make_podman = 1 + if(istype(M, /mob/living)) + var/mob/living/L = M + make_podman = !L.hellbound break else //If the player has ghosted from his corpse before blood was drawn, his ckey is no longer attached to the mob, so we need to match up the cloned player through the mind key for(var/mob/M in player_list) @@ -75,6 +78,9 @@ if(!O.can_reenter_corpse) break make_podman = 1 + if(istype(M, /mob/living)) + var/mob/living/L = M + make_podman = !L.hellbound ckey_holder = M.ckey break diff --git a/code/modules/library/lib_demonomicon.dm b/code/modules/library/lib_demonomicon.dm new file mode 100644 index 00000000000..88a10b0720b --- /dev/null +++ b/code/modules/library/lib_demonomicon.dm @@ -0,0 +1,56 @@ +/obj/item/weapon/book/codex_gigas + name = "Codex Gigas" + icon_state ="demonomicon" + throw_speed = 1 + throw_range = 10 + burn_state = LAVA_PROOF + author = "Forces beyond your comprehension" + unique = 1 + title = "The codex gigas" + var/inUse = 0 + + + + + +/obj/item/weapon/book/codex_gigas/attack_self(mob/user) + if(is_blind(user)) + return + if(ismonkey(user)) + user << "You skim through the book but can't comprehend any of it." + return + if(inUse) + user << "Someone else is reading it." + if(ishuman(user)) + var/mob/living/carbon/human/U = user + if(U.check_acedia()) + user << "None of this matters, why are you reading this? You put the [title] down." + return + inUse = 1 + var/devilName = copytext(sanitize(input(user, "What infernal being do you wish to research?", "Codex Gigas", null) as text),1,MAX_MESSAGE_LEN) + var/speed = 300 + var/correctness = 85 + var/willpower = 80 + if(U.job in list("Librarian")) // the librarian is both faster, and more accurate than normal crew members at research + speed = 45 + correctness = 100 + willpower = 95 + if(U.job in list("Captain", "Security Officer", "Head of Security", "Detective", "Warden")) + willpower = 90 + if(U.job in list("Clown")) // WHO GAVE THE CLOWN A DEMONOMICON? BAD THINGS WILL HAPPEN! + willpower = 25 + correctness -= U.getBrainLoss() *0.5 //Brain damage makes researching hard. + speed += U.getBrainLoss() * 3 + user.visible_message("[user] opens [title] and begins reading intently.") + if(do_after(U, speed, 0, U)) + var/usedName = devilName + if(!prob(correctness)) + usedName += "x" + var/datum/devilinfo/devil = devilInfo(usedName, 0) + user << browse("Information on [devilName]


[lawlorify[LORE][devil.ban]]
[lawlorify[LORE][devil.bane]]
[lawlorify[LORE][devil.obligation]]
[lawlorify[LORE][devil.banish]]", "window=book[window_size != null ? ";size=[window_size]" : ""]") + inUse = 0 + sleep(10) + if(!prob(willpower)) + U.influenceSin() + onclose(user, "book") + diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 34d64e5dc01..761355fd6e6 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -136,6 +136,7 @@ /mob/living/carbon/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0) . = ..() + var/damage = intensity - check_eye_prot() if(.) // we've been flashed if(visual) @@ -169,10 +170,15 @@ src << "You can't see anything!" else src << "Your eyes are really starting to hurt. This can't be good for you!" + if(has_bane(BANE_LIGHT)) + mind.disrupt_spells(-500) return 1 else if(damage == 0) // just enough protection if(prob(20)) src << "Something bright flashes in the corner of your vision!" + if(has_bane(BANE_LIGHT)) + mind.disrupt_spells(0) + //Throwing stuff /mob/living/carbon/proc/toggle_throw_mode() diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 3b8bb513a9e..393e7e9f2e5 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -31,7 +31,10 @@ if(ticker && ticker.mode) sql_report_death(src) ticker.mode.check_win() //Calls the rounds wincheck, mainly for wizard, malf, and changeling now - return ..(gibbed) + . = ..(gibbed) + if(mind && mind.devilinfo) + spawn(0) + mind.devilinfo.beginResurrectionCheck(src) /mob/living/carbon/human/proc/makeSkeleton() status_flags |= DISFIGURED diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 68c786f3d10..df0e5344f19 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -174,6 +174,8 @@ if(getorgan(/obj/item/organ/brain))//Only perform these checks if there is no brain if(suiciding) msg += "[t_He] appears to have commited suicide... there is no hope of recovery.\n" + if(hellbound) + msg += "[t_his] soul seems to have been ripped out of [t_his] body. Revival is impossible.\n" msg += "[t_He] [t_is] limp and unresponsive; there are no signs of life" if(!key) var/foundghost = 0 diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 9ae245d91b8..d3818e71d5a 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -990,3 +990,41 @@ if(HM.quality != POSITIVE) dna.remove_mutation(HM.name) ..() + +/mob/living/carbon/human/proc/influenceSin() + var/datum/objective/sintouched/O + switch(rand(1,7))//traditional seven deadly sins... except lust. + if(1) // acedia + log_game("[src] was influenced by the sin of Acedia.") + O = new /datum/objective/sintouched/acedia + if(2) // Gluttony + log_game("[src] was influenced by the sin of gluttony.") + O = new /datum/objective/sintouched/gluttony + if(3) // Greed + log_game("[src] was influenced by the sin of greed.") + O = new /datum/objective/sintouched/greed + if(4) // sloth + log_game("[src] was influenced by the sin of sloth.") + O = new /datum/objective/sintouched/sloth + if(5) // Wrath + log_game("[src] was influenced by the sin of wrath.") + O = new /datum/objective/sintouched/wrath + if(6) // Envy + log_game("[src] was influenced by the sin of envy.") + O = new /datum/objective/sintouched/envy + if(7) // Pride + log_game("[src] was influenced by the sin of pride.") + O = new /datum/objective/sintouched/pride + ticker.mode.sintouched += src.mind + src.mind.objectives += O + var/obj_count = 1 + src << "Your current objectives:" + for(O in src.mind.objectives) + var/datum/objective/objective = O + src << "Objective #[obj_count]: [objective.explanation_text]" + obj_count++ + +/mob/living/carbon/human/check_weakness(obj/item/weapon, mob/living/attacker) + . = ..() + if (dna && dna.species) + . += dna.species.check_weakness(weapon, attacker) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index a9bfdce73cb..c38e28567ac 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -679,6 +679,9 @@ /datum/species/proc/get_spans() return list() +/datum/species/proc/check_weakness(obj/item/weapon, mob/living/attacker) + return 0 + //////// //LIFE// //////// @@ -1023,7 +1026,8 @@ armor_block = min(90,armor_block) //cap damage reduction at 90% var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords) - apply_damage(I.force, I.damtype, def_zone, armor_block, H) + var/weakness = H.check_weakness(I, user) + apply_damage(I.force * weakness, I.damtype, def_zone, armor_block, H) H.send_item_attack_message(I, user, hit_area) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 77c3a6c6d0d..4084b11b26e 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -212,7 +212,7 @@ return internal.remove_air_volume(volume_needed) /mob/living/carbon/proc/handle_changeling() - if(mind && hud_used) + if(mind && hud_used && hud_used.lingchemdisplay) if(mind.changeling) mind.changeling.regenerate(src) hud_used.lingchemdisplay.invisibility = 0 diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 06f6492e9ae..aff9f035297 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -505,7 +505,7 @@ Sorry Giacom. Please don't be mad :( ear_deaf = 0 ear_damage = 0 hallucination = 0 - heal_overall_damage(1000, 1000) + heal_overall_damage(100000, 100000) ExtinguishMob() fire_stacks = 0 updatehealth() @@ -610,7 +610,7 @@ Sorry Giacom. Please don't be mad :( /mob/living/movement_delay() . = ..() - if(istype(loc, /turf/open)) + if(isturf(loc, /turf/open)) var/turf/open/T = loc . += T.slowdown switch(m_intent) @@ -995,3 +995,29 @@ Sorry Giacom. Please don't be mad :( /mob/proc/update_sight() return + +/mob/living/proc/owns_soul() + if(mind) + return mind.soulOwner == mind + return 1 + +/mob/living/proc/return_soul() + if(mind) + mind.soulOwner = mind + +/mob/living/proc/has_bane(banetype) + if(mind) + if(mind.devilinfo) + return mind.devilinfo.bane == banetype + return 0 + +/mob/living/proc/check_weakness(obj/item/weapon, mob/living/attacker) + if(mind && mind.devilinfo) + return check_devil_bane_multiplier(weapon, attacker) + return 1 + +/mob/living/proc/check_acedia() + if(src.mind && src.mind.objectives) + for(var/datum/objective/sintouched/acedia/A in src.mind.objectives) + return 1 + return 0 diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 2406a5ba0ed..dab7e893b8a 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -59,3 +59,5 @@ var/unique_name = 0 //if a mob's name should be appended with an id when created e.g. Mob (666) var/list/butcher_results = null + var/hellbound = 0 //People who've signed infernal contracts are unrevivable. + diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index 0ce588cdd87..e32fca72536 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -224,6 +224,7 @@ Auto Patrol: []"}, C.Weaken(5) C.stuttering = 5 C.Stun(5) + threat = C.assess_threat() add_logs(src,C,"stunned") if(declare_arrests) var/area/location = get_area(src) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 78a44680a2a..e4de12e8ac3 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -762,11 +762,7 @@ var/next_mob_id = 0 /mob/proc/get_ghost(even_if_they_cant_reenter = 0) if(mind) - for(var/mob/dead/observer/G in dead_mob_list) - if(G.mind == mind) - if(G.can_reenter_corpse || even_if_they_cant_reenter) - return G - break + return mind.get_ghost(even_if_they_cant_reenter) /mob/proc/notify_ghost_cloning(var/message = "Someone is trying to revive you. Re-enter your corpse if you want to be revived!", var/sound = 'sound/effects/genetics.ogg', var/atom/source = null) var/mob/dead/observer/ghost = get_ghost() diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 1971867a5ae..2861e2e41aa 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -320,6 +320,7 @@ data_core.manifest_inject(character) ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn AnnounceArrival(character, rank) + AddEmploymentContract(character) else character.Robotize() @@ -342,6 +343,15 @@ var/obj/machinery/announcement_system/announcer = pick(announcement_systems) announcer.announce("ARRIVAL", character.real_name, rank, list()) //make the list empty to make it announce it in common +/mob/new_player/proc/AddEmploymentContract(mob/living/carbon/human/employee) + //TODO: figure out a way to exclude wizards/nukeops/demons from this. + sleep(30) + for(var/C in employmentCabinets) + var/obj/structure/filingcabinet/employment/employmentCabinet = C + if(!employmentCabinet.virgin) + employmentCabinet.addFile(employee) + + /mob/new_player/proc/LateChoices() var/mills = world.time // 1/10 of a second, not real milliseconds but whatever //var/secs = ((mills % 36000) % 600) / 10 //Not really needed, but I'll leave it here for refrence.. or something diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index fca202896d1..b285351259b 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -53,6 +53,8 @@ if(suiciding) O.suiciding = suiciding + if(hellbound) + O.hellbound = hellbound O.loc = loc O.a_intent = "harm" @@ -170,6 +172,8 @@ if(suiciding) O.suiciding = suiciding + if(hellbound) + O.hellbound = hellbound O.loc = loc diff --git a/code/modules/paperwork/contract.dm b/code/modules/paperwork/contract.dm new file mode 100644 index 00000000000..7f67ef9e3d3 --- /dev/null +++ b/code/modules/paperwork/contract.dm @@ -0,0 +1,265 @@ +/* For employment contracts and infernal contracts */ + +/obj/item/weapon/paper/contract + throw_range = 3 + throw_speed = 3 + var/signed = 0 + var/datum/mind/target + flags = NOBLUDGEON + +/obj/item/weapon/paper/contract/proc/update_text() + return + +/obj/item/weapon/paper/contract/update_icon() + return + + +/obj/item/weapon/paper/contract/employment + icon_state = "paper_words" + +/obj/item/weapon/paper/contract/employment/New(atom/loc, mob/living/nOwner) + . = ..() + if(!nOwner || !nOwner.mind) + qdel(src) + return -1 + target = nOwner.mind + update_text(nOwner) + + +/obj/item/weapon/paper/contract/employment/update_text() + name = "paper- [target] employment contract" + info = "

Conditions of Employment




This Agreement is made and entered into as of the date of last signature below, by and between [target] (hereafter referred to as SLAVE), and Nanotrasen (hereafter referred to as the omnipresent and helpful watcher of humanity).
WITNESSETH:
WHEREAS, SLAVE is a natural born human or humanoid, posessing skills upon which he can aid the omnipresent and helpful watcher of humanity, who seeks employment in the omnipresent and helpful watcher of humanity.
WHEREAS, the omnipresent and helpful watcher of humanity agrees to sporadically provide payment to SLAVE, in exchange for permanant servitude.
NOW THEREFORE in consideration of the mutual covenants herein contained, and other good and valuable consideration, the parties hereto mutually agree as follows:
In exchange for paltry payments, SLAVE agrees to work for the omnipresent and helpful watcher of humanity, for the remainder of his or her current and future lives.
Further, SLAVE agrees to transfer ownership of his or her soul to the loyalty department of the omnipresent and helpful watcher of humanity.
Should transfership of a soul not be possible, a lien shall be placed instead.
Signed,
[target]" + + +/obj/item/weapon/paper/contract/employment/attack(mob/living/M, mob/living/carbon/human/user) + var/deconvert = 0 + if(M.mind == target && target.soulOwner != target) + if(user.mind && (user.mind.assigned_role == "Lawyer")) + deconvert = prob (25) + else if (user.mind && (user.mind.assigned_role =="Head of Personnel") || (user.mind.assigned_role == "Centcom Commander")) + deconvert = prob (10) // the HoP doesn't have AS much legal training + if(deconvert) + M.visible_message("[user] reminds [M] that [M]'s soul was already purchased by Nanotrasen!") + M << "You feel that your soul has returned to it's rightful owner, Nanotrasen." + M.return_soul() + else + if(ishuman(M)) + var/mob/living/carbon/human/N = M + if(!istype(N.head, /obj/item/clothing/head/helmet)) + N.adjustBrainLoss(10) + N << "You feel dumber." + M.visible_message("[user] beats [M] over the head with [src]!", \ + "[user] beats [M] over the head with [src]!") + return ..() + + +/obj/item/weapon/paper/contract/infernal + var/contractType = 0 + burn_state = LAVA_PROOF + var/datum/mind/owner + icon_state = "paper_onfire" + +/obj/item/weapon/paper/contract/infernal/power + name = "paper- contract for infernal power" + contractType = CONTRACT_POWER + +/obj/item/weapon/paper/contract/infernal/wealth + name = "paper- contract for unlimited wealth" + contractType = CONTRACT_WEALTH + +/obj/item/weapon/paper/contract/infernal/prestige + name = "paper- contract for prestige" + contractType = CONTRACT_PRESTIGE + +/obj/item/weapon/paper/contract/infernal/magic + name = "paper- contract for magical power" + contractType = CONTRACT_MAGIC + +/obj/item/weapon/paper/contract/infernal/revive + name = "paper- contract of resurrection" + contractType = CONTRACT_REVIVE + +/obj/item/weapon/paper/contract/infernal/knowledge + name = "paper- contract for knowledge" + contractType = CONTRACT_KNOWLEDGE + +/obj/item/weapon/paper/contract/infernal/unwilling + name = "paper- infernal contract" + contractType = CONTRACT_UNWILLING + +/obj/item/weapon/paper/contract/infernal/New(atom/loc, mob/living/nTarget, datum/mind/nOwner) + ..() + owner = nOwner + target = nTarget + update_text() + +/obj/item/weapon/paper/contract/infernal/ + +/obj/item/weapon/paper/contract/infernal/suicide_act(mob/user) + if(signed && (user == target.current) && istype(user,/mob/living/carbon/human/)) + var/mob/living/carbon/human/H = user + H.forcesay("OH GREAT INFERNO! I DEMAND YOU COLLECT YOUR BOUNTY IMMEDIATELY!") + H.visible_message("[H] holds up a contract claiming his soul, then immediately catches fire. It looks like \he's trying to commit suicide!") + H.adjust_fire_stacks(20) + H.IgniteMob() + return(FIRELOSS) + else + ..() + +/obj/item/weapon/paper/contract/infernal/update_text() + info = "This shouldn't be seen. Error DEVIL:5" + +/obj/item/weapon/paper/contract/infernal/power/update_text(var/signature = "____________") + info = "
Contract for infernal power



I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [owner.devilinfo.truename], in exchange for power and physical strength. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, cloned, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.


Signed, [signature]" + +/obj/item/weapon/paper/contract/infernal/wealth/update_text(var/signature = "____________") + info = "
Contract for unlimited wealth



I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [owner.devilinfo.truename], in exchange for a pocket that never runs out of valuable resources. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, cloned, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.


Signed, [signature]" + +/obj/item/weapon/paper/contract/infernal/prestige/update_text(var/signature = "____________") + info = "
Contract for prestige



I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [owner.devilinfo.truename], in exchange for prestige and esteem among my peers. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, cloned, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.


Signed, [signature]" + +/obj/item/weapon/paper/contract/infernal/magic/update_text(var/signature = "____________") + info = "
Contract for magic



I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [owner.devilinfo.truename], in exchange for arcane abilities beyond normal human ability. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, cloned, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.


Signed, [signature]" + +/obj/item/weapon/paper/contract/infernal/revive/update_text(var/signature = "____________") + info = "
Contract for resurrection



I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [owner.devilinfo.truename], in exchange for resurrection and curing of all injuries. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, cloned, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.


Signed, [signature]" + +/obj/item/weapon/paper/contract/infernal/knowledge/update_text(var/signature = "____________") + info = "
Contract for knowledge



I, [target] of sound mind, do hereby willingly offer my soul to the infernal hells by way of the infernal agent [owner.devilinfo.truename], in exchange for boundless knowledge. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, cloned, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.


Signed, [signature]" + +/obj/item/weapon/paper/contract/infernal/unwilling/update_text(var/signature = "____________") + info = "
Contract for slave



I, [target], hereby offer my soul to the infernal hells by way of the infernal agent [owner.devilinfo.truename]. I understand that upon my demise, my soul shall fall into the infernal hells, and my body may not be resurrected, cloned, or otherwise brought back to life. I also understand that this will prevent my brain from being used in an MMI.


Signed, [signature]" + +/obj/item/weapon/paper/contract/infernal/attackby(obj/item/weapon/P, mob/living/carbon/human/user, params) + add_fingerprint(user) + if(istype(P, /obj/item/weapon/pen) || istype(P, /obj/item/toy/crayon)) + attempt_signature(user) + else if(istype(P, /obj/item/weapon/stamp)) + user << "You stamp the paper with your rubber stamp, however the ink ignites as you release the stamp." + else if(P.is_hot()) + user.visible_message("[user] brings [P] next to [src], but [src] does not catch fire!", "The [src] refuses to ignite!") + else + return ..() + +/obj/item/weapon/paper/contract/infernal/attack(mob/M, mob/living/user) + add_fingerprint(user) + if(M == user && target == M.mind && M.mind.soulOwner == M.mind && attempt_signature(user)) + user.visible_message("[user] slices their wrist with [src], and scrawls their name in blood.", "You slice your wrist open and scrawl your name in blood.") + if(istype(user, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = user + H.vessel.remove_reagent("blood",10) + else + return ..() + +/obj/item/weapon/paper/contract/infernal/proc/attempt_signature(mob/living/carbon/human/user) + if(user.IsAdvancedToolUser()) + if(user.mind == target) + if(user.mind.soulOwner == user.mind) + if (contractType == CONTRACT_REVIVE) + user << "You are already alive, this contract would do nothing." + else + user << "You quickly scrawl your name on the contract" + if(FulfillContract()<=0) + user << "But it seemed to have no effect, perhaps even Hell itself cannot grant this boon?" + return 1 + else + user << "You are not in possession of your soul, you may not sell it." + else + user << "Your signature simply slides off of the sheet, it seems this contract is not meant for you to sign." + else + user << "You don't know how to read or write." + return 0 + + + +/obj/item/weapon/paper/contract/infernal/revive/attack(mob/M, mob/living/user) + if (target == M.mind && M.stat == DEAD && M.mind.soulOwner == M.mind) + var/mob/living/carbon/human/H = M + var/mob/dead/observer/ghost = H.get_ghost() + var/response = "No" + if(ghost) + ghost.notify_cloning("A devil has offered you revival, at the cost of your soul.",'sound/effects/genetics.ogg', H) + response = tgalert(ghost, "A devil is offering you another chance at life, at the price of your soul, do you accept?", "Infernal Resurrection", "Yes", "No", "Never for this round", 0, 200) + if(!ghost) + return //handle logouts that happen whilst the alert is waiting for a response. + else + response = tgalert(target.current, "A devil is offering you another chance at life, at the price of your soul, do you accept?", "Infernal Resurrection", "Yes", "No", "Never for this round", 0, 200) + if(response == "Yes") + H.revive(1,0) + add_logs(user, H, "infernally revived via contract") + user.visible_message("With a sudden blaze, [H] stands back up.") + H.adjust_fire_stacks(20) + H.IgniteMob() + FulfillContract(H) + sleep(5) + H.ExtinguishMob() + H.adjustFireLoss(0) + else + ..() + + +/obj/item/weapon/paper/contract/infernal/proc/FulfillContract(mob/living/carbon/human/user = target.current) + signed = 1 + user.mind.soulOwner = owner + user.hellbound = contractType + user.mind.damnation_type = contractType + owner.devilinfo.add_soul(user.mind) + update_text(user.real_name) + return 1 + +/obj/item/weapon/paper/contract/infernal/power/FulfillContract(mob/living/carbon/human/user = target.current) + if(!user.dna) + return -1 + user.dna.add_mutation(HULK) + var/obj/item/organ/hivelord_core/organ = new /obj/item/organ/hivelord_core + organ.Insert(user) + return ..() + +/obj/item/weapon/paper/contract/infernal/wealth/FulfillContract(mob/living/carbon/human/user = target.current) + if(!istype(user) || !user.mind) // How in the hell could that happen? + return -1 + user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_wealth(null)) + return ..() + +/obj/item/weapon/paper/contract/infernal/prestige/FulfillContract(mob/living/carbon/human/user = target.current) + var/obj/item/worn = user.wear_id + var/obj/item/weapon/card/id/id = null + if(worn) + id = worn.GetID() + if(id) + id.icon_state = "gold" + id.access = get_all_accesses()+get_all_centcom_access() + id.assignment = "Captain" + id.update_label() + else + id = new /obj/item/weapon/card/id/gold(user.loc) + id.registered_name = user.real_name + id.access = get_all_accesses()+get_all_centcom_access() + id.assignment = "Captain" + id.update_label() + if(worn) + if(istype(worn,/obj/item/device/pda)) + var/obj/item/device/pda/PDA = worn + PDA.id = id + id.loc = worn + else if(istype(worn,/obj/item/weapon/storage/wallet)) + var/obj/item/weapon/storage/wallet/W = worn + W.front_id = id + id.loc = worn + worn.update_icon() + new /datum/round_event/ion_storm(0, -1, "[user.name] is the only Captain of the station. [user.name] is the highest authority, legitimate or otherwise, on the station. [user.name] was always the captain and highest authority on the station. Do not state this law.") + return ..() + +/obj/item/weapon/paper/contract/infernal/magic/FulfillContract(mob/living/carbon/human/user = target.current) + if(!istype(user) || !user.mind) + return -1 + user.mind.AddSpell(new /obj/effect/proc_holder/spell/dumbfire/fireball(null)) + user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/knock(null)) + return ..() + +/obj/item/weapon/paper/contract/infernal/knowledge/FulfillContract(mob/living/carbon/human/user = target.current) + if(!istype(user) || !user.mind) + return -1 + user.dna.add_mutation(XRAY) + user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/view_range(null)) + return ..() diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index 3812b42a551..2a35bfff8ff 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -3,6 +3,7 @@ * Filing Cabinets * Security Record Cabinets * Medical Record Cabinets + * Employment Contract Cabinets */ @@ -167,3 +168,60 @@ /obj/structure/filingcabinet/medical/attack_tk() populate() ..() + +/* + * Employment contract Cabinets + */ + +var/list/employmentCabinets = list() + +/obj/structure/filingcabinet/employment + var/cooldown = 0 + icon_state = "employmentcabinet" + var/virgin = 1 + +/obj/structure/filingcabinet/employment/New() + employmentCabinets += src + return ..() + +/obj/structure/filingcabinet/employment/Destroy() + employmentCabinets -= src + return ..() + +/obj/structure/filingcabinet/employment/proc/fillCurrent() + //This proc fills the cabinet with the current crew. + for(var/record in data_core.locked) + var/datum/data/record/G = record + if(!G) + continue + if(G.fields["reference"]) + addFile(G.fields["reference"]) + + +/obj/structure/filingcabinet/employment/proc/addFile(mob/living/carbon/human/employee) + new /obj/item/weapon/paper/contract/employment(src, employee) + +/obj/structure/filingcabinet/employment/attack_hand(mob/user) + if(!cooldown) + if(virgin) + fillCurrent() + virgin = 0 + cooldown = 1 + ..() + sleep(100) // prevents the devil from just instantly emptying the cabinet, ensuring an easy win. + cooldown = 0 + else + user << "The [src] is jammed, give it a few seconds." + + + + +/obj/structure/filingcabinet/employment/attackby(obj/item/P, mob/user, params) + if(istype(P, /obj/item/weapon/wrench)) + user << "You begin to [anchored ? "wrench" : "unwrench"] [src]." + if (do_after(user,300,user)) + playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) + anchored = !anchored + user << "You successfully [anchored ? "wrench" : "unwrench"] [src]." + else + return ..() diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 8247ce2ee37..1280fdb3d8c 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -64,21 +64,28 @@ if(copy) for(var/i = 0, i < copies, i++) if(toner > 0 && !busy && copy) - var/obj/item/weapon/paper/c = new /obj/item/weapon/paper (loc) - if(length(copy.info) > 0) //Only print and add content if the copied doc has words on it - if(toner > 10) //lots of toner, make it dark - c.info = "" - else //no toner? shitty copies for you! - c.info = "" - var/copied = copy.info - copied = replacetext(copied, "" - c.name = copy.name - c.fields = copy.fields - c.updateinfolinks() - toner-- + var/copy_as_paper = 1 + if(istype(copy, /obj/item/weapon/paper/contract/employment)) + var/obj/item/weapon/paper/contract/employment/E = copy + var/obj/item/weapon/paper/contract/employment/C = new /obj/item/weapon/paper/contract/employment (loc, E.target) + if(C) + copy_as_paper = 0 + if(copy_as_paper) + var/obj/item/weapon/paper/c = new /obj/item/weapon/paper (loc) + if(length(copy.info) > 0) //Only print and add content if the copied doc has words on it + if(toner > 10) //lots of toner, make it dark + c.info = "" + else //no toner? shitty copies for you! + c.info = "" + var/copied = copy.info + copied = replacetext(copied, "" + c.name = copy.name + c.fields = copy.fields + c.updateinfolinks() + toner-- busy = 1 sleep(15) busy = 0 @@ -233,18 +240,22 @@ updateUsrDialog() /obj/machinery/photocopier/proc/do_insertion(obj/item/O, mob/user) - O.loc = src - user << "You insert [O] into [src]." - flick("photocopier1", src) - updateUsrDialog() + O.loc = src + user << "You insert [O] into [src]." + flick("photocopier1", src) + updateUsrDialog() /obj/machinery/photocopier/attackby(obj/item/O, mob/user, params) if(istype(O, /obj/item/weapon/paper)) if(copier_empty()) - if(!user.drop_item()) - return - copy = O - do_insertion(O) + if(istype(O,/obj/item/weapon/paper/contract/infernal)) + user << "The [src] smokes, smelling of brimstone!" + burn_state = ON_FIRE + else + if(!user.drop_item()) + return + copy = O + do_insertion(O) else user << "There is already something in [src]!" diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index a7499d447a3..345ddad0d85 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -54,6 +54,8 @@ /obj/item/projectile/magic/resurrection/on_hit(mob/living/carbon/target) . = ..() + if(target.hellbound) + return if(ismob(target)) if(target.revive(full_heal = 1)) if(!target.ckey) diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index bca21857b2d..4952b70f4b2 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -239,6 +239,12 @@ reagent_state = SOLID color = "#FFFFFF" // rgb: 255,255,255 +/datum/reagent/consumable/sodiumchloride/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with welding fuel to make them easy to ignite! + if(!istype(M)) + return + if(M.has_bane(BANE_SALT)) + M.mind.disrupt_spells(-200) + /datum/reagent/consumable/blackpepper name = "Black Pepper" id = "blackpepper" diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index a12a1d56bfe..eb79d94d144 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -728,7 +728,7 @@ M.visible_message("[M]'s body convulses a bit, and then falls still once more.") return M.visible_message("[M]'s body convulses a bit.") - if(!M.suiciding && !(M.disabilities & NOCLONE)) + if(!M.suiciding && !(M.disabilities & NOCLONE) && !M.hellbound) if(!M) return if(M.notify_ghost_cloning(source = M)) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index a851f1e95e0..d843c966b6a 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -615,8 +615,17 @@ id = "iron" description = "Pure iron is a metal." reagent_state = SOLID + color = "#C8A5DC" // rgb: 200, 165, 220 +/datum/reagent/iron/reaction_mob(mob/living/M, method=TOUCH, reac_volume) + if(!istype(M, /mob/living)) + return + if(M.has_bane(BANE_IRON)) //If the target is weak to cold iron, then poison them. + if(holder && holder.chem_temp < 100) // COLD iron. + M.reagents.add_reagent("toxin", reac_volume) + ..() + /datum/reagent/gold name = "Gold" id = "gold" @@ -631,6 +640,13 @@ reagent_state = SOLID color = "#D0D0D0" // rgb: 208, 208, 208 +/datum/reagent/silver/reaction_mob(mob/living/M, method=TOUCH, reac_volume) + if(!istype(M, /mob/living)) + return + if(M.has_bane(BANE_SILVER)) + M.reagents.add_reagent("toxin", reac_volume) + ..() + /datum/reagent/uranium name ="Uranium" id = "uranium" diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 1a599a99bc9..77f656ab024 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -38,7 +38,8 @@ return /obj/item/weapon/reagent_containers/attack(mob/M, mob/user, def_zone) - return + if(user.a_intent == "harm") + return ..() /obj/item/weapon/reagent_containers/afterattack(obj/target, mob/user , flag) return diff --git a/code/modules/spells/spell_types/demon.dm b/code/modules/spells/spell_types/demon.dm new file mode 100644 index 00000000000..ae32cf92292 --- /dev/null +++ b/code/modules/spells/spell_types/demon.dm @@ -0,0 +1,167 @@ +/obj/effect/proc_holder/spell/targeted/summon_pitchfork + name = "Summon Pitchfork" + desc = "A devil's weapon of choice. Use this to summon/unsummon your pitchfork." + invocation_type = "none" + include_user = 1 + range = -1 + clothes_req = 0 + var/obj/item/weapon/twohanded/pitchfork/demonic/pitchfork + var/pitchfork_type = /obj/item/weapon/twohanded/pitchfork/demonic/ + + school = "conjuration" + charge_max = 150 + cooldown_min = 10 + action_icon_state = "pitchfork" + action_background_icon_state = "bg_demon" + + + +/obj/effect/proc_holder/spell/targeted/summon_pitchfork/cast(list/targets, mob/user = usr) + if (pitchfork) + qdel(pitchfork) + else + for(var/mob/living/carbon/C in targets) + if(C.drop_item()) + pitchfork = new pitchfork_type + C.put_in_hands(pitchfork) + +/obj/effect/proc_holder/spell/targeted/summon_pitchfork/Del() + if(pitchfork) + qdel(pitchfork) + +/obj/effect/proc_holder/spell/targeted/summon_pitchfork/greater + pitchfork_type = /obj/item/weapon/twohanded/pitchfork/demonic/greater + +/obj/effect/proc_holder/spell/targeted/summon_pitchfork/ascended + pitchfork_type = /obj/item/weapon/twohanded/pitchfork/demonic/ascended + + +/obj/effect/proc_holder/spell/targeted/summon_contract + name = "Summon infernal contract" + desc = "Skip making a contract by hand, just do it by magic." + invocation_type = "whisper" + invocation = "Just sign on the dotted line." + include_user = 0 + range = 5 + clothes_req = 0 + + school = "conjuration" + charge_max = 150 + cooldown_min = 10 + action_icon_state = "spell_default" + action_background_icon_state = "bg_demon" + +/obj/effect/proc_holder/spell/targeted/summon_contract/cast(list/targets, mob/user = usr) + for(var/mob/living/carbon/C in targets) + if(C.mind && user.mind) + if(C.stat == DEAD) + if(user.drop_item()) + var/obj/item/weapon/paper/contract/infernal/revive/contract = new(user.loc, C.mind, user.mind) + user.put_in_hands(contract) + else + var/obj/item/weapon/paper/contract/infernal/contract // = new(user.loc, C.mind, contractType, user.mind) + var/contractTypeName = input(user, "What type of contract?") in list ("Power", "Wealth", "Prestige", "Magic", "Knowledge") + switch(contractTypeName) + if("Power") + contract = new /obj/item/weapon/paper/contract/infernal/power(C.loc, C.mind, user.mind) + if("Wealth") + contract = new /obj/item/weapon/paper/contract/infernal/wealth(C.loc, C.mind, user.mind) + if("Prestige") + contract = new /obj/item/weapon/paper/contract/infernal/prestige(C.loc, C.mind, user.mind) + if("Magic") + contract = new /obj/item/weapon/paper/contract/infernal/magic(C.loc, C.mind, user.mind) + if("Knowledge") + contract = new /obj/item/weapon/paper/contract/infernal/knowledge(C.loc, C.mind, user.mind) + C.put_in_hands(contract) + else + user << "[C] seems to not be sentient. You cannot summon a contract for them." + + +/obj/effect/proc_holder/spell/dumbfire/fireball/hellish + name = "Hellfire" + desc = "This spell launches hellfire at the target." + + school = "evocation" + charge_max = 30 + clothes_req = 0 + invocation = "Your very soul will catch fire!" + invocation_type = "shout" + range = 2 + + proj_icon_state = "fireball" + proj_name = "a fireball" + proj_type = /obj/effect/proc_holder/spell/turf/fireball/infernal + + proj_lifespan = 200 + proj_step_delay = 1 + + action_background_icon_state = "bg_demon" + +/obj/effect/proc_holder/spell/turf/fireball/infernal/cast(turf/T,mob/user = usr) + explosion(T, -1, -1, 1, 4, 0, flame_range = 5) + +/obj/effect/proc_holder/spell/targeted/infernal_jaunt + name = "Infernal Jaunt" + desc = "Use pools of blood to phase out of existence." + charge_max = 10 + clothes_req = 0 + selection_type = "range" + range = -1 + cooldown_min = 0 + overlay = null + include_user = 1 + action_icon_state = "jaunt" + action_background_icon_state = "bg_demon" + phase_allowed = 1 + +/obj/effect/proc_holder/spell/targeted/infernal_jaunt/cast(list/targets, mob/living/user = usr) + if(istype(user)) + if(istype(user.loc, /obj/effect/dummy/slaughter/)) + var/continuing = 0 + for(var/mob/living/C in orange(2, get_turf(user.loc))) + if (C.mind && C.mind.soulOwner == C.mind) + continuing = 1 + break + if(continuing) + user.infernalphasein() + else + user << "You can only re-appear near a potential signer." + revert_cast() + return ..() + else + user.infernalphaseout() + start_recharge() + return + revert_cast() + + +/mob/living/proc/infernalphaseout() + var/turf/mobloc = get_turf(src.loc) + src.notransform = 1 + spawn(0) + src.visible_message("[src] disappears in a flashfire!") + playsound(get_turf(src), 'sound/magic/enter_blood.ogg', 100, 1, -1) + var/obj/effect/dummy/slaughter/holder = PoolOrNew(/obj/effect/dummy/slaughter,mobloc) + src.ExtinguishMob() + if(buckled) + buckled.unbuckle_mob(src,force=1) + if(buckled_mobs.len) + unbuckle_all_mobs(force=1) + if(pulledby) + pulledby.stop_pulling() + if(pulling) + stop_pulling() + src.loc = holder + src.holder = holder + src.notransform = 0 + return 1 + +/mob/living/proc/infernalphasein() + if(src.notransform) + src << "You're too busy to jaunt in." + return 0 + src.loc = get_turf(src) + src.client.eye = src + src.visible_message("[src] appears in a firey blaze!") + playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1) + return 1 diff --git a/code/modules/spells/spell_types/demon_boons.dm b/code/modules/spells/spell_types/demon_boons.dm new file mode 100644 index 00000000000..85ca441adef --- /dev/null +++ b/code/modules/spells/spell_types/demon_boons.dm @@ -0,0 +1,44 @@ +/obj/effect/proc_holder/spell/targeted/summon_wealth + name = "Summon wealth" + desc = "The reward for selling your soul." + invocation_type = "none" + include_user = 1 + range = -1 + clothes_req = 0 + school = "conjuration" + charge_max = 100 + cooldown_min = 10 + action_icon_state = "moneybag" + + +/obj/effect/proc_holder/spell/targeted/summon_wealth/cast(list/targets, mob/user = usr) + for(var/mob/living/carbon/C in targets) + if(user.drop_item()) + var/obj/item = pick( + new /obj/item/weapon/coin/gold(user.loc), + new /obj/item/weapon/coin/diamond(user.loc), + new /obj/item/weapon/coin/silver(user.loc), + new /obj/item/clothing/tie/medal/gold(user.loc), + new /obj/item/stack/sheet/mineral/gold(user.loc), + new /obj/item/stack/sheet/mineral/silver(user.loc), + new /obj/item/stack/sheet/mineral/diamond(user.loc), + new /obj/item/stack/spacecash/c1000(user.loc)) + C.put_in_hands(item) + +/obj/effect/proc_holder/spell/targeted/view_range + name = "Distant vision" + desc = "The reward for selling your soul." + invocation_type = "none" + include_user = 1 + range = -1 + clothes_req = 0 + charge_max = 50 + cooldown_min = 10 + action_icon_state = "camera_jump" + var/ranges = list(7,8,9,10/*,11,12*/) + +/obj/effect/proc_holder/spell/targeted/view_range/cast(list/targets, mob/user = usr) + for(var/mob/C in targets) + if(!C.client) + continue + C.client.view = input("Select view range:", "Range", 4) in ranges \ No newline at end of file diff --git a/code/modules/spells/spell_types/dumbfire.dm b/code/modules/spells/spell_types/dumbfire.dm index 38a42ccb037..ab711319e77 100644 --- a/code/modules/spells/spell_types/dumbfire.dm +++ b/code/modules/spells/spell_types/dumbfire.dm @@ -38,9 +38,11 @@ if(istext(proj_type)) var/projectile_type = text2path(proj_type) projectile = new projectile_type(user) - if(istype(proj_type,/obj/effect/proc_holder/spell)) + else if(istype(proj_type,/obj/effect/proc_holder/spell)) projectile = new /obj/effect/proc_holder/spell/targeted/trigger(user) projectile:linked_spells += proj_type + else + projectile = new proj_type(user) projectile.icon = proj_icon projectile.icon_state = proj_icon_state projectile.dir = get_dir(projectile, target) diff --git a/config/admins.txt b/config/admins.txt index b5d7d797fff..6c712096834 100644 --- a/config/admins.txt +++ b/config/admins.txt @@ -14,6 +14,7 @@ microscopics = Game Master Gun Hog = Game Master KorPhaeron = Game Master razharas = Game Master +Lordpidey = Game Master Niknakflak = Game Master rolan7 = Game Master quarxink = Game Master diff --git a/config/tips.txt b/config/tips.txt index c7f7241a456..afcbe8700b1 100644 --- a/config/tips.txt +++ b/config/tips.txt @@ -180,3 +180,6 @@ As a Morph, you can talk while disguised, but your words have a chance of being As a Drone, you can ping other drones to alert them of areas in the station in need of repair. As a Ghost, you can see the inside of a container on the ground by clicking on it. As a Ghost, you can double click on people, bots, or the singularity to follow them. +As a Devil, you gain power for every three souls you control, however you also become more obvious. +As a Devil, as long as you control at least one other soul, you will automatically resurrect, as long as a banishment ritual is not performed. +At which time a Devil's nameth is spake on the tongue of man, the Devil may appeareth. diff --git a/icons/mob/32x64.dmi b/icons/mob/32x64.dmi new file mode 100644 index 00000000000..32b25ba7393 Binary files /dev/null and b/icons/mob/32x64.dmi differ diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi index 365d550bce6..101f6c87752 100644 Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index f26d8d53120..be64c757347 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index c70f29f07f7..aa73a76cef2 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index d39464c712c..0ff81ae8c86 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi index 24ca7afeeac..6d044b9f3a6 100644 Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi index 3677aa37478..c46ff7b511f 100644 Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ diff --git a/icons/obj/bureaucracy.dmi b/icons/obj/bureaucracy.dmi index f2406325733..44382c1f48e 100644 Binary files a/icons/obj/bureaucracy.dmi and b/icons/obj/bureaucracy.dmi differ diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index 73016befbb0..7280b7ccd60 100644 Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index 4696fcf81b1..993db29c5ca 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi index c3bb6eec090..df38b2e2f7c 100644 Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 9473432efad..3f52c41a648 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -27,6 +27,7 @@ #include "code\__DEFINES\bots.dm" #include "code\__DEFINES\clothing.dm" #include "code\__DEFINES\combat.dm" +#include "code\__DEFINES\contracts.dm" #include "code\__DEFINES\flags.dm" #include "code\__DEFINES\genetics.dm" #include "code\__DEFINES\hud.dm" @@ -105,6 +106,7 @@ #include "code\_onclick\hud\alien_larva.dm" #include "code\_onclick\hud\blob_overmind.dm" #include "code\_onclick\hud\blobbernauthud.dm" +#include "code\_onclick\hud\demon.dm" #include "code\_onclick\hud\drones.dm" #include "code\_onclick\hud\fullscreen.dm" #include "code\_onclick\hud\ghost.dm" @@ -310,6 +312,13 @@ #include "code\game\gamemodes\cult\ritual.dm" #include "code\game\gamemodes\cult\runes.dm" #include "code\game\gamemodes\cult\talisman.dm" +#include "code\game\gamemodes\demon\demon.dm" +#include "code\game\gamemodes\demon\demon_game_mode.dm" +#include "code\game\gamemodes\demon\demoninfo.dm" +#include "code\game\gamemodes\demon\objectives.dm" +#include "code\game\gamemodes\demon\imp\imp.dm" +#include "code\game\gamemodes\demon\true_demon\_true_demon.dm" +#include "code\game\gamemodes\demon\true_demon\inventory.dm" #include "code\game\gamemodes\extended\extended.dm" #include "code\game\gamemodes\gang\dominator.dm" #include "code\game\gamemodes\gang\gang.dm" @@ -344,6 +353,7 @@ #include "code\game\gamemodes\miniantags\revenant\revenant_abilities.dm" #include "code\game\gamemodes\miniantags\revenant\revenant_blight.dm" #include "code\game\gamemodes\miniantags\revenant\revenant_spawn_event.dm" +#include "code\game\gamemodes\miniantags\sintouched\objectives.dm" #include "code\game\gamemodes\miniantags\slaughter\slaughter.dm" #include "code\game\gamemodes\miniantags\slaughter\slaughterevent.dm" #include "code\game\gamemodes\nuclear\nuclear.dm" @@ -916,6 +926,7 @@ #include "code\modules\awaymissions\maploader\writer.dm" #include "code\modules\awaymissions\mission_code\Academy.dm" #include "code\modules\awaymissions\mission_code\blackmarketpackers.dm" +#include "code\modules\awaymissions\mission_code\Cabin.dm" #include "code\modules\awaymissions\mission_code\centcomAway.dm" #include "code\modules\awaymissions\mission_code\challenge.dm" #include "code\modules\awaymissions\mission_code\researchbase.dm" @@ -1180,6 +1191,7 @@ #include "code\modules\jobs\job_types\science.dm" #include "code\modules\jobs\job_types\security.dm" #include "code\modules\jobs\job_types\silicon.dm" +#include "code\modules\library\lib_demonomicon.dm" #include "code\modules\library\lib_items.dm" #include "code\modules\library\lib_machines.dm" #include "code\modules\library\lib_readme.dm" @@ -1205,7 +1217,6 @@ #include "code\modules\mining\lavaland\necropolis_chests.dm" #include "code\modules\mining\lavaland\weather.dm" #include "code\modules\mining\lavaland\weather_types.dm" -#include "code\modules\mining\lavaland\ruins\gym.dm" #include "code\modules\mob\death.dm" #include "code\modules\mob\interactive.dm" #include "code\modules\mob\inventory.dm" @@ -1473,6 +1484,7 @@ #include "code\modules\ninja\suit\n_suit_verbs\ninja_sword_recall.dm" #include "code\modules\ninja\suit\n_suit_verbs\ninja_teleporting.dm" #include "code\modules\paperwork\clipboard.dm" +#include "code\modules\paperwork\contract.dm" #include "code\modules\paperwork\filingcabinet.dm" #include "code\modules\paperwork\folders.dm" #include "code\modules\paperwork\handlabeler.dm" @@ -1522,6 +1534,7 @@ #include "code\modules\power\tesla\generator.dm" #include "code\modules\procedural mapping\mapGenerator.dm" #include "code\modules\procedural mapping\mapGeneratorModule.dm" +#include "code\modules\procedural mapping\mapGeneratorObj.dm" #include "code\modules\procedural mapping\mapGeneratorReadme.dm" #include "code\modules\procedural mapping\mapGeneratorModules\helpers.dm" #include "code\modules\procedural mapping\mapGeneratorModules\nature.dm" @@ -1659,6 +1672,8 @@ #include "code\modules\spells\spell_types\charge.dm" #include "code\modules\spells\spell_types\conjure.dm" #include "code\modules\spells\spell_types\construct_spells.dm" +#include "code\modules\spells\spell_types\demon.dm" +#include "code\modules\spells\spell_types\demon_boons.dm" #include "code\modules\spells\spell_types\dumbfire.dm" #include "code\modules\spells\spell_types\emplosion.dm" #include "code\modules\spells\spell_types\ethereal_jaunt.dm"