Merge branch 'master' into upstream-merge-26864

This commit is contained in:
kevinz000
2017-05-06 22:09:35 -07:00
committed by GitHub
132 changed files with 1155 additions and 514 deletions
+9 -9
View File
@@ -7034,8 +7034,8 @@
"anI" = (
/obj/docking_port/stationary/random{
dir = 1;
id = "pod_asteroid1";
name = "asteroid"
id = "pod_lavaland1";
name = "lavaland"
},
/turf/open/space,
/area/space)
@@ -8103,7 +8103,7 @@
/obj/machinery/computer/shuttle/pod{
pixel_x = -32;
pixel_y = 0;
possible_destinations = "pod_asteroid1";
possible_destinations = "pod_lavaland1";
shuttleId = "pod1"
},
/obj/machinery/light/small{
@@ -40738,7 +40738,7 @@
/obj/machinery/computer/shuttle/pod{
pixel_x = 0;
pixel_y = 32;
possible_destinations = "pod_asteroid3";
possible_destinations = "pod_lavaland3";
shuttleId = "pod3"
},
/obj/item/device/radio/intercom{
@@ -40760,8 +40760,8 @@
"btw" = (
/obj/docking_port/stationary/random{
dir = 4;
id = "pod_asteroid3";
name = "asteroid"
id = "pod_lavaland3";
name = "lavaland"
},
/turf/open/space,
/area/space)
@@ -68963,8 +68963,8 @@
"crd" = (
/obj/docking_port/stationary/random{
dir = 8;
id = "pod_asteroid2";
name = "asteroid"
id = "pod_lavaland2";
name = "lavaland"
},
/turf/open/space,
/area/space)
@@ -68979,7 +68979,7 @@
/obj/machinery/computer/shuttle/pod{
pixel_x = 0;
pixel_y = -32;
possible_destinations = "pod_asteroid2";
possible_destinations = "pod_lavaland2";
shuttleId = "pod2"
},
/obj/structure/chair{
+19 -21
View File
@@ -142,15 +142,15 @@
/area/solar/auxstarboard)
"aap" = (
/obj/docking_port/stationary/random{
id = "pod_asteroid1";
name = "asteroid"
id = "pod_lavaland1";
name = "lavaland"
},
/turf/open/space,
/area/space)
"aaq" = (
/obj/docking_port/stationary/random{
id = "pod_asteroid2";
name = "asteroid"
id = "pod_lavaland2";
name = "lavaland"
},
/turf/open/space,
/area/space)
@@ -203,7 +203,7 @@
},
/obj/machinery/computer/shuttle/pod{
pixel_x = -32;
possible_destinations = "pod_asteroid1";
possible_destinations = "pod_lavaland1";
shuttleId = "pod1"
},
/obj/effect/turf_decal/stripes/line{
@@ -226,7 +226,7 @@
},
/obj/machinery/computer/shuttle/pod{
pixel_x = -32;
possible_destinations = "pod_asteroid2";
possible_destinations = "pod_lavaland2";
shuttleId = "pod2"
},
/obj/effect/turf_decal/stripes/line{
@@ -25977,7 +25977,7 @@
},
/obj/machinery/computer/shuttle/pod{
pixel_y = -32;
possible_destinations = "pod_asteroid3";
possible_destinations = "pod_lavaland3";
shuttleId = "pod3"
},
/obj/effect/turf_decal/stripes/line{
@@ -25996,8 +25996,8 @@
"aXK" = (
/obj/docking_port/stationary/random{
dir = 4;
id = "pod_asteroid4";
name = "asteroid"
id = "pod_lavaland4";
name = "lavaland"
},
/turf/open/space,
/area/space)
@@ -34793,7 +34793,6 @@
dir = 4
},
/turf/open/floor/plasteel{
desc = "";
icon_state = "L14"
},
/area/hallway/primary/central)
@@ -70986,7 +70985,6 @@
"cDW" = (
/obj/machinery/atmospherics/pipe/manifold/supply/hidden,
/turf/open/floor/plasteel{
desc = "";
icon_state = "L13";
name = "floor"
},
@@ -79512,8 +79510,13 @@
name = "Medbay Central"
})
"cUf" = (
/obj/machinery/smartfridge/chemistry,
/turf/closed/wall,
/obj/structure/grille,
/obj/machinery/door/poddoor/shutters/preopen{
id = "chemisttop";
name = "Chemisty Lobby Shutters"
},
/obj/structure/window/reinforced/fulltile,
/turf/open/floor/plating,
/area/medical/medbay{
name = "Medbay Central"
})
@@ -79536,14 +79539,9 @@
name = "Medbay Central"
})
"cUh" = (
/obj/structure/grille,
/obj/structure/window/reinforced/fulltile,
/obj/machinery/door/poddoor/shutters/preopen{
id = "chemisttop";
name = "Chemisty Lobby Shutters"
},
/obj/structure/disposalpipe/segment,
/turf/open/floor/plating,
/obj/machinery/smartfridge/chemistry,
/turf/closed/wall,
/area/medical/medbay{
name = "Medbay Central"
})
@@ -82189,6 +82187,7 @@
/obj/item/weapon/grenade/chem_grenade,
/obj/item/weapon/grenade/chem_grenade,
/obj/item/weapon/grenade/chem_grenade,
/obj/item/weapon/screwdriver,
/turf/open/floor/plasteel/whiteyellow/corner{
icon_state = "whiteyellowcorner";
dir = 8
@@ -96353,7 +96352,6 @@
},
/area/medical/morgue)
"dAn" = (
/turf/open/floor/plating,
/obj/effect/decal/cleanable/dirt,
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
icon_state = "manifold";
+12 -14
View File
@@ -1910,8 +1910,8 @@
/area/shuttle/pod_3)
"adG" = (
/obj/docking_port/stationary/random{
id = "pod_asteroid2";
name = "asteroid"
id = "pod_lavaland2";
name = "lavaland"
},
/turf/open/space,
/area/space)
@@ -1927,7 +1927,7 @@
},
/obj/machinery/computer/shuttle/pod{
pixel_x = -32;
possible_destinations = "pod_asteroid2";
possible_destinations = "pod_lavaland2";
shuttleId = "pod2"
},
/turf/open/floor/mineral/titanium/blue,
@@ -23696,7 +23696,7 @@
},
/obj/machinery/computer/shuttle/pod{
pixel_y = -32;
possible_destinations = "pod_asteroid3";
possible_destinations = "pod_lavaland3";
shuttleId = "pod3"
},
/turf/open/floor/mineral/titanium/blue,
@@ -27963,7 +27963,6 @@
dir = 4
},
/turf/open/floor/plasteel{
desc = "";
icon_state = "L13";
name = "floor"
},
@@ -28813,7 +28812,6 @@
icon_state = "4-8"
},
/turf/open/floor/plasteel{
desc = "";
icon_state = "L14"
},
/area/hallway/primary/central)
@@ -34140,8 +34138,8 @@
"bii" = (
/obj/docking_port/stationary/random{
dir = 4;
id = "pod_asteroid3";
name = "asteroid"
id = "pod_lavaland3";
name = "lavaland"
},
/turf/open/space,
/area/space)
@@ -86084,8 +86082,8 @@
/area/toxins/xenobiology)
"cSP" = (
/obj/docking_port/stationary/random{
id = "pod_asteroid1";
name = "asteroid"
id = "pod_lavaland1";
name = "lavaland"
},
/turf/open/space,
/area/space)
@@ -86175,7 +86173,7 @@
},
/obj/machinery/computer/shuttle/pod{
pixel_x = -32;
possible_destinations = "pod_asteroid1";
possible_destinations = "pod_lavaland1";
shuttleId = "pod1"
},
/turf/open/floor/mineral/titanium/blue,
@@ -86368,7 +86366,7 @@
},
/obj/machinery/computer/shuttle/pod{
pixel_y = -32;
possible_destinations = "pod_asteroid4";
possible_destinations = "pod_lavaland4";
shuttleId = "pod4"
},
/turf/open/floor/mineral/titanium/blue,
@@ -87162,8 +87160,8 @@
"cUL" = (
/obj/docking_port/stationary/random{
dir = 4;
id = "pod_asteroid4";
name = "asteroid"
id = "pod_lavaland4";
name = "lavaland"
},
/turf/open/space,
/area/space)
+48 -6
View File
@@ -7303,7 +7303,6 @@
icon_state = "1-2"
},
/turf/open/floor/plasteel{
desc = "";
icon_state = "L14"
},
/area/hallway/primary/central{
@@ -16523,6 +16522,9 @@
/obj/machinery/status_display{
pixel_x = -32
},
/obj/machinery/light{
dir = 8
},
/turf/open/floor/mineral/plastitanium/brig,
/area/shuttle/escape)
"aAb" = (
@@ -16558,6 +16560,9 @@
"aAf" = (
/obj/structure/table/reinforced,
/obj/item/weapon/storage/fancy/donut_box,
/obj/machinery/light{
dir = 4
},
/turf/open/floor/plasteel/vault{
dir = 8
},
@@ -24133,6 +24138,9 @@
},
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/delivery,
/obj/machinery/light{
dir = 8
},
/turf/open/floor/plasteel,
/area/shuttle/escape)
"aME" = (
@@ -24187,6 +24195,9 @@
/obj/machinery/status_display{
pixel_x = 32
},
/obj/machinery/light{
dir = 4
},
/turf/open/floor/plasteel/whiteblue/side{
dir = 5
},
@@ -25964,7 +25975,6 @@
icon_state = "4-8"
},
/turf/open/floor/plasteel{
desc = "";
icon_state = "L13";
name = "floor"
},
@@ -41920,6 +41930,38 @@
/area/ruin/unpowered{
name = "Asteroid"
})
"bvO" = (
/obj/machinery/light{
dir = 1
},
/turf/open/floor/plasteel/neutral/side{
dir = 1
},
/area/shuttle/escape)
"bvP" = (
/obj/structure/chair{
dir = 8
},
/obj/effect/turf_decal/bot,
/obj/machinery/light/small{
dir = 4
},
/turf/open/floor/plasteel,
/area/shuttle/escape)
"bvQ" = (
/obj/structure/chair{
dir = 4
},
/obj/effect/turf_decal/bot,
/obj/machinery/light/small{
dir = 8
},
/turf/open/floor/plasteel,
/area/shuttle/escape)
"bvR" = (
/obj/machinery/light,
/turf/open/floor/plasteel/neutral/side,
/area/shuttle/escape)
(1,1,1) = {"
aaa
@@ -94203,7 +94245,7 @@ aAb
axY
aDl
aEi
aEi
bvP
aEi
aEi
aEi
@@ -94715,13 +94757,13 @@ axY
aAc
axY
aCp
aDl
bvO
aEk
aEj
aGd
aEl
aEk
aJf
bvR
aKn
aLz
axY
@@ -95231,7 +95273,7 @@ aAd
aCq
aDl
aEm
aEm
bvQ
aEm
aEm
aEm
@@ -32850,10 +32850,6 @@
/turf/open/floor/plasteel/white,
/area/toxins/xenobiology)
"bnU" = (
/obj/machinery/door/airlock/research{
name = "Kill Room Access";
req_access_txt = "55"
},
/obj/structure/disposalpipe/segment{
dir = 4
},
+12 -14
View File
@@ -2501,7 +2501,7 @@
"afq" = (
/obj/machinery/computer/shuttle/pod{
pixel_y = -32;
possible_destinations = "pod_asteroid3";
possible_destinations = "pod_lavaland3";
shuttleId = "pod3"
},
/obj/structure/chair{
@@ -7787,8 +7787,8 @@
"aqG" = (
/obj/docking_port/stationary/random{
dir = 4;
id = "pod_asteroid3";
name = "asteroid"
id = "pod_lavaland3";
name = "lavaland"
},
/turf/open/space,
/area/space)
@@ -17330,7 +17330,6 @@
/area/hallway/primary/central)
"aMf" = (
/turf/open/floor/plasteel{
desc = "";
icon_state = "L13";
name = "floor"
},
@@ -17836,7 +17835,6 @@
/area/hallway/primary/central)
"aNB" = (
/turf/open/floor/plasteel{
desc = "";
icon_state = "L14"
},
/area/hallway/primary/central)
@@ -53823,8 +53821,8 @@
"cpe" = (
/obj/docking_port/stationary/random{
dir = 8;
id = "pod_asteroid2";
name = "asteroid"
id = "pod_lavaland2";
name = "lavaland"
},
/turf/open/space,
/area/space)
@@ -54079,7 +54077,7 @@
/obj/machinery/computer/shuttle/pod{
pixel_x = 0;
pixel_y = -32;
possible_destinations = "pod_asteroid2";
possible_destinations = "pod_lavaland2";
shuttleId = "pod2"
},
/obj/structure/chair{
@@ -57394,8 +57392,8 @@
"cwV" = (
/obj/docking_port/stationary/random{
dir = 8;
id = "pod_asteroid1";
name = "asteroid"
id = "pod_lavaland1";
name = "lavaland"
},
/turf/open/space,
/area/space)
@@ -57508,7 +57506,7 @@
/obj/machinery/computer/shuttle/pod{
pixel_x = 0;
pixel_y = -32;
possible_destinations = "pod_asteroid1";
possible_destinations = "pod_lavaland1";
shuttleId = "pod1"
},
/obj/structure/chair{
@@ -58424,7 +58422,7 @@
"czL" = (
/obj/machinery/computer/shuttle/pod{
pixel_y = -32;
possible_destinations = "pod_asteroid4";
possible_destinations = "pod_lavaland4";
shuttleId = "pod4"
},
/obj/structure/chair{
@@ -58455,8 +58453,8 @@
"czN" = (
/obj/docking_port/stationary/random{
dir = 4;
id = "pod_asteroid4";
name = "asteroid"
id = "pod_lavaland4";
name = "lavaland"
},
/turf/open/space,
/area/space)
+7 -7
View File
@@ -37,15 +37,15 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us
#define JUDGEMENT_CV_REQ 300
//general component/cooldown things
#define SLAB_PRODUCTION_TIME 900 //how long(deciseconds) slabs require to produce a single component; defaults to 1 minute 30 seconds
#define SLAB_PRODUCTION_TIME 450 //how long(deciseconds) slabs require to produce a single component; defaults to 45 seconds
#define SLAB_SERVANT_SLOWDOWN 300 //how much each servant above 5 slows down slab-based generation; defaults to 30 seconds per sevant
#define SLAB_SERVANT_SLOWDOWN 150 //how much each servant above 5 slows down slab-based generation; defaults to 15 seconds per sevant
#define SLAB_SLOWDOWN_MAXIMUM 2700 //maximum slowdown from additional servants; defaults to 4 minutes 30 seconds
#define SLAB_SLOWDOWN_MAXIMUM 1350 //maximum slowdown from additional servants; defaults to 2 minutes 15 seconds
#define CACHE_PRODUCTION_TIME 600 //how long(deciseconds) caches require to produce a component; defaults to 1 minute
#define CACHE_PRODUCTION_TIME 300 //how long(deciseconds) caches require to produce a component; defaults to 30 seconds
#define ACTIVE_CACHE_SLOWDOWN 100 //how many additional deciseconds caches take to produce a component for each linked cache; defaults to 10 seconds
#define ACTIVE_CACHE_SLOWDOWN 50 //how many additional deciseconds caches take to produce a component for each linked cache; defaults to 5 seconds
#define LOWER_PROB_PER_COMPONENT 10 //how much each component in the cache reduces the weight of getting another of that component type
@@ -87,9 +87,9 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us
#define GATEWAY_RATVAR_ARRIVAL 300 //when progress is at or above this, game over ratvar's here everybody go home
#define ARK_SUMMON_COST 3 //how many of each component an Ark costs to summon
#define ARK_SUMMON_COST 5 //how many of each component an Ark costs to summon
#define ARK_CONSUME_COST 7 //how many of each component an Ark needs to consume to activate
#define ARK_CONSUME_COST 15 //how many of each component an Ark needs to consume to activate
//Objective text define
#define CLOCKCULT_OBJECTIVE "Construct the Ark of the Clockwork Justicar and free Ratvar."
+1
View File
@@ -1342,6 +1342,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
//This prevents RCEs from badmins
//kevinz000 if you touch this I will hunt you down
GLOBAL_VAR_INIT(valid_HTTPSGet, FALSE)
GLOBAL_PROTECT(valid_HTTPSGet)
/proc/HTTPSGet(url)
if(findtext(url, "\""))
GLOB.valid_HTTPSGet = FALSE
@@ -5,7 +5,7 @@ PROCESSING_SUBSYSTEM_DEF(flightpacks)
stat_tag = "FM"
flags = SS_NO_INIT|SS_TICKER|SS_KEEP_TIMING
var/flightsuit_processing = FLIGHTSUIT_PROCESSING_FULL
var/flightsuit_processing = FLIGHTSUIT_PROCESSING_NONE
/datum/controller/subsystem/processing/flightpacks/Initialize()
sync_flightsuit_processing()
+2 -2
View File
@@ -625,8 +625,8 @@ SUBSYSTEM_DEF(ticker)
if(selected_tip)
m = selected_tip
else
var/list/randomtips = world.file2list("config/tips.txt")
var/list/memetips = world.file2list("config/sillytips.txt")
var/list/randomtips = world.file2list("strings/tips.txt")
var/list/memetips = world.file2list("strings/sillytips.txt")
if(randomtips.len && prob(95))
m = pick(randomtips)
else if(memetips.len)
-25
View File
@@ -1,25 +0,0 @@
diff a/code/datums/antagonists/datum_cult.dm b/code/datums/antagonists/datum_cult.dm (rejected hunks)
@@ -5,13 +5,20 @@
qdel(communion)
return ..()
+/datum/antagonist/cult/can_be_owned(datum/mind/new_owner)
+ . = ..()
+ if(.)
+ . = is_convertable_to_cult(new_owner.current)
+
/datum/antagonist/cult/on_gain()
. = ..()
- if(!owner)
- return
+ SSticker.mode.cult += owner
+ SSticker.mode.update_cult_icons_added(owner)
+ if(istype(SSticker.mode, /datum/game_mode/cult))
+ var/datum/game_mode/cult/C = SSticker.mode
+ C.memorize_cult_objectives(owner)
if(jobban_isbanned(owner.current, ROLE_CULTIST))
addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, owner.current, ROLE_CULTIST, ROLE_CULTIST), 0)
- SSticker.mode.update_cult_icons_added(owner)
owner.current.log_message("<font color=#960000>Has been converted to the cult of Nar'Sie!</font>", INDIVIDUAL_ATTACK_LOG)
/datum/antagonist/cult/apply_innate_effects(mob/living/mob_override)
+159
View File
@@ -0,0 +1,159 @@
#define HOLOPAD_MAX_DIAL_TIME 200
/mob/camera/aiEye/remote/holo/setLoc()
. = ..()
var/obj/machinery/holopad/H = origin
H.move_hologram(eye_user, loc)
//this datum manages it's own references
/datum/holocall
var/mob/living/user //the one that called
var/obj/machinery/holopad/calling_holopad //the one that sent the call
var/obj/machinery/holopad/connected_holopad //the one that answered the call (may be null)
var/list/dialed_holopads //all things called, will be cleared out to just connected_holopad once answered
var/mob/camera/aiEye/remote/holo/eye //user's eye, once connected
var/obj/effect/overlay/holo_pad_hologram/hologram //user's hologram, once connected
var/call_start_time
//creates a holocall made by `caller` from `calling_pad` to `callees`
/datum/holocall/New(mob/living/caller, obj/machinery/holopad/calling_pad, list/callees)
call_start_time = world.time
user = caller
calling_pad.outgoing_call = src
calling_holopad = calling_pad
dialed_holopads = list()
for(var/I in callees)
var/obj/machinery/holopad/H = I
if(!QDELETED(H) && H.is_operational())
dialed_holopads += H
LAZYADD(H.holo_calls, src)
if(!dialed_holopads.len)
calling_pad.say("Connection failure.")
qdel(src)
testing("Holocall started")
//cleans up ALL references :)
/datum/holocall/Destroy()
QDEL_NULL(eye)
user.reset_perspective()
user = null
hologram.HC = null
hologram = null
calling_holopad.outgoing_call = null
for(var/I in dialed_holopads)
var/obj/machinery/holopad/H = I
LAZYREMOVE(H.holo_calls, src)
dialed_holopads.Cut()
if(calling_holopad)
calling_holopad.SetLightsAndPower()
calling_holopad = null
if(connected_holopad)
connected_holopad.SetLightsAndPower()
connected_holopad = null
testing("Holocall destroyed")
return ..()
//Gracefully disconnects a holopad `H` from a call. Pads not in the call are ignored. Notifies participants of the disconnection
/datum/holocall/proc/Disconnect(obj/machinery/holopad/H)
testing("Holocall disconnect")
if(H == connected_holopad)
calling_holopad.say("[usr] disconnected.")
else if(H == calling_holopad && connected_holopad)
connected_holopad.say("[usr] disconnected.")
ConnectionFailure(H, TRUE)
//Forcefully disconnects a holopad `H` from a call. Pads not in the call are ignored.
/datum/holocall/proc/ConnectionFailure(obj/machinery/holopad/H, graceful = FALSE)
testing("Holocall connection failure: graceful [graceful]")
if(H == connected_holopad || H == calling_holopad)
if(!graceful)
calling_holopad.say("Connection failure.")
qdel(src)
return
LAZYREMOVE(H.holo_calls, src)
dialed_holopads -= H
if(!dialed_holopads.len)
if(graceful)
calling_holopad.say("Call rejected.")
testing("No recipients, terminating")
qdel(src)
//Answers a call made to a holopad `H` which cannot be the calling holopad. Pads not in the call are ignored
/datum/holocall/proc/Answer(obj/machinery/holopad/H)
testing("Holocall answer")
if(H == calling_holopad)
CRASH("How cute, a holopad tried to answer itself.")
if(!(H in dialed_holopads))
return
if(connected_holopad)
CRASH("Multi-connection holocall")
connected_holopad = H
for(var/I in dialed_holopads)
if(I == H)
continue
var/obj/machinery/holopad/Holo = I
LAZYREMOVE(Holo.holo_calls, src)
dialed_holopads -= Holo
for(var/I in H.holo_calls)
var/datum/holocall/HC = I
if(HC != src)
HC.Disconnect(H)
if(!Check())
return
hologram = H.activate_holo(user)
hologram.HC = src
//eyeobj code is horrid, this is the best copypasta I could make
eye = new
eye.origin = H
eye.eye_initialized = TRUE
eye.eye_user = user
eye.name = "Camera Eye ([user.name])"
user.remote_control = eye
user.reset_perspective(eye)
eye.setLoc(H.loc)
//Checks the validity of a holocall and qdels itself if it's not. Returns TRUE if valid, FALSE otherwise
/datum/holocall/proc/Check()
for(var/I in dialed_holopads)
var/obj/machinery/holopad/H = I
if(!H.is_operational())
ConnectionFailure(H)
if(QDELETED(src))
return FALSE
. = !QDELETED(user) && !user.incapacitated() && !QDELETED(calling_holopad) && calling_holopad.is_operational() && user.loc == calling_holopad.loc
if(.)
if(connected_holopad)
. = !QDELETED(connected_holopad) && connected_holopad.is_operational()
else
. = world.time < (call_start_time + HOLOPAD_MAX_DIAL_TIME)
if(!.)
calling_holopad.say("No answer recieved.")
calling_holopad.temp = ""
if(!.)
testing("Holocall Check fail")
qdel(src)
-2
View File
@@ -44,9 +44,7 @@
var/datum/job/assigned_job
var/list/datum/objective/objectives = list()
var/list/datum/objective/special_verbs = list()
var/list/cult_words = list()
var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button.
var/datum/faction/faction //associated faction
+1
View File
@@ -42,6 +42,7 @@
However, all the inhabitants seem to do is grow drugs and guns."
suffix = "lavaland_surface_seed_vault.dmm"
cost = 10
allow_duplicates = FALSE
/datum/map_template/ruin/lavaland/ash_walker
name = "Ash Walker Nest"
@@ -13,8 +13,6 @@
var/req_dna = 0 //amount of dna needed to use this ability. Changelings always have atleast 1
var/req_human = 0 //if you need to be human to use this ability
var/req_stat = CONSCIOUS // CONSCIOUS, UNCONSCIOUS or DEAD
var/genetic_damage = 0 // genetic damage caused by using the sting. Nothing to do with cloneloss.
var/max_genetic_damage = 100 // hard counter for spamming abilities. Not used/balanced much yet.
var/always_keep = 0 // important for abilities like revive that screw you if you lose them.
var/ignores_fakedeath = FALSE // usable with the FAKEDEATH flag
@@ -39,7 +37,7 @@
if(sting_action(user, target))
SSblackbox.add_details("changeling_powers",name)
sting_feedback(user, target)
take_chemical_cost(c)
c.chem_charges -= chemical_cost
/obj/effect/proc_holder/changeling/proc/sting_action(mob/user, mob/target)
return 0
@@ -47,10 +45,6 @@
/obj/effect/proc_holder/changeling/proc/sting_feedback(mob/user, mob/target)
return 0
/obj/effect/proc_holder/changeling/proc/take_chemical_cost(datum/changeling/changeling)
changeling.chem_charges -= chemical_cost
changeling.geneticdamage += genetic_damage
//Fairly important to remember to return 1 on success >.<
/obj/effect/proc_holder/changeling/proc/can_sting(mob/user, mob/target)
if(!ishuman(user) && !ismonkey(user)) //typecast everything from mob to carbon from this point onwards
@@ -71,9 +65,6 @@
if((user.status_flags & FAKEDEATH) && (!ignores_fakedeath))
to_chat(user, "<span class='warning'>We are incapacitated.</span>")
return 0
if(c.geneticdamage > max_genetic_damage)
to_chat(user, "<span class='warning'>Our genomes are still reassembling. We need time to recover first.</span>")
return 0
return 1
//used in /mob/Stat()
@@ -4,7 +4,6 @@
chemical_cost = 0
dna_cost = 0
req_human = 1
max_genetic_damage = 100
/obj/effect/proc_holder/changeling/absorbDNA/can_sting(mob/living/carbon/user)
if(!..())
@@ -5,9 +5,6 @@
chemical_cost = 30 //High cost to prevent spam
dna_cost = 2
req_human = 1
genetic_damage = 10
max_genetic_damage = 0
/obj/effect/proc_holder/changeling/biodegrade/sting_action(mob/living/carbon/human/user)
var/used = FALSE // only one form of shackles removed per use
@@ -5,9 +5,6 @@
dna_cost = 2
chemical_cost = 25
req_human = 1
genetic_damage = 10
max_genetic_damage = 50
/obj/effect/proc_holder/changeling/chameleon_skin/sting_action(mob/user)
var/mob/living/carbon/human/H = user //SHOULD always be human, because req_human = 1
@@ -5,8 +5,6 @@
dna_cost = 0
req_dna = 1
req_stat = DEAD
max_genetic_damage = 100
//Fake our own death and fully heal. You will appear to be dead but regenerate fully after a short delay.
/obj/effect/proc_holder/changeling/fakedeath/sting_action(mob/living/user)
@@ -2,10 +2,7 @@
name = "Human Form"
desc = "We change into a human."
chemical_cost = 5
genetic_damage = 3
req_dna = 1
max_genetic_damage = 3
//Transform into a human.
/obj/effect/proc_holder/changeling/humanform/sting_action(mob/living/carbon/user)
@@ -3,7 +3,6 @@
desc = "We debase ourselves and become lesser. We become a monkey."
chemical_cost = 5
dna_cost = 1
genetic_damage = 3
req_human = 1
//Transform into a monkey.
@@ -4,7 +4,6 @@
chemical_cost = 0
dna_cost = 0
req_human = 1
max_genetic_damage = 100
/obj/effect/proc_holder/changeling/linglink/can_sting(mob/living/carbon/user)
if(!..())
@@ -16,7 +16,6 @@
helptext = "Yell at Miauw and/or Perakp"
chemical_cost = 1000
dna_cost = -1
genetic_damage = 1000
var/silent = FALSE
var/weapon_type
@@ -67,7 +66,6 @@
helptext = "Yell at Miauw and/or Perakp"
chemical_cost = 1000
dna_cost = -1
genetic_damage = 1000
var/helmet_type = /obj/item
var/suit_type = /obj/item
@@ -89,7 +87,7 @@
return 1
var/mob/living/carbon/human/H = user
if(istype(H.wear_suit, suit_type) || istype(H.head, helmet_type))
H.visible_message("<span class='warning'>[H] casts off their [suit_name_simple]!</span>", "<span class='warning'>We cast off our [suit_name_simple][genetic_damage > 0 ? ", temporarily weakening our genomes." : "."]</span>", "<span class='italics'>You hear the organic matter ripping and tearing!</span>")
H.visible_message("<span class='warning'>[H] casts off their [suit_name_simple]!</span>", "<span class='warning'>We cast off our [suit_name_simple].</span>", "<span class='italics'>You hear the organic matter ripping and tearing!</span>")
H.temporarilyRemoveItemFromInventory(H.head, TRUE) //The qdel on dropped() takes care of it
H.temporarilyRemoveItemFromInventory(H.wear_suit, TRUE)
H.update_inv_wear_suit()
@@ -100,7 +98,6 @@
H.add_splatter_floor()
playsound(H.loc, 'sound/effects/splat.ogg', 50, 1) //So real sounds
changeling.geneticdamage += genetic_damage //Casting off a space suit leaves you weak for a few seconds.
changeling.chem_recharge_slowdown -= recharge_slowdown
return 1
@@ -139,9 +136,7 @@
helptext = "We may retract our armblade in the same manner as we form it. Cannot be used while in lesser form."
chemical_cost = 20
dna_cost = 2
genetic_damage = 10
req_human = 1
max_genetic_damage = 20
weapon_type = /obj/item/weapon/melee/arm_blade
weapon_name_simple = "blade"
@@ -217,9 +212,7 @@
and Harm will stun it, and stab it if we're also holding a sharp weapon. Cannot be used while in lesser form."
chemical_cost = 10
dna_cost = 2
genetic_damage = 5
req_human = 1
max_genetic_damage = 10
weapon_type = /obj/item/weapon/gun/magic/tentacle
weapon_name_simple = "tentacle"
silent = TRUE
@@ -381,9 +374,7 @@
helptext = "Organic tissue cannot resist damage forever; the shield will break after it is hit too much. The more genomes we absorb, the stronger it is. Cannot be used while in lesser form."
chemical_cost = 20
dna_cost = 1
genetic_damage = 12
req_human = 1
max_genetic_damage = 20
weapon_type = /obj/item/weapon/shield/changeling
weapon_name_simple = "shield"
@@ -430,12 +421,10 @@
/obj/effect/proc_holder/changeling/suit/organic_space_suit
name = "Organic Space Suit"
desc = "We grow an organic suit to protect ourselves from space exposure."
helptext = "We must constantly repair our form to make it space-proof, reducing chemical production while we are protected. Retreating the suit damages our genomes. Cannot be used in lesser form."
helptext = "We must constantly repair our form to make it space-proof, reducing chemical production while we are protected. Cannot be used in lesser form."
chemical_cost = 20
dna_cost = 2
genetic_damage = 8
req_human = 1
max_genetic_damage = 20
suit_type = /obj/item/clothing/suit/space/changeling
helmet_type = /obj/item/clothing/head/helmet/space/changeling
@@ -477,12 +466,10 @@
/obj/effect/proc_holder/changeling/suit/armor
name = "Chitinous Armor"
desc = "We turn our skin into tough chitin to protect us from damage."
helptext = "Upkeep of the armor requires a low expenditure of chemicals. The armor is strong against brute force, but does not provide much protection from lasers. Retreating the armor damages our genomes. Cannot be used in lesser form."
helptext = "Upkeep of the armor requires a low expenditure of chemicals. The armor is strong against brute force, but does not provide much protection from lasers. Cannot be used in lesser form."
chemical_cost = 20
dna_cost = 1
genetic_damage = 11
req_human = 1
max_genetic_damage = 20
recharge_slowdown = 0.25
suit_type = /obj/item/clothing/suit/armor/changeling
@@ -40,10 +40,9 @@
return
if(!AStar(user, target.loc, /turf/proc/Distance, user.mind.changeling.sting_range, simulated_only = 0))
return
if(target.mind && target.mind.changeling)
sting_feedback(user,target)
take_chemical_cost(user.mind.changeling)
return
if(target.mind && target.mind.changeling)
sting_feedback(user, target)
user.mind.changeling.chem_charges -= chemical_cost
return 1
/obj/effect/proc_holder/changeling/sting/sting_feedback(mob/user, mob/target)
@@ -62,7 +61,6 @@
sting_icon = "sting_transform"
chemical_cost = 40
dna_cost = 3
genetic_damage = 100
var/datum/changelingprofile/selected_dna = null
/obj/effect/proc_holder/changeling/sting/transformation/Click()
@@ -117,8 +115,6 @@
sting_icon = "sting_armblade"
chemical_cost = 20
dna_cost = 1
genetic_damage = 20
max_genetic_damage = 10
/obj/item/weapon/melee/arm_blade/false
desc = "A grotesque mass of flesh that used to be your arm. Although it looks dangerous at first, you can tell it's actually quite dull and useless."
@@ -5,7 +5,6 @@
dna_cost = 0
req_dna = 1
req_human = 1
max_genetic_damage = 3
/obj/item/clothing/glasses/changeling
name = "flesh"
@@ -54,8 +54,11 @@
clockwork_desc = "A sigil that will stun the next non-Servant to cross it."
icon_state = "sigildull"
layer = HIGH_SIGIL_LAYER
alpha = 60
alpha = 75
color = "#FAE48C"
light_range = 1.4
light_power = 0.4
light_color = "#FAE48C"
sigil_name = "Sigil of Transgression"
/obj/effect/clockwork/sigil/transgression/sigil_effects(mob/living/L)
@@ -326,13 +326,19 @@
if(production_time != SLAB_PRODUCTION_TIME+SLAB_SLOWDOWN_MAXIMUM)
production_text_addon = ", which increases for each human or silicon servant above <b>[SCRIPT_SERVANT_REQ]</b>"
production_time = production_time/600
var/production_text = "<b>[round(production_time)] minute\s"
var/list/production_text
if(round(production_time))
production_text = list("<b>[round(production_time)] minute\s")
if(production_time != round(production_time))
production_time -= round(production_time)
production_time *= 60
production_text += " and [round(production_time, 1)] second\s"
if(!LAZYLEN(production_text))
production_text = list("<b>[round(production_time, 1)] second\s")
else
production_text += " and [round(production_time, 1)] second\s"
production_text += "</b>"
production_text += production_text_addon
production_text = production_text.Join()
textlist = list("<font color=#BE8700 size=3><b><center>Chetr nyy hagehguf-naq-ubabe Ratvar.</center></b></font><br>\
\
@@ -13,6 +13,7 @@
speak_emote = list("clanks", "clinks", "clunks", "clangs")
verb_ask = "requests"
verb_exclaim = "proclaims"
verb_whisper = "imparts"
verb_yell = "harangues"
initial_languages = list(/datum/language/common, /datum/language/ratvar)
only_speaks_language = /datum/language/ratvar
@@ -272,7 +272,7 @@
var/static/prev_cost = 0
/datum/clockwork_scripture/create_object/tinkerers_cache/creation_update()
var/cache_cost_increase = min(round(GLOB.clockwork_caches*0.25), 5)
var/cache_cost_increase = min(round(GLOB.clockwork_caches*0.4), 10)
if(cache_cost_increase != prev_cost)
prev_cost = cache_cost_increase
consumed_components = list(BELLIGERENT_EYE = 0, VANGUARD_COGWHEEL = 0, GEIS_CAPACITOR = 0, REPLICANT_ALLOY = 1, HIEROPHANT_ANSIBLE = 0)
@@ -9,7 +9,7 @@
desc = "Taps the limitless power of Inath-neq, one of Ratvar's four generals. The benevolence of Inath-Neq will grant complete invulnerability to all Servants in range for fifteen seconds."
invocations = list("I call upon you, Vanguard!!", "Let the Resonant Cogs turn once more!!", "Grant me and my allies the strength to vanquish our foes!!")
channel_time = 100
consumed_components = list(VANGUARD_COGWHEEL = 4, GEIS_CAPACITOR = 2, REPLICANT_ALLOY = 2, HIEROPHANT_ANSIBLE = 2)
consumed_components = list(VANGUARD_COGWHEEL = 10, GEIS_CAPACITOR = 3, REPLICANT_ALLOY = 3, HIEROPHANT_ANSIBLE = 3)
usage_tip = "Servants affected by this scripture are only weak to things that outright destroy bodies, such as bombs or the singularity."
tier = SCRIPTURE_REVENANT
primary_component = VANGUARD_COGWHEEL
@@ -44,7 +44,7 @@
for all non-servant humans on the same z-level as them. The power of this scripture falls off somewhat with distance, and certain things may reduce its effects."
invocations = list("I call upon you, Fright!!", "Let your power shatter the sanity of the weak-minded!!", "Let your tendrils hold sway over all!!")
channel_time = 150
consumed_components = list(BELLIGERENT_EYE = 3, VANGUARD_COGWHEEL = 3, GEIS_CAPACITOR = 6, HIEROPHANT_ANSIBLE = 3)
consumed_components = list(BELLIGERENT_EYE = 6, VANGUARD_COGWHEEL = 6, GEIS_CAPACITOR = 10, HIEROPHANT_ANSIBLE = 6)
usage_tip = "Causes brain damage, hallucinations, confusion, and dizziness in massive amounts."
tier = SCRIPTURE_REVENANT
sort_priority = 3
@@ -108,7 +108,7 @@
clockwork proselytizers will charge very rapidly."
invocations = list("I call upon you, Armorer!!", "Let your machinations reign on this miserable station!!", "Let your power flow through the tools of your master!!")
channel_time = 150
consumed_components = list(BELLIGERENT_EYE = 3, VANGUARD_COGWHEEL = 3, GEIS_CAPACITOR = 3, REPLICANT_ALLOY = 6)
consumed_components = list(BELLIGERENT_EYE = 6, VANGUARD_COGWHEEL = 6, GEIS_CAPACITOR = 6, REPLICANT_ALLOY = 10)
usage_tip = "Ocular wardens will become empowered, clockwork proselytizers will require no alloy, tinkerer's daemons will produce twice as quickly, \
and interdiction lenses, mania motors, tinkerer's daemons, and clockwork obelisks will all require no power."
tier = SCRIPTURE_REVENANT
@@ -153,7 +153,7 @@
will be struck by devastating lightning bolts."
invocations = list("I call upon you, Amperage!!", "Let your energy flow through me!!", "Let your boundless power shatter stars!!")
channel_time = 100
consumed_components = list(BELLIGERENT_EYE = 2, GEIS_CAPACITOR = 2, REPLICANT_ALLOY = 2, HIEROPHANT_ANSIBLE = 4)
consumed_components = list(BELLIGERENT_EYE = 3, GEIS_CAPACITOR = 3, REPLICANT_ALLOY = 3, HIEROPHANT_ANSIBLE = 10)
usage_tip = "Struck targets will also be knocked down for about sixteen seconds."
tier = SCRIPTURE_REVENANT
primary_component = HIEROPHANT_ANSIBLE
@@ -9,7 +9,7 @@
desc = "Forms an automatic short-range turret which will automatically attack nearby unrestrained non-Servants that can see it."
invocations = list("Guardians...", "...of the Engine...", "...defend us!")
channel_time = 120
consumed_components = list(BELLIGERENT_EYE = 1, REPLICANT_ALLOY = 1)
consumed_components = list(BELLIGERENT_EYE = 2, REPLICANT_ALLOY = 1)
object_path = /obj/structure/destructible/clockwork/ocular_warden
creator_message = "<span class='brass'>You form an ocular warden, which will automatically attack nearby unrestrained non-Servants that can see it.</span>"
observer_message = "<span class='warning'>A brass eye takes shape and slowly rises into the air, its red iris glaring!</span>"
@@ -36,7 +36,7 @@
desc = "Creates a small shell fitted for soul vessels. Adding an active soul vessel to it results in a small construct with tools and an inbuilt proselytizer."
invocations = list("Call forth...", "...the workers of Armorer.")
channel_time = 60
consumed_components = list(BELLIGERENT_EYE = 1, HIEROPHANT_ANSIBLE = 1)
consumed_components = list(BELLIGERENT_EYE = 2, HIEROPHANT_ANSIBLE = 1)
object_path = /obj/structure/destructible/clockwork/shell/cogscarab
creator_message = "<span class='brass'>You form a cogscarab, a constructor soul vessel receptacle.</span>"
observer_message = "<span class='warning'>The slab disgorges a puddle of black metal that contracts and forms into a strange shell!</span>"
@@ -56,7 +56,7 @@
Matrices have drained from non-Servants. Dead Servants can be revived by this sigil if there is vitality equal to the target Servant's non-oxygen damage."
invocations = list("Divinity...", "...steal their life...", "...for these shells!")
channel_time = 60
consumed_components = list(BELLIGERENT_EYE = 1, VANGUARD_COGWHEEL = 1)
consumed_components = list(BELLIGERENT_EYE = 1, VANGUARD_COGWHEEL = 2)
whispered = TRUE
object_path = /obj/effect/clockwork/sigil/vitality
creator_message = "<span class='brass'>A vitality matrix appears below you. It will drain life from non-Servants and heal Servants that cross it.</span>"
@@ -77,7 +77,7 @@
chant_invocations = list("Mend our dents!", "Heal our scratches!", "Repair our gears!")
chant_amount = 10
chant_interval = 20
consumed_components = list(VANGUARD_COGWHEEL = 1, REPLICANT_ALLOY = 1)
consumed_components = list(VANGUARD_COGWHEEL = 2, REPLICANT_ALLOY = 1)
usage_tip = "This is a very effective way to rapidly reinforce a base after an attack."
tier = SCRIPTURE_SCRIPT
primary_component = VANGUARD_COGWHEEL
@@ -187,7 +187,7 @@
desc = "Places a luminous sigil that will enslave any valid beings standing on it after a time."
invocations = list("Divinity, enlighten...", "...those who trespass here!")
channel_time = 60
consumed_components = list(BELLIGERENT_EYE = 1, GEIS_CAPACITOR = 1)
consumed_components = list(BELLIGERENT_EYE = 1, GEIS_CAPACITOR = 2)
whispered = TRUE
object_path = /obj/effect/clockwork/sigil/submission
creator_message = "<span class='brass'>A luminous sigil appears below you. The next non-servant to cross it will be enslaved after a brief time if they do not move.</span>"
@@ -207,7 +207,7 @@
desc = "Forms an ancient positronic brain with an overriding directive to serve Ratvar."
invocations = list("Herd the souls of...", "...the blasphemous damned!")
channel_time = 30
consumed_components = list(VANGUARD_COGWHEEL = 1, GEIS_CAPACITOR = 1)
consumed_components = list(VANGUARD_COGWHEEL = 1, GEIS_CAPACITOR = 2)
whispered = TRUE
object_path = /obj/item/device/mmi/posibrain/soul_vessel
creator_message = "<span class='brass'>You form a soul vessel, which can be used in-hand to attract spirits, or used on an unconscious or dead human to extract their consciousness.</span>"
@@ -227,7 +227,7 @@
desc = "Forms a device that, when used on certain objects, converts them into their Ratvarian equivalents. It requires power to function."
invocations = list("With this device...", "...his presence shall be made known.")
channel_time = 20
consumed_components = list(GEIS_CAPACITOR = 1, REPLICANT_ALLOY = 1)
consumed_components = list(GEIS_CAPACITOR = 1, REPLICANT_ALLOY = 2)
whispered = TRUE
object_path = /obj/item/clockwork/clockwork_proselytizer/preloaded
creator_message = "<span class='brass'>You form a clockwork proselytizer.</span>"
@@ -248,7 +248,7 @@
vanish three minutes after being summoned."
invocations = list("Grant me...", "...the might of brass!")
channel_time = 20
consumed_components = list(REPLICANT_ALLOY = 1, HIEROPHANT_ANSIBLE = 1)
consumed_components = list(REPLICANT_ALLOY = 2, HIEROPHANT_ANSIBLE = 1)
whispered = TRUE
usage_tip = "You can impale human targets with the spear by pulling them, then attacking. Throwing the spear at a mob will do massive damage and stun them, but break the spear."
tier = SCRIPTURE_SCRIPT
@@ -307,7 +307,7 @@
Each servant assisting in the invocation adds one additional use and four additional seconds to the gateway's uses and duration."
invocations = list("Spatial Gateway...", "...activate!")
channel_time = 80
consumed_components = list(VANGUARD_COGWHEEL = 1, HIEROPHANT_ANSIBLE = 1)
consumed_components = list(VANGUARD_COGWHEEL = 1, HIEROPHANT_ANSIBLE = 2)
multiple_invokers_used = TRUE
multiple_invokers_optional = TRUE
usage_tip = "This gateway is strictly one-way and will only allow things through the invoker's portal."
@@ -356,7 +356,7 @@
chant_invocations = list("Use charge to kill!", "Slay with power!", "Hunt with energy!")
chant_amount = 4
chant_interval = 5
consumed_components = list(GEIS_CAPACITOR = 1, HIEROPHANT_ANSIBLE = 1)
consumed_components = list(GEIS_CAPACITOR = 1, HIEROPHANT_ANSIBLE = 2)
usage_tip = "Though it requires you to stand still, this scripture can do massive damage."
tier = SCRIPTURE_SCRIPT
primary_component = HIEROPHANT_ANSIBLE
@@ -28,7 +28,7 @@
var/mutable_appearance/alert_overlay = mutable_appearance('icons/effects/clockwork_effects.dmi', "ratvar_alert")
var/area/A = get_area(src)
notify_ghosts("The Justiciar's light calls to you! Reach out to Ratvar in [A.name] to be granted a shell to spread his glory!", null, source = src, alert_overlay = alert_overlay)
INVOKE_ASYNC(SSshuttle.emergency, /obj/docking_port/mobile/emergency..proc/request, null, 0)
INVOKE_ASYNC(SSshuttle.emergency, /obj/docking_port/mobile/emergency..proc/request, null, 0, 0)
/obj/structure/destructible/clockwork/massive/ratvar/Destroy()
GLOB.ratvar_awakens--
@@ -18,7 +18,7 @@
var/static/mutable_appearance/component_glow = mutable_appearance('icons/obj/clockwork_objects.dmi', "t_random_component")
var/component_id_to_produce
var/production_time = 0 //last time we produced a component
var/production_cooldown = 120
var/production_cooldown = 60
/obj/structure/destructible/clockwork/powered/tinkerers_daemon/Initialize()
. = ..()
+1 -1
View File
@@ -133,7 +133,7 @@ This file contains the arcane tome files.
text += "<font color='red'><b>Talisman of Armaments</b></font><br>The Talisman of Arming will equip the user with armored robes, a backpack, an eldritch longsword, an empowered bola, and a pair of boots. Any items that cannot \
be equipped will not be summoned. Attacking a fellow cultist with it will instead equip them.<br><br>"
text += "<font color='red'><b>Talisman of Horrors</b></font><br>The Talisman of Horror must be applied directly to the victim, it will shatter your victim's mind with visions of the endtimes that may incapitate them.<br><br>"
text += "<font color='red'><b>Talisman of Horrors</b></font><br>The Talisman of Horror, unlike other talismans, can be applied at range, without the victim noticing. It will cause the victim to have severe hallucinations after a short while.<br><br>"
text += "<font color='red'><b>Talisman of Shackling</b></font><br>The Talisman of Shackling must be applied directly to the victim, it has 4 uses and cuffs victims with magic shackles that disappear when removed.<br><br>"
+4 -4
View File
@@ -293,12 +293,12 @@
invocation = "Lo'Nab Na'Dm!"
creation_time = 80
/obj/item/weapon/paper/talisman/horror/attack(mob/living/target, mob/living/user)
if(iscultist(user))
to_chat(user, "<span class='cultitalic'>You disturb [target] with visons of the end!</span>")
/obj/item/weapon/paper/talisman/horror/afterattack(mob/living/target, mob/living/user)
if(iscultist(user) && (get_dist(user, target) < 7))
to_chat(user, "<span class='cultitalic'>You disturb [target] with visions of madness!</span>")
if(iscarbon(target))
var/mob/living/carbon/H = target
H.reagents.add_reagent("mindbreaker", 25)
H.reagents.add_reagent("mindbreaker", 12)
if(is_servant_of_ratvar(target))
to_chat(target, "<span class='userdanger'>You see a brief but horrible vision of Ratvar, rusted and scrapped, being torn apart.</span>")
target.emote("scream")
+2 -1
View File
@@ -13,6 +13,7 @@
var/list/territory = list()
var/list/territory_new = list()
var/list/territory_lost = list()
var/recalls = 1
var/dom_attempts = 2
var/points = 15
var/datum/atom_hud/antag/gang/ganghud
@@ -262,4 +263,4 @@
ganghud = new()
/datum/gang/multiverse/income()
return
return
+4
View File
@@ -168,6 +168,9 @@
if(recalling)
to_chat(usr, "<span class='warning'>Error: Recall already in progress.</span>")
return 0
if(!gang.recalls)
to_chat(usr, "<span class='warning'>Error: Unable to access communication arrays. Firewall has logged our signature and is blocking all further attempts.</span>")
gang.message_gangtools("[usr] is attempting to recall the emergency shuttle.")
recalling = 1
@@ -209,6 +212,7 @@
userturf = get_turf(user)
if(userturf.z == 1) //Check one more time that they are on station.
if(SSshuttle.cancelEvac(user))
gang.recalls -= 1
return 1
to_chat(loc, "<span class='info'>\icon[src]No response recieved. Emergency shuttle cannot be recalled at this time.</span>")
@@ -14,6 +14,7 @@
var/icon_reveal = "revenant_revealed"
var/icon_stun = "revenant_stun"
var/icon_drain = "revenant_draining"
var/stasis = 0
incorporeal_move = 3
invisibility = INVISIBILITY_REVENANT
health = INFINITY //Revenants don't use health, they use essence instead
@@ -94,6 +95,8 @@
//Life, Stat, Hud Updates, and Say
/mob/living/simple_animal/revenant/Life()
if(stasis)
return
if(revealed && essence <= 0)
death()
if(unreveal_time && world.time >= unreveal_time)
@@ -200,9 +203,8 @@
death()
/mob/living/simple_animal/revenant/death()
if(!revealed || stat == DEAD) //Revenants cannot die if they aren't revealed //or are already dead
if(!revealed || stasis) //Revenants cannot die if they aren't revealed //or are already dead
return 0
..(1)
to_chat(src, "<span class='revendanger'>NO! No... it's too late, you can feel your essence [pick("breaking apart", "drifting away")]...</span>")
notransform = TRUE
revealed = TRUE
@@ -217,9 +219,12 @@
var/reforming_essence = essence_regen_cap //retain the gained essence capacity
var/obj/item/weapon/ectoplasm/revenant/R = new(get_turf(src))
R.essence = max(reforming_essence - 15 * perfectsouls, 75) //minus any perfect souls
R.client_to_revive = src.client //If the essence reforms, the old revenant is put back in the body
ghostize()
qdel(src)
R.client_to_revive = client //If the essence reforms, the old revenant is put back in the body
R.revenant = src
invisibility = INVISIBILITY_ABSTRACT
revealed = 0
stasis = 1
ghostize(0)//Don't re-enter invisible corpse
return
@@ -302,6 +307,18 @@
to_chat(src, "<span class='revenminor'>Lost [essence_amt]E[source ? " from [source]":""].</span>")
return 1
/mob/living/simple_animal/revenant/proc/death_reset()
revealed = FALSE
unreveal_time = 0
notransform = 0
unstun_time = 0
inhibited = FALSE
draining = FALSE
incorporeal_move = 3
invisibility = INVISIBILITY_REVENANT
alpha=255
stasis = 0
//reforming
/obj/item/weapon/ectoplasm/revenant
@@ -314,11 +331,15 @@
var/reforming = TRUE
var/inert = FALSE
var/client/client_to_revive
var/mob/living/simple_animal/revenant/revenant
/obj/item/weapon/ectoplasm/revenant/New()
..()
addtimer(CALLBACK(src, .proc/try_reform), 600)
/obj/item/weapon/ectoplasm/revenant/proc/scatter()
qdel(src)
/obj/item/weapon/ectoplasm/revenant/proc/try_reform()
if(reforming)
reforming = FALSE
@@ -333,14 +354,14 @@
user.visible_message("<span class='notice'>[user] scatters [src] in all directions.</span>", \
"<span class='notice'>You scatter [src] across the area. The particles slowly fade away.</span>")
user.drop_item()
qdel(src)
scatter()
/obj/item/weapon/ectoplasm/revenant/throw_impact(atom/hit_atom)
..()
if(inert)
return
visible_message("<span class='notice'>[src] breaks into particles upon impact, which fade away to nothingness.</span>")
qdel(src)
scatter()
/obj/item/weapon/ectoplasm/revenant/examine(mob/user)
..()
@@ -350,47 +371,51 @@
to_chat(user, "<span class='revenwarning'>It is shifting and distorted. It would be wise to destroy this.</span>")
/obj/item/weapon/ectoplasm/revenant/proc/reform()
if(QDELETED(src) || inert)
if(QDELETED(src) || QDELETED(revenant) || inert)
return
var/key_of_revenant
message_admins("Revenant ectoplasm was left undestroyed for 1 minute and is reforming into a new revenant.")
loc = get_turf(src) //In case it's in a backpack or someone's hand
var/mob/living/simple_animal/revenant/R = new(get_turf(src))
revenant.forceMove(loc)
if(client_to_revive)
for(var/mob/M in GLOB.dead_mob_list)
if(M.client == client_to_revive) //Only recreates the mob if the mob the client is in is dead
R.client = client_to_revive
revenant.client = client_to_revive
key_of_revenant = client_to_revive.key
if(!key_of_revenant)
message_admins("The new revenant's old client either could not be found or is in a new, living mob - grabbing a random candidate instead...")
var/list/candidates = get_candidates(ROLE_REVENANT)
var/list/candidates = pollCandidatesForMob("Do you want to be [revenant.name] (reforming)?", "revenant", null, ROLE_REVENANT, 50, revenant)
if(!candidates.len)
qdel(R)
qdel(revenant)
message_admins("No candidates were found for the new revenant. Oh well!")
inert = TRUE
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
return
var/client/C = pick(candidates)
revenant.client = C
key_of_revenant = C.key
if(!key_of_revenant)
qdel(R)
qdel(revenant)
message_admins("No ckey was found for the new revenant. Oh well!")
inert = TRUE
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
return
var/datum/mind/player_mind = new /datum/mind(key_of_revenant)
R.essence_regen_cap = essence
R.essence = R.essence_regen_cap
player_mind.active = 1
player_mind.transfer_to(R)
player_mind.assigned_role = "revenant"
player_mind.special_role = "Revenant"
SSticker.mode.traitors |= player_mind
message_admins("[key_of_revenant] has been [client_to_revive ? "re":""]made into a revenant by reforming ectoplasm.")
log_game("[key_of_revenant] was [client_to_revive ? "re":""]made as a revenant by reforming ectoplasm.")
visible_message("<span class='revenboldnotice'>[src] suddenly rises into the air before fading away.</span>")
revenant.essence = essence
revenant.essence_regen_cap = essence
revenant.death_reset()
revenant.key = key_of_revenant
revenant = null
qdel(src)
/obj/item/weapon/ectoplasm/revenant/Destroy()
if(!QDELETED(revenant))
qdel(revenant)
..()
//objectives
/datum/objective/revenant
@@ -58,7 +58,12 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E
/obj/machinery/computer/telecrystals/uplinker/proc/donateTC(amt, addLog = 1)
if(uplinkholder && linkedboss)
if(amt <= uplinkholder.hidden_uplink.telecrystals)
if(amt < 0)
linkedboss.storedcrystals += uplinkholder.hidden_uplink.telecrystals
if(addLog)
linkedboss.logTransfer("[src] donated [uplinkholder.hidden_uplink.telecrystals] telecrystals to [linkedboss].")
uplinkholder.hidden_uplink.telecrystals = 0
else if(amt <= uplinkholder.hidden_uplink.telecrystals)
uplinkholder.hidden_uplink.telecrystals -= amt
linkedboss.storedcrystals += amt
if(addLog)
@@ -66,7 +71,12 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E
/obj/machinery/computer/telecrystals/uplinker/proc/giveTC(amt, addLog = 1)
if(uplinkholder && linkedboss)
if(amt <= linkedboss.storedcrystals)
if(amt < 0)
uplinkholder.hidden_uplink.telecrystals += linkedboss.storedcrystals
if(addLog)
linkedboss.logTransfer("[src] received [linkedboss.storedcrystals] telecrystals from [linkedboss].")
linkedboss.storedcrystals = 0
else if(amt <= linkedboss.storedcrystals)
uplinkholder.hidden_uplink.telecrystals += amt
linkedboss.storedcrystals -= amt
if(addLog)
@@ -89,7 +99,7 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E
if(uplinkholder)
dat += "[uplinkholder.hidden_uplink.telecrystals] telecrystals remain in this uplink.<BR>"
if(linkedboss)
dat += "Donate TC: <a href='byond://?src=\ref[src];donate1=1'>1</a> | <a href='byond://?src=\ref[src];donate5=1'>5</a>"
dat += "Donate TC: <a href='byond://?src=\ref[src];donate=1'>1</a> | <a href='byond://?src=\ref[src];donate=5'>5</a> | <a href='byond://?src=\ref[src];donate=-1'>All</a>"
dat += "<br><a href='byond://?src=\ref[src];eject=1'>Eject Uplink</a>"
@@ -103,11 +113,9 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E
if(..())
return
if(href_list["donate1"])
donateTC(1)
if(href_list["donate5"])
donateTC(5)
if(href_list["donate"])
var/tcamt = text2num(href_list["donate"])
donateTC(tcamt)
if(href_list["eject"])
ejectuplink()
@@ -162,7 +170,7 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E
var/dat = ""
dat += "<a href='byond://?src=\ref[src];scan=1'>Scan for TC stations.</a><BR>"
dat += "This [src] has [storedcrystals] telecrystals available for distribution. <BR>"
dat += "[storedcrystals] telecrystals are available for distribution. <BR>"
dat += "<BR><BR>"
@@ -171,10 +179,10 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E
if(A.uplinkholder)
dat += "[A.uplinkholder.hidden_uplink.telecrystals] telecrystals."
if(storedcrystals)
dat+= "<BR>Add TC: <a href ='?src=\ref[src];give1=\ref[A]'>1</a> | <a href ='?src=\ref[src];give5=\ref[A]'>5</a>"
dat+= "<BR>Add TC: <a href ='?src=\ref[src];target=\ref[A];give=1'>1</a> | <a href ='?src=\ref[src];target=\ref[A];give=5'>5</a> | <a href ='?src=\ref[src];target=\ref[A];give=10'>10</a> | <a href ='?src=\ref[src];target=\ref[A];give=-1'>All</a>"
dat += "<BR>"
if(TCstations.len)
if(TCstations.len && storedcrystals)
dat += "<BR><BR><a href='byond://?src=\ref[src];distrib=1'>Evenly distribute remaining TC.</a><BR><BR>"
@@ -195,13 +203,11 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E
if(href_list["scan"])
scanUplinkers()
if(href_list["give1"])
var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["give1"])
A.giveTC(1)
if(href_list["give5"])
var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["give5"])
A.giveTC(5)
if(href_list["give"])
var/tcamt = text2num(href_list["give"])
if(TCstations.len) // sanity
var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["target"]) in TCstations
A.giveTC(tcamt)
if(href_list["distrib"])
var/sanity = 0
+220 -74
View File
@@ -26,14 +26,13 @@ Possible to do for anyone motivated enough:
#define HOLOPAD_PASSIVE_POWER_USAGE 1
#define HOLOGRAM_POWER_USAGE 2
#define RANGE_BASED 4
#define AREA_BASED 6
GLOBAL_LIST_EMPTY(holopads)
#define HOLOPAD_MODE RANGE_BASED
/obj/machinery/holopad
name = "\improper AI holopad"
desc = "It's a floor-mounted device for projecting holographic images. It is activated remotely."
name = "Holopad"
desc = "It's a floor-mounted device for projecting holographic images."
icon_state = "holopad0"
layer = LOW_OBJ_LAYER
flags = HEAR
@@ -44,21 +43,32 @@ Possible to do for anyone motivated enough:
obj_integrity = 300
max_integrity = 300
armor = list(melee = 50, bullet = 20, laser = 20, energy = 20, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 0)
var/list/masters = list()//List of AIs that use the holopad
var/list/masters = list()//List of living mobs that use the holopad
var/last_request = 0 //to prevent request spam. ~Carn
var/holo_range = 5 // Change to change how far the AI can move away from the holopad before deactivating.
var/temp = ""
var/list/holo_calls //array of /datum/holocalls
var/datum/holocall/outgoing_call //do not modify the datums only check and call the public procs
var/static/force_answer_call = FALSE //Calls will be automatically answered after a couple rings, here for debugging
var/static/list/holopads = list()
/obj/machinery/holopad/New()
/obj/machinery/holopad/Initialize()
..()
var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/holopad(null)
B.apply_default_parts(src)
holopads += src
/obj/machinery/holopad/Destroy()
for (var/mob/living/silicon/ai/master in masters)
clear_holo(master)
if(outgoing_call)
LAZYADD(holo_calls, outgoing_call)
for(var/I in holo_calls)
var/datum/holocall/HC = I
HC.ConnectionFailure(src)
LAZYCLEARLIST(holo_calls)
for (var/I in masters)
clear_holo(I)
holopads -= src
return ..()
@@ -91,20 +101,58 @@ Possible to do for anyone motivated enough:
return
return ..()
/obj/machinery/holopad/proc/CheckCallClose()
for(var/I in holo_calls)
var/datum/holocall/HC = I
if(usr == HC.eye)
HC.Disconnect(HC.calling_holopad) //disconnect via clicking the called holopad
return TRUE
return FALSE
/obj/machinery/holopad/Click(location,control,params)
if(!CheckCallClose())
return ..()
/obj/machinery/holopad/AltClick(mob/living/carbon/human/user)
interact(user)
if(!CheckCallClose())
interact(user)
/obj/machinery/holopad/interact(mob/living/carbon/human/user) //Carn: Hologram requests.
if(!istype(user))
return
if(user.stat || !is_operational())
if(outgoing_call || user.incapacitated() || !is_operational())
return
user.set_machine(src)
var/dat
if(temp)
dat = temp
else
dat = "<A href='?src=\ref[src];AIrequest=1'>request an AI's presence.</A>"
dat = "<a href='?src=\ref[src];AIrequest=1'>Request an AI's presence.</a><br>"
dat += "<a href='?src=\ref[src];Holocall=1'>Call another holopad.</a><br>"
if(LAZYLEN(holo_calls))
dat += "=====================================================<br>"
var/one_answered_call = FALSE
var/one_unanswered_call = FALSE
for(var/I in holo_calls)
var/datum/holocall/HC = I
if(HC.connected_holopad != src)
dat += "<a href='?src=\ref[src];connectcall=\ref[HC]'>Answer call from [get_area(HC.calling_holopad)].</a><br>"
one_unanswered_call = TRUE
else
one_answered_call = TRUE
if(one_answered_call && one_unanswered_call)
dat += "=====================================================<br>"
//we loop twice for formatting
for(var/I in holo_calls)
var/datum/holocall/HC = I
if(HC.connected_holopad == src)
dat += "<a href='?src=\ref[src];disconnectcall=\ref[HC]'>Disconnect call from [HC.user].</a><br>"
var/datum/browser/popup = new(user, "holopad", name, 300, 130)
popup.set_content(dat)
@@ -112,7 +160,10 @@ Possible to do for anyone motivated enough:
popup.open()
/obj/machinery/holopad/Topic(href, href_list)
if(..() || !is_operational())
if(..() || isAI(usr))
return
add_fingerprint(usr)
if(!is_operational())
return
if (href_list["AIrequest"])
if(last_request + 200 < world.time)
@@ -120,7 +171,7 @@ Possible to do for anyone motivated enough:
temp = "You requested an AI's presence.<BR>"
temp += "<A href='?src=\ref[src];mainmenu=1'>Main Menu</A>"
var/area/area = get_area(src)
for(var/mob/living/silicon/ai/AI in GLOB.living_mob_list)
for(var/mob/living/silicon/ai/AI in GLOB.silicon_mobs)
if(!AI.client)
continue
to_chat(AI, "<span class='info'>Your presence is requested at <a href='?src=\ref[AI];jumptoholopad=\ref[src]'>\the [area]</a>.</span>")
@@ -128,12 +179,49 @@ Possible to do for anyone motivated enough:
temp = "A request for AI presence was already sent recently.<BR>"
temp += "<A href='?src=\ref[src];mainmenu=1'>Main Menu</A>"
else if(href_list["mainmenu"])
else if(href_list["Holocall"])
if(outgoing_call)
return
temp = "You must stand on the holopad to make a call!<br>"
temp += "<A href='?src=\ref[src];mainmenu=1'>Main Menu</A>"
if(usr.loc == loc)
var/list/callnames = list()
for(var/I in holopads)
var/area/A = get_area(I)
if(A)
LAZYADD(callnames[A], I)
callnames -= get_area(src)
var/result = input(usr, "Choose an area to call", "Holocall") as null|anything in callnames
if(QDELETED(usr) || !result || outgoing_call)
return
if(usr.loc == loc)
temp = "Dialing...<br>"
temp += "<A href='?src=\ref[src];mainmenu=1'>Main Menu</A>"
new /datum/holocall(usr, src, callnames[result])
else if(href_list["connectcall"])
var/datum/holocall/call_to_connect = locate(href_list["connectcall"])
if(!QDELETED(call_to_connect))
call_to_connect.Answer(src)
temp = ""
updateDialog()
add_fingerprint(usr)
else if(href_list["disconnectcall"])
var/datum/holocall/call_to_disconnect = locate(href_list["disconnectcall"])
if(!QDELETED(call_to_disconnect))
call_to_disconnect.Disconnect(src)
temp = ""
else if(href_list["mainmenu"])
temp = ""
if(outgoing_call)
outgoing_call.Disconnect()
updateDialog()
//do not allow AIs to answer calls or people will use it to meta the AI sattelite
/obj/machinery/holopad/attack_ai(mob/living/silicon/ai/user)
if (!istype(user))
return
@@ -148,39 +236,75 @@ Possible to do for anyone motivated enough:
clear_holo(user)
/obj/machinery/holopad/process()
if(masters.len)//If there is a hologram.
for (var/mob/living/silicon/ai/master in masters)
if(master && !master.stat && master.client && master.eyeobj)//If there is an AI attached, it's not incapacitated, it has a client, and the client eye is centered on the projector.
if(!(stat & NOPOWER))//If the machine has power.
if(HOLOPAD_MODE == RANGE_BASED)
if(get_dist(master.eyeobj, src) <= holo_range)
return TRUE
else
var/obj/machinery/holopad/pad_close = get_closest_atom(/obj/machinery/holopad, holopads, master.eyeobj)
if(get_dist(pad_close, master.eyeobj) <= holo_range)
var/obj/effect/overlay/holo_pad_hologram/h = masters[master]
unset_holo(master)
pad_close.set_holo(master, h)
return TRUE
for(var/I in masters)
var/mob/living/master = I
var/mob/living/silicon/ai/AI = master
if(!istype(AI))
AI = null
else if (HOLOPAD_MODE == AREA_BASED)
if(!QDELETED(master) && !master.incapacitated() && master.client && (!AI || AI.eyeobj))//If there is an AI attached, it's not incapacitated, it has a client, and the client eye is centered on the projector.
if(is_operational())//If the machine has power.
if(AI) //ais are range based
if(get_dist(AI.eyeobj, src) <= holo_range)
continue
else
var/obj/machinery/holopad/pad_close = get_closest_atom(/obj/machinery/holopad, holopads, AI.eyeobj)
if(get_dist(pad_close, AI.eyeobj) <= holo_range)
var/obj/effect/overlay/holo_pad_hologram/h = masters[master]
unset_holo(master)
pad_close.set_holo(master, h)
continue
else
continue
clear_holo(master)//If not, we want to get rid of the hologram.
var/area/holo_area = get_area(src)
var/area/eye_area = get_area(master.eyeobj)
if(outgoing_call)
outgoing_call.Check()
if(eye_area in holo_area.related)
return TRUE
for(var/I in holo_calls)
var/datum/holocall/HC = I
if(HC.connected_holopad != src)
if(force_answer_call && world.time > (HC.call_start_time + (HOLOPAD_MAX_DIAL_TIME / 2)))
HC.Answer(src)
break
if(outgoing_call)
HC.Disconnect(src)//can't answer calls while calling
else
playsound(src, 'sound/machines/twobeep.ogg', 100) //bring, bring!
clear_holo(master)//If not, we want to get rid of the hologram.
return TRUE
/obj/machinery/holopad/proc/activate_holo(mob/living/user)
var/mob/living/silicon/ai/AI = user
if(!istype(AI))
AI = null
/obj/machinery/holopad/proc/activate_holo(mob/living/silicon/ai/user)
if(!(stat & NOPOWER) && user.eyeobj.loc == src.loc)//If the projector has power and client eye is on it
if (istype(user.current, /obj/machinery/holopad))
if(is_operational() && (!AI || AI.eyeobj.loc == loc))//If the projector has power and client eye is on it
if (AI && istype(AI.current, /obj/machinery/holopad))
to_chat(user, "<span class='danger'>ERROR:</span> \black Image feed in progress.")
return
create_holo(user)//Create one.
src.visible_message("A holographic image of [user] flicks to life right before your eyes!")
var/obj/effect/overlay/holo_pad_hologram/Hologram = new(loc)//Spawn a blank effect at the location.
if(AI)
Hologram.icon = AI.holo_icon
else //make it like real life
Hologram.icon = user.icon
Hologram.icon_state = user.icon_state
Hologram.copy_overlays(user, TRUE)
//codersprite some holo effects here
Hologram.alpha = 100
Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY)
Hologram.Impersonation = user
Hologram.languages = user.languages
Hologram.mouse_opacity = 0//So you can't click on it.
Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them.
Hologram.anchored = 1//So space wind cannot drag it.
Hologram.name = "[user.name] (Hologram)"//If someone decides to right click.
Hologram.set_light(2) //hologram lighting
set_holo(user, Hologram)
visible_message("A holographic image of [user] flicks to life right before your eyes!")
return Hologram
else
to_chat(user, "<span class='danger'>ERROR:</span> \black Unable to project hologram.")
@@ -192,58 +316,80 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
if(masters[master] && speaker != master)
master.relay_speech(message, speaker, message_language, raw_message, radio_freq, spans, message_mode)
/obj/machinery/holopad/proc/create_holo(mob/living/silicon/ai/A, turf/T = loc)
var/obj/effect/overlay/holo_pad_hologram/h = new(T)//Spawn a blank effect at the location.
h.icon = A.holo_icon
h.mouse_opacity = 0//So you can't click on it.
h.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them.
h.anchored = 1//So space wind cannot drag it.
h.name = "[A.name] (Hologram)"//If someone decides to right click.
h.set_light(2) //hologram lighting
set_holo(A, h)
for(var/I in holo_calls)
var/datum/holocall/HC = I
if(HC.connected_holopad == src && speaker != HC.hologram)
HC.user.Hear(message, speaker, message_language, raw_message, radio_freq, spans, message_mode)
if(outgoing_call && speaker == outgoing_call.user)
outgoing_call.hologram.say(raw_message)
/obj/machinery/holopad/proc/SetLightsAndPower()
var/total_users = masters.len + LAZYLEN(holo_calls)
use_power = HOLOPAD_PASSIVE_POWER_USAGE + HOLOGRAM_POWER_USAGE * total_users
if(total_users)
set_light(2)
icon_state = "holopad1"
else
set_light(0)
icon_state = "holopad0"
/obj/machinery/holopad/proc/set_holo(mob/living/user, var/obj/effect/overlay/holo_pad_hologram/h)
masters[user] = h
var/mob/living/silicon/ai/AI = user
if(istype(AI))
AI.current = src
SetLightsAndPower()
return TRUE
/obj/machinery/holopad/proc/set_holo(mob/living/silicon/ai/A, var/obj/effect/overlay/holo_pad_hologram/h)
masters[A] = h
set_light(2) // pad lighting
icon_state = "holopad1"
A.current = src
use_power += HOLOGRAM_POWER_USAGE
return TRUE
/obj/machinery/holopad/proc/clear_holo(mob/living/silicon/ai/user)
/obj/machinery/holopad/proc/clear_holo(mob/living/user)
qdel(masters[user]) // Get rid of user's hologram
unset_holo(user)
return TRUE
/obj/machinery/holopad/proc/unset_holo(mob/living/silicon/ai/user)
if(user.current == src)
user.current = null
/obj/machinery/holopad/proc/unset_holo(mob/living/user)
var/mob/living/silicon/ai/AI = user
if(istype(AI) && AI.current == src)
AI.current = null
masters -= user // Discard AI from the list of those who use holopad
use_power = max(HOLOPAD_PASSIVE_POWER_USAGE, use_power - HOLOGRAM_POWER_USAGE)//Reduce power usage
if (!masters.len) // If no users left
set_light(0) // pad lighting (hologram lighting will be handled automatically since its owner was deleted)
icon_state = "holopad0"
use_power = HOLOPAD_PASSIVE_POWER_USAGE
SetLightsAndPower()
return TRUE
/obj/machinery/holopad/proc/move_hologram(mob/living/silicon/ai/user)
/obj/machinery/holopad/proc/move_hologram(mob/living/user, turf/new_turf)
if(masters[user])
step_to(masters[user], user.eyeobj)
var/obj/effect/overlay/holo_pad_hologram/H = masters[user]
H.loc = get_turf(user.eyeobj)
step_to(H, new_turf)
H.loc = new_turf
var/area/holo_area = get_area(src)
var/area/eye_area = new_turf.loc
if(!(eye_area in holo_area.related))
clear_holo(user)
return TRUE
/obj/effect/overlay/holo_pad_hologram
var/mob/living/Impersonation
var/datum/holocall/HC
/obj/effect/overlay/holo_pad_hologram/Destroy()
Impersonation = null
if(HC)
HC.Disconnect(HC.calling_holopad)
return ..()
/obj/effect/overlay/holo_pad_hologram/Process_Spacemove(movement_dir = 0)
return 1
/obj/effect/overlay/holo_pad_hologram/examine(mob/user)
if(Impersonation)
return Impersonation.examine(user)
return ..()
/obj/item/weapon/circuitboard/machine/holopad
name = "AI Holopad (Machine Board)"
build_path = /obj/machinery/holopad
origin_tech = "programming=1"
req_components = list(/obj/item/weapon/stock_parts/capacitor = 1)
#undef RANGE_BASED
#undef AREA_BASED
#undef HOLOPAD_PASSIVE_POWER_USAGE
#undef HOLOGRAM_POWER_USAGE
#undef HOLOGRAM_POWER_USAGE
+44
View File
@@ -0,0 +1,44 @@
diff a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm (rejected hunks)
@@ -152,7 +152,7 @@ GLOBAL_LIST_EMPTY(holopads)
var/datum/holocall/HC = I
if(HC.connected_holopad == src)
dat += "<a href='?src=\ref[src];disconnectcall=\ref[HC]'>Disconnect call from [HC.user].</a><br>"
-
+
var/datum/browser/popup = new(user, "holopad", name, 300, 130)
popup.set_content(dat)
@@ -192,7 +192,7 @@ GLOBAL_LIST_EMPTY(holopads)
if(A)
LAZYADD(callnames[A], I)
callnames -= get_area(src)
-
+
var/result = input(usr, "Choose an area to call", "Holocall") as null|anything in callnames
if(QDELETED(usr) || !result || outgoing_call)
return
@@ -201,7 +201,7 @@ GLOBAL_LIST_EMPTY(holopads)
temp = "Dialing...<br>"
temp += "<A href='?src=\ref[src];mainmenu=1'>Main Menu</A>"
new /datum/holocall(usr, src, callnames[result])
-
+
else if(href_list["connectcall"])
var/datum/holocall/call_to_connect = locate(href_list["connectcall"])
if(!QDELETED(call_to_connect))
@@ -315,12 +315,12 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
for(var/mob/living/silicon/ai/master in masters)
if(masters[master] && speaker != master)
master.relay_speech(message, speaker, message_language, raw_message, radio_freq, spans, message_mode)
-
+
for(var/I in holo_calls)
var/datum/holocall/HC = I
if(HC.connected_holopad == src && speaker != HC.hologram)
- HC.user.Hear(message, speaker, message_language, raw_message, radio_freq, spans)
-
+ HC.user.Hear(message, speaker, message_language, raw_message, radio_freq, spans, message_mode)
+
if(outgoing_call && speaker == outgoing_call.user)
outgoing_call.hologram.say(raw_message)
+2
View File
@@ -251,6 +251,8 @@ GLOBAL_LIST_INIT(pipeID2State, list(
var/mob/living/carbon/C = user
for(var/i=1 to 20)
C.vomit(0,1,0,4,0)
if(prob(20))
C.spew_organ()
sleep(5)
C.blood_volume = 0
return(OXYLOSS|BRUTELOSS)
@@ -364,6 +364,10 @@
var/list/targets = list()
var/turretview = view(scan_range, base)
for(var/A in turretview)
var/atom/AA = A
if(AA.invisibility>SEE_INVISIBLE_LIVING)
continue
if(check_anomalies)//if it's set to check for simple animals
if(istype(A, /mob/living/simple_animal))
var/mob/living/simple_animal/SA = A
+12 -4
View File
@@ -56,6 +56,7 @@
var/dish_quants = list() //used by the snack machine's custom compartment to count dishes.
var/obj/item/weapon/vending_refill/refill_canister = null //The type of refill canisters used by this machine.
var/refill_count = 3 //The number of canisters the vending machine uses
/obj/machinery/vending/Initialize()
..()
@@ -88,7 +89,9 @@
/obj/machinery/vending/cola = "Robust Softdrinks",
/obj/machinery/vending/cigarette = "ShadyCigs Deluxe",
/obj/machinery/vending/autodrobe = "AutoDrobe",
/obj/machinery/vending/clothing = "ClothesMate")
/obj/machinery/vending/clothing = "ClothesMate",
/obj/machinery/vending/medical = "NanoMed Plus",
/obj/machinery/vending/wallmed = "NanoMed")
/obj/item/weapon/circuitboard/machine/vendor/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/screwdriver))
@@ -104,7 +107,7 @@
/obj/item/weapon/circuitboard/machine/vendor/proc/set_type(var/obj/machinery/vending/typepath)
build_path = typepath
name = "[names_paths[build_path]] Vendor (Machine Board)"
req_components = list(initial(typepath.refill_canister) = 3)
req_components = list(initial(typepath.refill_canister) = initial(typepath.refill_count))
/obj/item/weapon/circuitboard/machine/vendor/apply_default_parts(obj/machinery/M)
for(var/typepath in names_paths)
@@ -113,7 +116,6 @@
break
..()
/obj/machinery/vending/Destroy()
qdel(wires)
wires = null
@@ -307,7 +309,10 @@
if(panel_open)
attack_hand(user)
return
else if(istype(W, /obj/item/weapon/coin) && premium.len > 0)
else if(istype(W, /obj/item/weapon/coin))
if(!premium.len)
to_chat(user, "<span class='warning'>[src] doesn't have a coin slot.</span>")
return
if(!user.drop_item())
return
W.loc = src
@@ -874,6 +879,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
premium = list(/obj/item/weapon/storage/box/hug/medical = 1,/obj/item/weapon/reagent_containers/hypospray/medipen = 3, /obj/item/weapon/storage/belt/medical = 3, /obj/item/weapon/wrench/medical = 1)
armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50)
resistance_flags = FIRE_PROOF
refill_canister = /obj/item/weapon/vending_refill/medical
//This one's from bay12
/obj/machinery/vending/plasmaresearch
@@ -896,6 +902,8 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 2,/obj/item/weapon/reagent_containers/pill/morphine = 2)
armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50)
resistance_flags = FIRE_PROOF
refill_canister = /obj/item/weapon/vending_refill/medical
refill_count = 1
/obj/machinery/vending/security
name = "\improper SecTech"
+1 -1
View File
@@ -107,7 +107,7 @@
icon_state = "mecha_ion"
origin_tech = "materials=4;engineering=4;combat=6;magnets=6"
energy_drain = 500
projectile = /obj/item/projectile/energy/tesla_cannon
projectile = /obj/item/projectile/energy/tesla/cannon
fire_sound = 'sound/magic/lightningbolt.ogg'
+96 -23
View File
@@ -37,9 +37,9 @@
return 1
/obj/item/device/flashlight/attack(mob/living/carbon/human/M, mob/living/carbon/human/user)
/obj/item/device/flashlight/attack(mob/living/carbon/M, mob/living/carbon/human/user)
add_fingerprint(user)
if(on && user.zone_selected == "eyes")
if(istype(M) && on && user.zone_selected in list("eyes", "mouth"))
if((user.disabilities & CLUMSY || user.getBrainLoss() >= 60) && prob(50)) //too dumb to use flashlight properly
return ..() //just hit them in the head
@@ -48,28 +48,101 @@
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return
var/mob/living/carbon/human/H = M //mob has protective eyewear
if(ishuman(M) && ((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES)))
to_chat(user, "<span class='notice'>You're going to need to remove that [(H.head && H.head.flags_cover & HEADCOVERSEYES) ? "helmet" : (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) ? "mask": "glasses"] first.</span>")
if(!M.get_bodypart("head"))
to_chat(user, "<span class='warning'>[M] doesn't have a head!</span>")
return
if(M == user) //they're using it on themselves
if(M.flash_act(visual = 1))
M.visible_message("[M] directs [src] to [M.p_their()] eyes.", "<span class='notice'>You wave the light in front of your eyes! Trippy!</span>")
else
M.visible_message("[M] directs [src] to [M.p_their()] eyes.", "<span class='notice'>You wave the light in front of your eyes.</span>")
else
user.visible_message("<span class='warning'>[user] directs [src] to [M]'s eyes.</span>", \
"<span class='danger'>You direct [src] to [M]'s eyes.</span>")
var/mob/living/carbon/C = M
if(istype(C))
if(C.stat == DEAD || (C.disabilities & BLIND)) //mob is dead or fully blind
to_chat(user, "<span class='warning'>[C] pupils don't react to the light!</span>")
else if(C.dna.check_mutation(XRAY)) //mob has X-RAY vision
to_chat(user, "<span class='danger'>[C] pupils give an eerie glow!</span>")
else //they're okay!
if(C.flash_act(visual = 1))
to_chat(user, "<span class='notice'>[C]'s pupils narrow.</span>")
switch(user.zone_selected)
if("eyes")
if((M.head && M.head.flags_cover & HEADCOVERSEYES) || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSEYES) || (M.glasses && M.glasses.flags_cover & GLASSESCOVERSEYES))
to_chat(user, "<span class='notice'>You're going to need to remove that [(M.head && M.head.flags_cover & HEADCOVERSEYES) ? "helmet" : (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSEYES) ? "mask": "glasses"] first.</span>")
return
var/obj/item/organ/eyes/E = M.getorganslot("eye_sight")
if(!E)
to_chat(user, "<span class='danger'>[M] doesn't have any eyes!</span>")
return
if(M == user) //they're using it on themselves
if(M.flash_act(visual = 1))
M.visible_message("[M] directs [src] to [M.p_their()] eyes.", "<span class='notice'>You wave the light in front of your eyes! Trippy!</span>")
else
M.visible_message("[M] directs [src] to [M.p_their()] eyes.", "<span class='notice'>You wave the light in front of your eyes.</span>")
else
user.visible_message("<span class='warning'>[user] directs [src] to [M]'s eyes.</span>", \
"<span class='danger'>You direct [src] to [M]'s eyes.</span>")
if(M.stat == DEAD || (M.disabilities & BLIND) || !M.flash_act(visual = 1)) //mob is dead or fully blind
to_chat(user, "<span class='warning'>[M]'s pupils don't react to the light!</span>")
else if(M.dna && M.dna.check_mutation(XRAY)) //mob has X-RAY vision
to_chat(user, "<span class='danger'>[M]'s pupils give an eerie glow!</span>")
else //they're okay!
to_chat(user, "<span class='notice'>[M]'s pupils narrow.</span>")
if("mouth")
if((M.head && M.head.flags_cover & HEADCOVERSMOUTH) || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
to_chat(user, "<span class='notice'>You're going to need to remove that [(M.head && M.head.flags_cover & HEADCOVERSMOUTH) ? "helmet" : "mask"] first.</span>")
return
var/their = M.p_their()
var/list/mouth_organs = new
for(var/obj/item/organ/O in M.internal_organs)
if(O.zone == "mouth")
mouth_organs.Add(O)
var/organ_list = ""
var/organ_count = LAZYLEN(mouth_organs)
if(organ_count)
for(var/I in 1 to organ_count)
if(I > 1)
if(I == mouth_organs.len)
organ_list += ", and "
else
organ_list += ", "
var/obj/item/organ/O = mouth_organs[I]
organ_list += (O.gender == "plural" ? O.name : "\an [O.name]")
var/pill_count = 0
for(var/datum/action/item_action/hands_free/activate_pill/AP in M.actions)
pill_count++
if(M == user)
var/can_use_mirror = FALSE
if(isturf(user.loc))
var/obj/structure/mirror/mirror = locate(/obj/structure/mirror, user.loc)
if(mirror)
switch(user.dir)
if(NORTH)
can_use_mirror = mirror.pixel_y > 0
if(SOUTH)
can_use_mirror = mirror.pixel_y < 0
if(EAST)
can_use_mirror = mirror.pixel_x > 0
if(WEST)
can_use_mirror = mirror.pixel_x < 0
M.visible_message("[M] directs [src] to [their] mouth.", \
"<span class='notice'>You point [src] into your mouth.</span>")
if(!can_use_mirror)
to_chat(user, "<span class='notice'>You can't see anything without a mirror.</span>")
return
if(organ_count)
to_chat(user, "<span class='notice'>Inside your mouth [organ_count > 1 ? "are" : "is"] [organ_list].</span>")
else
to_chat(user, "<span class='notice'>There's nothing inside your mouth.</span>")
if(pill_count)
to_chat(user, "<span class='notice'>You have [pill_count] implanted pill[pill_count > 1 ? "s" : ""].</span>")
else
user.visible_message("<span class='notice'>[user] directs [src] to [M]'s mouth.</span>",\
"<span class='notice'>You direct [src] to [M]'s mouth.</span>")
if(organ_count)
to_chat(user, "<span class='notice'>Inside [their] mouth [organ_count > 1 ? "are" : "is"] [organ_list].</span>")
else
to_chat(user, "<span class='notice'>[M] doesn't have any organs in [their] mouth.</span>")
if(pill_count)
to_chat(user, "<span class='notice'>[M] has [pill_count] pill[pill_count > 1 ? "s" : ""] implanted in [their] teeth.")
else
return ..()
@@ -280,7 +353,7 @@
return TRUE
/obj/item/device/flashlight/emp/attack(mob/living/M, mob/living/user)
if(on && user.zone_selected == "eyes") // call original attack proc only if aiming at the eyes
if(on && user.zone_selected in list("eyes", "mouth")) // call original attack when examining organs
..()
return
@@ -237,6 +237,7 @@
/obj/item/borg/upgrade/selfrepair/proc/check_dropped()
if(loc != cyborg)
toggle_action.Remove(cyborg)
QDEL_NULL(toggle_action)
cyborg = null
deactivate()
@@ -399,4 +400,4 @@
return
R.make_shell(src)
return TRUE
return TRUE
@@ -1,5 +1,5 @@
/obj/item/weapon/grenade/spawnergrenade
desc = "It will unleash unleash an unspecified anomaly into the vicinity."
desc = "It will unleash an unspecified anomaly into the vicinity."
name = "delivery grenade"
icon = 'icons/obj/grenade.dmi'
icon_state = "delivery"
@@ -219,7 +219,8 @@
new /obj/item/weapon/reagent_containers/glass/bottle/polonium(src)
new /obj/item/weapon/reagent_containers/glass/bottle/venom(src)
new /obj/item/weapon/reagent_containers/glass/bottle/neurotoxin2(src)
new /obj/item/weapon/reagent_containers/glass/bottle/formaldehyde(src)
new /obj/item/weapon/reagent_containers/glass/bottle/formaldehyde(src)
new /obj/item/weapon/reagent_containers/glass/bottle/spewium(src)
new /obj/item/weapon/reagent_containers/glass/bottle/cyanide(src)
new /obj/item/weapon/reagent_containers/glass/bottle/histamine(src)
new /obj/item/weapon/reagent_containers/glass/bottle/initropidril(src)
@@ -71,3 +71,9 @@
icon_state = "refill_clothes"
charges = list(31, 4, 4)// of 101 standard, 12 contraband, 10 premium(?)
init_charges = list(31, 4, 4)
/obj/item/weapon/vending_refill/medical
machine_name = "NanoMed"
icon_state = "refill_medical"
charges = list(26, 5, 3)// of 76 standard, 13 contraband, 8 premium
init_charges = list(26, 5, 3)
+1 -1
View File
@@ -298,7 +298,7 @@
else
for(var/mob/M in range(1,src))
if(CanHug(M))
child.Attach(M)
child.Leap(M)
break
/obj/structure/alien/egg/obj_break(damage_flag)
+1 -1
View File
@@ -88,7 +88,7 @@
pixel_y = -20
/obj/structure/flora/tree/jungle/Initialize()
icon_state = "[icon_state][rand(1, 3)]"
icon_state = "[icon_state][rand(1, 6)]"
..()
//grass
+3 -3
View File
@@ -35,10 +35,10 @@ GLOBAL_LIST_INIT(freqtospan, list(
return 1
/atom/movable/proc/send_speech(message, range = 7, obj/source = src, bubble_type, list/spans, datum/language/message_language = null, message_mode)
var/rendered = compose_message(src, message_language, message, , spans)
var/rendered = compose_message(src, message_language, message, , spans, message_mode)
for(var/_AM in get_hearers_in_view(range, source))
var/atom/movable/AM = _AM
AM.Hear(rendered, src, message_language, message, , spans)
AM.Hear(rendered, src, message_language, message, , spans, message_mode)
//To get robot span classes, stuff like that.
/atom/movable/proc/get_spans()
@@ -58,7 +58,7 @@ GLOBAL_LIST_INIT(freqtospan, list(
var/endspanpart = "</span>"
//Message
var/messagepart = " <span class='message'>[lang_treat(speaker, message_language, raw_message, spans)]</span></span>"
var/messagepart = " <span class='message'>[lang_treat(speaker, message_language, raw_message, spans, message_mode)]</span></span>"
var/languageicon = ""
var/datum/language/D = get_language_instance(message_language)
+16 -2
View File
@@ -143,14 +143,14 @@
qdel(S.mmi)
qdel(AM)
if(AM && !QDELETED(AM)) //It's indestructible
visible_message("<span class='boldwarning'>[src] spits out the [AM]!</span>")
AM.alpha = oldalpha
AM.color = oldcolor
AM.transform = oldtransform
AM.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1, 10),rand(1, 10))
/turf/open/chasm/straight_down/lava_land_surface/normal_air
initial_gas_mix = "o2=22;n2=82;TEMP=293.15"
@@ -158,3 +158,17 @@
/turf/open/chasm/CanPass(atom/movable/mover, turf/target, height=0)
return 1
//Jungle
/turf/open/chasm/jungle
icon = 'icons/turf/floors/junglechasm.dmi'
planetary_atmos = TRUE
initial_gas_mix = "o2=14;n2=23;TEMP=300"
/turf/open/chasm/straight_down/jungle
icon = 'icons/turf/floors/junglechasm.dmi'
planetary_atmos = TRUE
initial_gas_mix = "o2=14;n2=23;TEMP=300"
@@ -3,19 +3,9 @@
desc = "Upon closer examination, it's still dirt."
icon = 'icons/turf/floors.dmi'
icon_state = "dirt"
var/smooth_icon = 'icons/turf/floors/dirt.dmi'
canSmoothWith = list(/turf/closed, /turf/open/floor/plating/dirt)
smooth = SMOOTH_MORE|SMOOTH_BORDER
baseturf = /turf/open/chasm/straight_down/lava_land_surface
baseturf = /turf/open/chasm/straight_down/jungle
initial_gas_mix = "o2=14;n2=23;TEMP=300"
planetary_atmos = TRUE
/turf/open/floor/plating/dirt/Initialize()
pixel_y = -2
pixel_x = -2
icon = smooth_icon
..()
/turf/open/floor/plating/dirt/dark
icon_state = "darkdirt"
smooth_icon = 'icons/turf/floors/darkdirt.dmi'
icon_state = "greenerdirt"
-10
View File
@@ -1,10 +0,0 @@
diff a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm (rejected hunks)
@@ -8,7 +8,7 @@
if(href_list["ahelp"])
if(!check_rights(R_ADMIN))
return
-
+
var/ahelp_ref = href_list["ahelp"]
var/datum/admin_help/AH = locate(ahelp_ref)
if(AH)
+1 -1
View File
@@ -19,7 +19,7 @@
if (!msg)
return
var/nicknames = world.file2list("config/admin_nicknames.txt")
var/static/nicknames = world.file2list("config/admin_nicknames.txt")
var/rendered = "<span class='game deadsay'><span class='prefix'>DEAD:</span> <span class='name'>ADMIN([src.holder.fakekey ? pick(nicknames) : src.key])</span> says, <span class='message'>\"[msg]\"</span></span>"
+1 -1
View File
@@ -21,7 +21,7 @@
var/res = alert(usr, "Show the title of this song to the players?",, "No", "Yes", "Cancel")
switch(res)
if("Yes")
to_chat(world, "An admin played: [S]")
to_chat(world, "<span class='boldannounce'>An admin played: [S]</span>")
if("Cancel")
return
-1
View File
@@ -350,7 +350,6 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(G_found.mind && !G_found.mind.active)
G_found.mind.transfer_to(new_character) //be careful when doing stuff like this! I've already checked the mind isn't in use
new_character.mind.special_verbs = list()
else
new_character.mind_initialize()
if(!new_character.mind.assigned_role)
+8
View File
@@ -828,6 +828,14 @@
/obj/item/weapon/defibrillator/loaded)
crate_name = "defibrillator crate"
/datum/supply_pack/medical/vending
name = "Medical Vending Crate"
cost = 2000
contains = list(/obj/item/weapon/vending_refill/medical,
/obj/item/weapon/vending_refill/medical,
/obj/item/weapon/vending_refill/medical)
crate_name = "medical vending crate"
//////////////////////////////////////////////////////////////////////////////
//////////////////////////// Science /////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
+2 -2
View File
@@ -13,8 +13,8 @@
return
if(confirm == "Yes")
suiciding = 1
log_game("[key_name(src)] (job: [job ? "[job]" : "None"]) commited suicide at [get_area(src)].")
message_admins("[key_name(src)] (job: [job ? "[job]" : "None"]) commited suicide at [get_area(src)].")
log_game("[key_name(src)] (job: [job ? "[job]" : "None"]) committed suicide at [get_area(src)].")
message_admins("[key_name(src)] (job: [job ? "[job]" : "None"]) committed suicide at [get_area(src)].")
var/obj/item/held_item = get_active_held_item()
if(held_item)
var/damagetype = held_item.suicide_act(src)
+6 -19
View File
@@ -326,9 +326,6 @@
disable_flight(1)
if(!suit)
disable_flight(1)
if(!resync)
addtimer(CALLBACK(src, .proc/resync), 600)
resync = 1
if(!wearer) //Oh god our user fell off!
disable_flight(1)
if(!pressure && brake)
@@ -340,12 +337,6 @@
stabilizer = FALSE
usermessage("Warning: Sensor data is not being recieved from flight shoes. Stabilizers and airbrake modules OFFLINE!", 2)
//Resync the suit
/obj/item/device/flightpack/proc/resync()
resync = FALSE
suit.resync()
//How fast should the wearer be?
/obj/item/device/flightpack/proc/update_slowdown()
if(!flight)
suit.slowdown = slowdown_ground
@@ -356,20 +347,11 @@
/obj/item/device/flightpack/process()
if(!suit || (processing_mode == FLIGHTSUIT_PROCESSING_NONE))
return FALSE
update_slowdown()
update_icon()
check_conditions()
calculate_momentum_speed()
momentum_drift()
handle_boost()
handle_damage()
handle_flight()
/obj/item/device/flightpack/proc/handle_flight()
if(!flight)
return FALSE
if(wearer)
wearer.float(TRUE)
/obj/item/device/flightpack/proc/handle_damage()
if(crash_damage)
@@ -424,7 +406,6 @@
if(boost_charge < boost_maxcharge)
boost_charge = Clamp(boost_charge+boost_chargerate, 0, boost_maxcharge)
/obj/item/device/flightpack/proc/cycle_power()
if(powersetting < powersetting_high)
powersetting++
@@ -654,6 +635,8 @@
wearer.movement_type |= FLYING
wearer.pass_flags |= flight_passflags
usermessage("ENGAGING FLIGHT ENGINES.")
update_slowdown()
wearer.floating = TRUE
wearer.visible_message("<font color='blue' size='2'>[wearer]'s flight engines activate as they lift into the air!</font>")
//I DONT HAVE SOUND EFFECTS YET playsound(
flight = TRUE
@@ -670,6 +653,8 @@
momentum_x = 0
momentum_y = 0
usermessage("DISENGAGING FLIGHT ENGINES.")
update_slowdown()
wearer.floating = FALSE
wearer.visible_message("<font color='blue' size='2'>[wearer] drops to the ground as their flight engines cut out!</font>")
//NO SOUND YET playsound(
ion_trail.stop()
@@ -749,11 +734,13 @@
wearer.visible_message("<span class='notice'>[wearer.name]'s flightpack engines flare in intensity as they are rocketed forward by the immense thrust!</span>")
boost = TRUE
update_slowdown()
update_icon()
/obj/item/device/flightpack/proc/deactivate_booster()
usermessage("Boosters disengaged!")
boost = FALSE
update_slowdown()
update_icon()
/obj/item/device/flightpack/proc/enable_airbrake()
if(wearer)
+4 -4
View File
@@ -13,6 +13,8 @@
var/scanning = 0
var/list/log = list()
origin_tech = "engineering=4;biotech=2;programming=5"
var/range = 8
var/view_check = TRUE
/obj/item/device/detective_scanner/attack_self(mob/user)
if(log.len && !scanning)
@@ -43,7 +45,7 @@
log = list()
scanning = 0
/obj/item/device/detective_scanner/pre_attackby(atom/A, mob/user, params)
/obj/item/device/detective_scanner/afterattack(atom/A, mob/user, params)
scan(A, user)
return FALSE
@@ -51,9 +53,7 @@
set waitfor = 0
if(!scanning)
// Can remotely scan objects and mobs.
if(!in_range(A, user) && !(A in view(world.view, user)))
return
if(loc != user)
if((get_dist(A, user) > range) || (!(A in view(range, user)) && view_check) || (loc != user))
return
scanning = 1
@@ -13,8 +13,8 @@
filling_color = "#D2691E"
tastes = list("donut" = 1)
/obj/item/weapon/reagent_containers/food/snacks/donut/New()
..()
/obj/item/weapon/reagent_containers/food/snacks/donut/Initialize()
. = ..()
if(prob(30))
icon_state = "donut2"
name = "frosted donut"
@@ -28,8 +28,8 @@
bitesize = 10
tastes = list("donut" = 3, "chaos" = 1)
/obj/item/weapon/reagent_containers/food/snacks/donut/chaos/New()
..()
/obj/item/weapon/reagent_containers/food/snacks/donut/chaos/Initialize()
. = ..()
extra_reagent = pick("nutriment", "capsaicin", "frostoil", "krokodil", "plasma", "cocoa", "slimejelly", "banana", "berryjuice", "omnizine")
reagents.add_reagent("[extra_reagent]", 3)
bonus_reagents = list("[extra_reagent]" = 3, "sugar" = 1)
@@ -48,8 +48,8 @@
extra_reagent = "berryjuice"
tastes = list("jelly" = 1, "donut" = 3)
/obj/item/weapon/reagent_containers/food/snacks/donut/jelly/New()
..()
/obj/item/weapon/reagent_containers/food/snacks/donut/jelly/Initialize()
. = ..()
if(extra_reagent)
reagents.add_reagent("[extra_reagent]", 3)
if(prob(30))
@@ -210,13 +210,13 @@
filling_color = "#F0E68C"
tastes = list("mushroom" = 1, "biscuit" = 1)
/obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit/New()
/obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit/Initialize()
var/fey = prob(10)
if(fey)
name = "exceptional plump helmet biscuit"
desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump helmet biscuit!"
bonus_reagents = list("omnizine" = 5, "nutriment" = 1, "vitamin" = 1)
..()
. = ..()
if(fey)
reagents.add_reagent("omnizine", 5)
+1
View File
@@ -111,6 +111,7 @@
for(var/datum/plant_gene/trait/trait in seed.genes)
trait.on_squash(src, target)
reagents.reaction(T)
for(var/A in T)
reagents.reaction(A)
+11 -2
View File
@@ -84,7 +84,7 @@
if(D.make_reagents.len)
return 0
var/build_amount = 1
var/build_amount = 0
for(var/mat_id in D.materials)
var/M = D.materials[mat_id]
@@ -93,7 +93,15 @@
if(!M || !redemption_mat)
return 0
build_amount = min(build_amount, round(redemption_mat.amount / M))
var/smeltable_sheets = round(redemption_mat.amount / M)
if(!smeltable_sheets)
return 0
if(!build_amount)
build_amount = smeltable_sheets
build_amount = min(build_amount, smeltable_sheets)
return build_amount
@@ -152,6 +160,7 @@
if(exchange_parts(user, W))
return
if(default_pry_open(W))
materials.retrieve_all()
return
if(default_unfasten_wrench(user, W))
return
+1 -1
View File
@@ -20,6 +20,6 @@
to_follow = V.source
var/link = FOLLOW_LINK(src, to_follow)
// Recompose the message, because it's scrambled by default
message = compose_message(speaker, message_language, raw_message, radio_freq, spans)
message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode)
to_chat(src, "[link] [message]")
+3 -4
View File
@@ -35,22 +35,21 @@
blood_volume += 0.1 // regenerate blood VERY slowly
//Effects of bloodloss
var/word = pick("dizzy","woozy","faint")
switch(blood_volume)
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
if(prob(5))
to_chat(src, "<span class='warning'>You feel [pick("dizzy","woozy","faint")].</span>")
to_chat(src, "<span class='warning'>You feel [word].</span>")
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1))
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1))
if(prob(5))
blur_eyes(6)
var/word = pick("dizzy","woozy","faint")
to_chat(src, "<span class='warning'>You feel very [word].</span>")
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
adjustOxyLoss(5)
if(prob(15))
Paralyse(rand(1,3))
var/word = pick("dizzy","woozy","faint")
to_chat(src, "<span class='warning'>You feel extremely [word].</span>")
if(0 to BLOOD_VOLUME_SURVIVE)
death()
@@ -70,7 +69,7 @@
bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases
if(bleed_rate && !bleedsuppress)
if(bleed_rate && !bleedsuppress && !(status_flags & FAKEDEATH))
bleed(bleed_rate)
//Makes a blood drop, leaking amt units of blood from the mob
@@ -87,6 +87,8 @@
owner.adjustFireLoss(-heal_amt)
owner.adjustOxyLoss(-heal_amt)
owner.adjustCloneLoss(-heal_amt)
else
owner.adjustPlasma(plasma_rate * 0.1)
/obj/item/organ/alien/plasmavessel/Insert(mob/living/carbon/M, special = 0)
..()
+1 -1
View File
@@ -1,4 +1,4 @@
/mob/living/proc/alien_talk(message, shown_name = name)
/mob/living/proc/alien_talk(message, shown_name = real_name)
log_say("[key_name(src)] : [message]")
message = trim(message)
if(!message) return
+11 -1
View File
@@ -484,7 +484,7 @@
adjustBruteLoss(3)
else
if(T)
T.add_vomit_floor(src, 0)//toxic barf looks different
T.add_vomit_floor(src, toxic)//toxic barf looks different
nutrition -= lost_nutrition
adjustToxLoss(-3)
T = get_step(T, dir)
@@ -492,6 +492,16 @@
break
return 1
/mob/living/carbon/proc/spew_organ(power = 5)
if(!internal_organs.len)
return //Guess we're out of organs
var/obj/item/organ/guts = pick(internal_organs)
var/turf/T = get_turf(src)
guts.Remove(src)
guts.forceMove(T)
var/atom/throw_target = get_edge_target_turf(guts, dir)
guts.throw_at(throw_target, power, 4, src)
/mob/living/carbon/fully_replace_character_name(oldname,newname)
..()
@@ -1,10 +0,0 @@
diff a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm (rejected hunks)
@@ -32,7 +32,7 @@
dna.species.spec_death(gibbed, src)
- if(SSticker && SSticker.mode)
+ if(SSticker.HasRoundStarted())
SSblackbox.ReportDeath(src)
if(mind && mind.devilinfo)
INVOKE_ASYNC(mind.devilinfo, /datum/devilinfo.proc/beginResurrectionCheck, src)
@@ -134,7 +134,7 @@
if(stat == DEAD || (status_flags & FAKEDEATH))
appears_dead = 1
if(suiciding)
msg += "<span class='warning'>[t_He] appear[p_s()] to have commited suicide... there is no hope of recovery.</span>\n"
msg += "<span class='warning'>[t_He] appear[p_s()] to have committed suicide... there is no hope of recovery.</span>\n"
if(hellbound)
msg += "<span class='warning'>[t_His] soul seems to have been ripped out of [t_his] body. Revival is impossible.</span>\n"
msg += "<span class='deadsay'>[t_He] [t_is] limp and unresponsive; there are no signs of life"
@@ -28,7 +28,7 @@
//Holopad
if(istype(ai.current, /obj/machinery/holopad))
var/obj/machinery/holopad/H = ai.current
H.move_hologram(ai)
H.move_hologram(ai, T)
/mob/camera/aiEye/Move()
return 0
@@ -106,4 +106,4 @@
/mob/camera/aiEye/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
if(relay_speech && speaker && ai && !radio_freq && speaker != ai && near_camera(speaker))
ai.relay_speech(message, speaker, message_language, raw_message, radio_freq, spans)
ai.relay_speech(message, speaker, message_language, raw_message, radio_freq, spans, message_mode)
@@ -108,6 +108,7 @@
speak_emote = list("clanks", "clinks", "clunks", "clangs")
verb_ask = "requests"
verb_exclaim = "proclaims"
verb_whisper = "imparts"
verb_yell = "harangues"
bubble_icon = "clock"
initial_languages = list(/datum/language/common, /datum/language/ratvar)
@@ -401,7 +401,7 @@ Difficulty: Very Hard
to_chat(user, observer_desc)
to_chat(user, "It is activated by [activation_method].")
/obj/machinery/anomalous_crystal/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans)
/obj/machinery/anomalous_crystal/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode)
..()
if(isliving(speaker))
ActivationReaction(speaker, ACTIVATE_SPEECH)
@@ -1,4 +1,4 @@
/mob/living/simple_animal/slime/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans)
/mob/living/simple_animal/slime/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode)
if(speaker != src && !radio_freq && !stat)
if (speaker in Friends)
speech_buffer = list()
@@ -16,7 +16,7 @@
response_disarm = "shoos"
response_harm = "stomps on"
emote_see = list("jiggles", "bounces in place")
speak_emote = list("telepathically chirps")
speak_emote = list("blorbles")
bubble_icon = "slime"
initial_languages = list(/datum/language/common, /datum/language/slime)
@@ -31,10 +31,10 @@
see_in_dark = 8
verb_say = "telepathically chirps"
verb_ask = "telepathically asks"
verb_exclaim = "telepathically cries"
verb_yell = "telephatically cries"
verb_say = "blorbles"
verb_ask = "inquisitively blorbles"
verb_exclaim = "loudly blorbles"
verb_yell = "loudly blorbles"
// canstun and canweaken don't affect slimes because they ignore stun and weakened variables
// for the sake of cleanliness, though, here they are.
+2
View File
@@ -351,6 +351,8 @@
/mob/proc/spin(spintime, speed)
set waitfor = 0
var/D = dir
if((spintime < 1)||(speed < 1)||!spintime||!speed)
return
while(spintime >= speed)
sleep(speed)
switch(D)
+30 -13
View File
@@ -28,11 +28,12 @@
/obj/machinery/power/generator/Initialize(mapload)
. = ..()
. = ..()
var/obj/machinery/atmospherics/components/binary/circulator/circpath = /obj/machinery/atmospherics/components/binary/circulator
cold_circ = locate(circpath) in get_step(src, cold_dir)
hot_circ = locate(circpath) in get_step(src, hot_dir)
connect_to_network()
SSair.atmos_machinery += src
if(cold_circ)
switch(cold_dir)
@@ -55,6 +56,9 @@
update_icon()
/obj/machinery/power/generator/Destroy()
SSair.atmos_machinery -= src
return ..()
/obj/machinery/power/generator/update_icon()
@@ -63,21 +67,20 @@
else
cut_overlays()
if(lastgenlev != 0)
add_overlay("teg-op[lastgenlev]")
var/L = min(round(lastgenlev/100000),11)
if(L != 0)
add_overlay(image('icons/obj/power.dmi', "teg-op[L]"))
add_overlay("teg-oc[lastcirc]")
add_overlay("teg-oc[lastcirc]")
#define GENRATE 800 // generator output coefficient from Q
/obj/machinery/power/generator/process()
/obj/machinery/power/generator/process_atmos()
if(!cold_circ || !hot_circ)
return
lastgen = 0
if(powernet)
//to_chat(world, "cold_circ and hot_circ pass")
@@ -104,7 +107,7 @@
var/energy_transfer = delta_temperature*hot_air_heat_capacity*cold_air_heat_capacity/(hot_air_heat_capacity+cold_air_heat_capacity)
var/heat = energy_transfer*(1-efficiency)
lastgen = energy_transfer*efficiency
lastgen += energy_transfer*efficiency
//to_chat(world, "lastgen = [lastgen]; heat = [heat]; delta_temperature = [delta_temperature]; hot_air_heat_capacity = [hot_air_heat_capacity]; cold_air_heat_capacity = [cold_air_heat_capacity];")
@@ -113,7 +116,7 @@
//to_chat(world, "POWER: [lastgen] W generated at [efficiency*100]% efficiency and sinks sizes [cold_air_heat_capacity], [hot_air_heat_capacity]")
add_avail(lastgen)
//add_avail(lastgen) This is done in process now
// update icon overlays only if displayed level has changed
if(hot_air)
@@ -124,15 +127,23 @@
var/datum/gas_mixture/cold_circ_air1 = cold_circ.AIR1
cold_circ_air1.merge(cold_air)
var/genlev = max(0, min( round(11*lastgen / 100000), 11))
update_icon()
var/circ = "[cold_circ && cold_circ.last_pressure_delta > 0 ? "1" : "0"][hot_circ && hot_circ.last_pressure_delta > 0 ? "1" : "0"]"
if((genlev != lastgenlev) || (circ != lastcirc))
lastgenlev = genlev
if(circ != lastcirc)
lastcirc = circ
update_icon()
src.updateDialog()
/obj/machinery/power/generator/process()
//Setting this number higher just makes the change in power output slower, it doesnt actualy reduce power output cause **math**
var/power_output = round(lastgen / 10)
add_avail(power_output)
lastgenlev = power_output
lastgen -= power_output
..()
/obj/machinery/power/generator/attack_hand(mob/user)
if(..())
user << browse(null, "window=teg")
@@ -151,7 +162,13 @@
t += "<div class='statusDisplay'>"
t += "Output: [round(lastgen)] W"
var/displaygen = lastgenlev
if(displaygen < 1000000) //less than a MW
displaygen /= 1000
t += "Output: [round(displaygen,0.01)] kW"
else
displaygen /= 1000000
t += "Output: [round(displaygen,0.01)] MW"
t += "<BR>"
+3 -2
View File
@@ -14,6 +14,7 @@
light_power = 0.7
light_range = 15
light_color = rgb(255, 0, 0)
gender = FEMALE
var/clashing = FALSE //If Nar-Sie is fighting Ratvar
/obj/singularity/narsie/large
@@ -26,8 +27,8 @@
grav_pull = 10
consume_range = 12 //How many tiles out do we eat
/obj/singularity/narsie/large/New()
..()
/obj/singularity/narsie/large/Initialize()
. = ..()
send_to_playing_players("<span class='narsie'>NAR-SIE HAS RISEN</span>")
send_to_playing_players(pick('sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg'))
@@ -29,12 +29,12 @@
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
dangerous_possession = TRUE
/obj/singularity/New(loc, var/starting_energy = 50, var/temp = 0)
/obj/singularity/Initialize(mapload, starting_energy = 50)
//CARN: admin-alert for chuckle-fuckery.
admin_investigate_setup()
src.energy = starting_energy
..()
. = ..()
START_PROCESSING(SSobj, src)
GLOB.poi_list |= src
GLOB.singularities |= src
@@ -129,6 +129,7 @@
/obj/machinery/power/supermatter_shard/Initialize()
. = ..()
SSair.atmos_machinery += src
countdown = new(src)
countdown.start()
GLOB.poi_list |= src
@@ -139,6 +140,7 @@
/obj/machinery/power/supermatter_shard/Destroy()
investigate_log("has been destroyed.", "supermatter")
SSair.atmos_machinery -= src
QDEL_NULL(radio)
GLOB.poi_list -= src
QDEL_NULL(countdown)
@@ -181,7 +183,7 @@
E.energy = power
qdel(src)
/obj/machinery/power/supermatter_shard/process()
/obj/machinery/power/supermatter_shard/process_atmos()
var/turf/T = loc
if(isnull(T)) // We have a null turf...something is wrong, stop processing this entity.
@@ -296,6 +298,7 @@
if(produces_gas)
env.merge(removed)
air_update_turf()
for(var/mob/living/carbon/human/l in view(src, HALLUCINATION_RANGE(power))) // If they can see it without mesons on. Bad on them.
if(!istype(l.glasses, /obj/item/clothing/glasses/meson))
+11 -1
View File
@@ -40,6 +40,11 @@ GLOBAL_LIST_INIT(blacklisted_tesla_types, typecacheof(list(/obj/machinery/atmosp
var/energy_to_raise = 32
var/energy_to_lower = -20
/obj/singularity/energy_ball/Initialize(mapload, starting_energy = 50, is_miniball = FALSE)
. = ..()
if(!is_miniball)
set_light(10, 7, "#EEEEFF")
/obj/singularity/energy_ball/ex_act(severity, target)
return
@@ -54,6 +59,11 @@ GLOBAL_LIST_INIT(blacklisted_tesla_types, typecacheof(list(/obj/machinery/atmosp
. = ..()
/obj/singularity/energy_ball/admin_investigate_setup()
if(istype(loc, /obj/singularity/energy_ball))
return
..()
/obj/singularity/energy_ball/process()
if(!orbiting)
handle_energy()
@@ -117,7 +127,7 @@ GLOBAL_LIST_INIT(blacklisted_tesla_types, typecacheof(list(/obj/machinery/atmosp
/obj/singularity/energy_ball/proc/new_mini_ball()
if(!loc)
return
var/obj/singularity/energy_ball/EB = new(loc)
var/obj/singularity/energy_ball/EB = new(loc, 0, TRUE)
EB.transform *= pick(0.3, 0.4, 0.5, 0.6, 0.7)
var/icon/I = icon(icon,icon_state,dir)
@@ -191,7 +191,7 @@
fire_sound = 'sound/magic/lightningbolt.ogg'
e_cost = 200
select_name = "stun"
projectile_type = /obj/item/projectile/energy/tesla_revolver
projectile_type = /obj/item/projectile/energy/tesla/revolver
/obj/item/ammo_casing/energy/gravityrepulse
projectile_type = /obj/item/projectile/gravityrepulse
+14 -9
View File
@@ -179,6 +179,8 @@
return
if(setAngle)
Angle = setAngle
var/old_pixel_x = pixel_x
var/old_pixel_y = pixel_y
if(!legacy) //new projectiles
set waitfor = 0
var/next_run = world.time
@@ -201,29 +203,30 @@
var/Pixel_x=round((sin(Angle)+16*sin(Angle)*2), 1) //round() is a floor operation when only one argument is supplied, we don't want that here
var/Pixel_y=round((cos(Angle)+16*cos(Angle)*2), 1)
var/pixel_x_offset = pixel_x + Pixel_x
var/pixel_y_offset = pixel_y + Pixel_y
var/pixel_x_offset = old_pixel_x + Pixel_x
var/pixel_y_offset = old_pixel_y + Pixel_y
var/new_x = x
var/new_y = y
while(pixel_x_offset > 16)
pixel_x_offset -= 32
pixel_x -= 32
old_pixel_x -= 32
new_x++// x++
while(pixel_x_offset < -16)
pixel_x_offset += 32
pixel_x += 32
old_pixel_x += 32
new_x--
while(pixel_y_offset > 16)
pixel_y_offset -= 32
pixel_y -= 32
old_pixel_y -= 32
new_y++
while(pixel_y_offset < -16)
pixel_y_offset += 32
pixel_y += 32
old_pixel_y += 32
new_y--
pixel_x = old_pixel_x
pixel_y = old_pixel_y
step_towards(src, locate(new_x, new_y, z))
next_run += max(world.tick_lag, speed)
var/delay = next_run - world.time
@@ -232,7 +235,9 @@
pixel_y = pixel_y_offset
else
animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = max(1, (delay <= 3 ? delay - 1 : delay)), flags = ANIMATION_END_NOW)
old_pixel_x = pixel_x_offset
old_pixel_y = pixel_y_offset
if(original && (original.layer>=2.75) || ismob(original))
if(loc == get_turf(original))
if(!(original in permutated))
+14 -24
View File
@@ -159,44 +159,34 @@
/obj/item/projectile/energy/bolt/large
damage = 20
/obj/item/projectile/energy/tesla_revolver
/obj/item/projectile/energy/tesla
name = "tesla bolt"
icon_state = "tesla_projectile"
impact_effect_type = /obj/effect/overlay/temp/impact_effect/blue_laser
var/chain
/obj/item/projectile/energy/tesla_revolver/fire(setAngle)
/obj/item/projectile/energy/tesla/fire(setAngle)
if(firer)
chain = firer.Beam(src, icon_state = "lightning[rand(1, 12)]", time = INFINITY, maxdistance = INFINITY)
..()
/obj/item/projectile/energy/tesla_revolver/on_hit(atom/target)
. = ..()
if(isliving(target))
tesla_zap(src, 3, 10000)
qdel(src)
/obj/item/projectile/energy/tesla_revolver/Destroy()
/obj/item/projectile/energy/tesla/Destroy()
qdel(chain)
return ..()
/obj/item/projectile/energy/tesla/revolver
name = "energy orb"
/obj/item/projectile/energy/tesla_cannon
name = "tesla bolt"
icon_state = "tesla_projectile"
impact_effect_type = /obj/effect/overlay/temp/impact_effect/blue_laser
var/chain
/obj/item/projectile/energy/tesla/revolver/on_hit(atom/target)
. = ..()
if(isliving(target))
tesla_zap(target, 3, 10000)
qdel(src)
/obj/item/projectile/energy/tesla_cannon/fire(setAngle)
if(firer)
chain = firer.Beam(src, icon_state = "lightning[rand(1, 12)]", time = INFINITY, maxdistance = INFINITY)
..()
/obj/item/projectile/energy/tesla/cannon
name = "tesla orb"
/obj/item/projectile/energy/tesla_cannon/on_hit(atom/target)
/obj/item/projectile/energy/tesla/cannon/on_hit(atom/target)
. = ..()
tesla_zap(src, 3, 10000, explosive = FALSE, stun_mobs = FALSE)
tesla_zap(target, 3, 10000, explosive = FALSE, stun_mobs = FALSE)
qdel(src)
/obj/item/projectile/energy/tesla_cannon/Destroy()
qdel(chain)
return ..()
@@ -38,7 +38,7 @@
/obj/item/weapon/reagent_containers/food/snacks/grown/wheat = list("flour" = -5),
/obj/item/weapon/reagent_containers/food/snacks/grown/oat = list("flour" = -5),
/obj/item/weapon/reagent_containers/food/snacks/grown/rice = list("rice" = -5),
/obj/item/weapon/reagent_containers/food/snacks/donut/New = list("sprinkles" = -2, "sugar" = 1),
/obj/item/weapon/reagent_containers/food/snacks/donut = list("sprinkles" = -2, "sugar" = 1),
/obj/item/weapon/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0),
/obj/item/weapon/reagent_containers/food/snacks/egg = list("eggyolk" = -5),
@@ -60,7 +60,10 @@
// data for nutriment is one or more (flavour -> ratio)
// where all the ratio values adds up to 1
var/list/taste_amounts = data.Copy()
var/list/taste_amounts = list()
if(data)
taste_amounts = data.Copy()
counterlist_scale(taste_amounts, volume)
var/list/other_taste_amounts = newdata.Copy()
@@ -347,10 +347,9 @@
/datum/reagent/medicine/mine_salve/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1)
if(iscarbon(M) && M.stat != DEAD)
if(method in list(INGEST, VAPOR, INJECT))
M.Stun(4)
M.Weaken(4)
M.nutrition -= 5
if(show_message)
to_chat(M, "<span class='warning'>Your stomach agonizingly cramps!</span>")
to_chat(M, "<span class='warning'>Your stomach feels empty and cramps!</span>")
else
var/mob/living/carbon/C = M
for(var/s in C.surgeries)
@@ -962,8 +961,7 @@
/datum/reagent/medicine/antitoxin/on_mob_life(mob/living/M)
M.adjustToxLoss(-2*REM, 0)
for(var/datum/reagent/toxin/R in M.reagents.reagent_list)
if(R != src)
M.reagents.remove_reagent(R.id,1)
M.reagents.remove_reagent(R.id,1)
..()
. = 1
@@ -189,7 +189,7 @@
/datum/reagent/water/holywater/on_mob_life(mob/living/M)
if(!data) data = 1
data++
M.jitteriness = max(M.jitteriness-5,0)
M.jitteriness = min(M.jitteriness+4,10)
if(data >= 30) // 12 units, 54 seconds @ metabolism 0.4 units & tick rate 1.8 sec
if(!M.stuttering)
M.stuttering = 1
@@ -212,9 +212,9 @@
SSticker.mode.remove_cultist(M.mind, 1, 1)
else if(is_servant_of_ratvar(M))
remove_servant_of_ratvar(M)
holder.remove_reagent(id, volume) // maybe this is a little too perfect and a max() cap on the statuses would be better??
M.jitteriness = 0
M.stuttering = 0
holder.remove_reagent(id, volume) // maybe this is a little too perfect and a max() cap on the statuses would be better??
return
holder.remove_reagent(id, 0.4) //fixed consumption to prevent balancing going out of whack
@@ -658,7 +658,7 @@
taste_mult = 0 // apparently tasteless.
/datum/reagent/mercury/on_mob_life(mob/living/M)
if(M.canmove && isspaceturf(M.loc))
if(M.canmove && !isspaceturf(M.loc))
step(M, pick(GLOB.cardinal))
if(prob(5))
M.emote(pick("twitch","drool","moan"))
@@ -738,7 +738,7 @@
taste_description = "metal"
/datum/reagent/lithium/on_mob_life(mob/living/M)
if(M.canmove && isspaceturf(M.loc))
if(M.canmove && !isspaceturf(M.loc))
step(M, pick(GLOB.cardinal))
if(prob(5))
M.emote(pick("twitch","drool","moan"))
@@ -648,6 +648,34 @@
M.losebreath += 5
return ..()
/datum/reagent/toxin/spewium
name = "Spewium"
id = "spewium"
description = "A powerful emetic, causes uncontrollable vomiting. May result in vomiting organs at high doses."
reagent_state = LIQUID
color = "#2f6617" //A sickly green color
metabolization_rate = REAGENTS_METABOLISM
overdose_threshold = 29
toxpwr = 0
taste_description = "vomit"
/datum/reagent/toxin/spewium/on_mob_life(mob/living/M)
.=..()
if(current_cycle >=11 && prob(min(50,current_cycle)) && ishuman(M))
var/mob/living/carbon/human/H = M
H.vomit(lost_nutrition = 10, blood = prob(10), stun = prob(50), distance = rand(0,4), message = TRUE, toxic = prob(30))
for(var/datum/reagent/toxin/R in M.reagents.reagent_list)
if(R != src)
H.reagents.remove_reagent(R.id,1)
/datum/reagent/toxin/spewium/overdose_process(mob/living/M)
. = ..()
if(current_cycle >=33 && prob(15) && ishuman(M))
var/mob/living/carbon/human/H = M
H.spew_organ()
H.vomit(lost_nutrition = 0, blood = 1, stun = 1, distance = 4)
to_chat(H, "<span class='userdanger'>You feel something lumpy come up as you vomit.</span>")
/datum/reagent/toxin/curare
name = "Curare"
id = "curare"
@@ -58,6 +58,12 @@
icon_state = "bottle12"
list_reagents = list("cyanide" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/spewium
name = "spewium bottle"
desc = "A small bottle of spewium."
icon_state = "bottle12"
list_reagents = list("spewium" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/morphine
name = "morphine bottle"
desc = "A small bottle of morphine."
+10
View File
@@ -0,0 +1,10 @@
/obj/docking_port/mobile/elevator
name = "elevator"
id = "elevator"
dwidth = 3
width = 7
height = 7
knockdown = FALSE
/obj/docking_port/mobile/elevator/request(obj/docking_port/stationary/S) //No transit, no ignition, just a simple up/down platform
dock(S, TRUE)
+3 -3
View File
@@ -3,7 +3,7 @@
return
// Called when shuttle attempts to move an atom.
/atom/movable/proc/onShuttleMove(turf/T1, rotation)
/atom/movable/proc/onShuttleMove(turf/T1, rotation, knockdown = TRUE)
if(rotation)
shuttleRotate(rotation)
loc = T1
@@ -47,11 +47,11 @@
else
shake_camera(src, 7, 1)
/mob/living/carbon/onShuttleMove()
/mob/living/carbon/onShuttleMove(turf/T1, rotation, knockdown = TRUE)
. = ..()
if(!.)
return
if(!buckled)
if(!buckled && knockdown)
Weaken(3)
/obj/effect/abstract/proximity_checker/onShuttleMove()
+4 -5
View File
@@ -217,6 +217,8 @@
var/launch_status = NOLAUNCH
var/knockdown = TRUE //Will it knock down mobs when it docks?
// A timid shuttle will not register itself with the shuttle subsystem
// All shuttle templates are timid
var/timid = FALSE
@@ -517,7 +519,7 @@
//move mobile to new location
for(var/atom/movable/AM in T0)
if(AM.onShuttleMove(T1, rotation))
if(AM.onShuttleMove(T1, rotation, knockdown))
moved_atoms += AM
if(rotation)
@@ -578,10 +580,7 @@
if(M.pulledby)
M.pulledby.stop_pulling()
M.stop_pulling()
M.visible_message("<span class='warning'>[M] is hit by \
a hyperspace ripple!</span>",
"<span class='userdanger'>You feel an immense \
crushing pressure as the space around you ripples.</span>")
M.visible_message("<span class='warning'>[src] slams into [M]!</span>")
if(M.key || M.get_ghost(TRUE))
SSblackbox.add_details("shuttle_gib", "[type]")
else
@@ -62,29 +62,14 @@ Also, you never added distance checking after target is selected. I've went ahea
var/mob/caster = user//The wizard/whomever doing the body transferring.
//MIND TRANSFER BEGIN
if(caster.mind.special_verbs.len)//If the caster had any special verbs, remove them from the mob verb list.
for(var/V in caster.mind.special_verbs)//Since the caster is using an object spell system, this is mostly moot.
caster.verbs -= V//But a safety nontheless.
if(victim.mind.special_verbs.len)//Now remove all of the victim's verbs.
for(var/V in victim.mind.special_verbs)
victim.verbs -= V
var/mob/dead/observer/ghost = victim.ghostize(0)
caster.mind.transfer_to(victim)
if(victim.mind.special_verbs.len)//To add all the special verbs for the original caster.
for(var/V in caster.mind.special_verbs)//Not too important but could come into play.
caster.verbs += V
ghost.mind.transfer_to(caster)
if(ghost.key)
caster.key = ghost.key //have to transfer the key since the mind was not active
qdel(ghost)
if(caster.mind.special_verbs.len)//If they had any special verbs, we add them here.
for(var/V in caster.mind.special_verbs)
caster.verbs += V
//MIND TRANSFER END
//Here we paralyze both mobs and knock them out for a time.
@@ -218,6 +218,14 @@
for(var/X in list(owner.glasses, owner.ears, owner.wear_mask, owner.head))
var/obj/item/I = X
owner.dropItemToGround(I, TRUE)
//Handle dental implants
for(var/datum/action/item_action/hands_free/activate_pill/AP in owner.actions)
AP.Remove(owner)
var/obj/pill = AP.target
if(pill)
pill.forceMove(src)
name = "[owner.real_name]'s head"
..()
@@ -300,6 +308,14 @@
C.real_name = real_name
real_name = ""
name = initial(name)
//Handle dental implants
for(var/obj/item/weapon/reagent_containers/pill/P in src)
for(var/datum/action/item_action/hands_free/activate_pill/AP in P.actions)
P.forceMove(C)
AP.Grant(C)
break
..()
+4 -1
View File
@@ -48,7 +48,10 @@
brain = null
update_icon_dropped()
else
I.loc = T
if(istype(I, /obj/item/weapon/reagent_containers/pill))
for(var/datum/action/item_action/hands_free/activate_pill/AP in I.actions)
qdel(AP)
I.forceMove(T)
/obj/item/bodypart/head/update_limb(dropping_limb, mob/living/carbon/source)
var/mob/living/carbon/C
+2 -3
View File
@@ -18,10 +18,10 @@
user.drop_item()
tool.loc = target
var/datum/action/item_action/hands_free/activate_pill/P = new
var/datum/action/item_action/hands_free/activate_pill/P = new(tool)
P.button.name = "Activate [tool.name]"
P.target = tool
P.Grant(target)
P.Grant(target) //The pill never actually goes in an inventory slot, so the owner doesn't inherit actions from it
user.visible_message("[user] wedges \the [tool] into [target]'s [parse_zone(target_zone)]!", "<span class='notice'>You wedge [tool] into [target]'s [parse_zone(target_zone)].</span>")
return 1
@@ -37,6 +37,5 @@
if(target.reagents.total_volume)
target.reagents.reaction(owner, INGEST)
target.reagents.trans_to(owner, target.reagents.total_volume)
Remove(owner)
qdel(target)
return 1

Some files were not shown because too many files have changed in this diff Show More