Merge remote-tracking branch 'origin/master' into what-should-i-name-this-branch
This commit is contained in:
@@ -387,8 +387,7 @@
|
||||
log_combat(user, M, "used a cult spell on", source.name, "")
|
||||
M.set_last_attacker(user)
|
||||
|
||||
/obj/item/melee/blood_magic/afterattack(atom/target, mob/living/carbon/user, proximity)
|
||||
. = ..()
|
||||
/obj/item/melee/blood_magic/proc/post_cast(atom/target, mob/living/carbon/user, proximity)
|
||||
if(invocation)
|
||||
user.whisper(invocation, language = /datum/language/common)
|
||||
if(health_cost)
|
||||
@@ -467,6 +466,7 @@
|
||||
to_chat(user, "<span class='cultitalic'>In an brilliant flash of red, [L] [is_servant_of_ratvar(L) ? "writhes in pain!" : "falls to the ground!"]</span>")
|
||||
uses--
|
||||
..()
|
||||
post_cast(target, user, proximity)
|
||||
|
||||
//Teleportation
|
||||
/obj/item/melee/blood_magic/teleport
|
||||
@@ -480,40 +480,45 @@
|
||||
to_chat(user, "<span class='warning'>You can only teleport adjacent cultists with this spell!</span>")
|
||||
return
|
||||
if(iscultist(user))
|
||||
var/list/potential_runes = list()
|
||||
var/list/teleportnames = list()
|
||||
for(var/R in GLOB.teleport_runes)
|
||||
var/obj/effect/rune/teleport/T = R
|
||||
potential_runes[avoid_assoc_duplicate_keys(T.listkey, teleportnames)] = T
|
||||
|
||||
if(!potential_runes.len)
|
||||
to_chat(user, "<span class='warning'>There are no valid runes to teleport to!</span>")
|
||||
log_game("Teleport talisman failed - no other teleport runes")
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(is_away_level(T.z))
|
||||
to_chat(user, "<span class='cultitalic'>You are not in the right dimension!</span>")
|
||||
log_game("Teleport spell failed - user in away mission")
|
||||
return
|
||||
|
||||
var/input_rune_key = input(user, "Choose a rune to teleport to.", "Rune to Teleport to") as null|anything in potential_runes //we know what key they picked
|
||||
var/obj/effect/rune/teleport/actual_selected_rune = potential_runes[input_rune_key] //what rune does that key correspond to?
|
||||
if(QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated() || !actual_selected_rune || !proximity)
|
||||
return
|
||||
var/turf/dest = get_turf(actual_selected_rune)
|
||||
if(is_blocked_turf(dest, TRUE))
|
||||
to_chat(user, "<span class='warning'>The target rune is blocked. Attempting to teleport to it would be massively unwise.</span>")
|
||||
return
|
||||
uses--
|
||||
var/turf/origin = get_turf(user)
|
||||
var/mob/living/L = target
|
||||
if(do_teleport(L, dest, channel = TELEPORT_CHANNEL_CULT))
|
||||
origin.visible_message("<span class='warning'>Dust flows from [user]'s hand, and [user.p_they()] disappear[user.p_s()] with a sharp crack!</span>", \
|
||||
"<span class='cultitalic'>You speak the words of the talisman and find yourself somewhere else!</span>", "<i>You hear a sharp crack.</i>")
|
||||
dest.visible_message("<span class='warning'>There is a boom of outrushing air as something appears above the rune!</span>", null, "<i>You hear a boom.</i>")
|
||||
try_teleport(target, user, proximity)
|
||||
..()
|
||||
|
||||
/obj/item/melee/blood_magic/teleport/proc/try_teleport(atom/target, mob/living/carbon/user, proximity)
|
||||
set waitfor = FALSE
|
||||
var/list/potential_runes = list()
|
||||
var/list/teleportnames = list()
|
||||
for(var/R in GLOB.teleport_runes)
|
||||
var/obj/effect/rune/teleport/T = R
|
||||
potential_runes[avoid_assoc_duplicate_keys(T.listkey, teleportnames)] = T
|
||||
|
||||
if(!potential_runes.len)
|
||||
to_chat(user, "<span class='warning'>There are no valid runes to teleport to!</span>")
|
||||
log_game("Teleport talisman failed - no other teleport runes")
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(is_away_level(T.z))
|
||||
to_chat(user, "<span class='cultitalic'>You are not in the right dimension!</span>")
|
||||
log_game("Teleport spell failed - user in away mission")
|
||||
return
|
||||
|
||||
var/input_rune_key = input(user, "Choose a rune to teleport to.", "Rune to Teleport to") as null|anything in potential_runes //we know what key they picked
|
||||
var/obj/effect/rune/teleport/actual_selected_rune = potential_runes[input_rune_key] //what rune does that key correspond to?
|
||||
if(QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated() || !actual_selected_rune || !proximity)
|
||||
return
|
||||
var/turf/dest = get_turf(actual_selected_rune)
|
||||
if(is_blocked_turf(dest, TRUE))
|
||||
to_chat(user, "<span class='warning'>The target rune is blocked. Attempting to teleport to it would be massively unwise.</span>")
|
||||
return
|
||||
uses--
|
||||
var/turf/origin = get_turf(user)
|
||||
var/mob/living/L = target
|
||||
if(do_teleport(L, dest, channel = TELEPORT_CHANNEL_CULT))
|
||||
origin.visible_message("<span class='warning'>Dust flows from [user]'s hand, and [user.p_they()] disappear[user.p_s()] with a sharp crack!</span>", \
|
||||
"<span class='cultitalic'>You speak the words of the talisman and find yourself somewhere else!</span>", "<i>You hear a sharp crack.</i>")
|
||||
dest.visible_message("<span class='warning'>There is a boom of outrushing air as something appears above the rune!</span>", null, "<i>You hear a boom.</i>")
|
||||
post_cast(target, user, proximity)
|
||||
|
||||
//Shackles
|
||||
/obj/item/melee/blood_magic/shackles
|
||||
name = "Binding Aura"
|
||||
@@ -530,6 +535,7 @@
|
||||
user.visible_message("<span class='cultitalic'>This victim doesn't have enough arms to complete the restraint!</span>")
|
||||
return
|
||||
..()
|
||||
post_cast(target, user, proximity)
|
||||
|
||||
/obj/item/melee/blood_magic/shackles/proc/CuffAttack(mob/living/carbon/C, mob/living/user)
|
||||
if(!C.handcuffed)
|
||||
@@ -583,6 +589,7 @@
|
||||
to_chat(user, "<span class='warning'>A dark cloud emanates from your hand and swirls around the metal, twisting it into a construct shell!</span>")
|
||||
new /obj/structure/constructshell(T)
|
||||
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
|
||||
post_cast(target, proximity_flag, user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need 50 metal to produce a construct shell!</span>")
|
||||
else if(istype(target, /obj/item/stack/sheet/plasteel))
|
||||
@@ -593,56 +600,73 @@
|
||||
new /obj/item/stack/sheet/runed_metal(T,quantity)
|
||||
to_chat(user, "<span class='warning'>A dark cloud emanates from you hand and swirls around the plasteel, transforming it into runed metal!</span>")
|
||||
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
|
||||
post_cast(target, user, proximity_flag)
|
||||
if(istype(target, /obj/item/clothing/suit/hooded/wintercoat) && target.type != /obj/item/clothing/suit/hooded/wintercoat/narsie)
|
||||
if (do_after(user,30,target=target))
|
||||
new /obj/item/clothing/suit/hooded/wintercoat/narsie(T)
|
||||
qdel(target)
|
||||
to_chat(user, "<span class='warning'>A dark cloud emanates from you hand and swirls around [target], transforming it into a narsian winter coat!</span>")
|
||||
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
|
||||
convert_coat(target, user, proximity_flag, T)
|
||||
else if(istype(target,/mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/candidate = target
|
||||
if(!iscultist(user, TRUE))
|
||||
to_chat(user, "<span class='warning'>You are not strongly connected enough to Nar'sie to use make constructs...</span>")
|
||||
else if(candidate.mmi)
|
||||
user.visible_message("<span class='danger'>A dark cloud emanates from [user]'s hand and swirls around [candidate]!</span>")
|
||||
playsound(T, 'sound/machines/airlock_alien_prying.ogg', 80, 1)
|
||||
var/prev_color = candidate.color
|
||||
candidate.color = "black"
|
||||
if(do_after(user, 90, target = candidate))
|
||||
candidate.emp_act(80)
|
||||
var/construct_class = alert(user, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer")
|
||||
user.visible_message("<span class='danger'>The dark cloud receedes from what was formerly [candidate], revealing a\n [construct_class]!</span>")
|
||||
switch(construct_class)
|
||||
if("Juggernaut")
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/armored, candidate, user, 0, T)
|
||||
if("Wraith")
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/wraith, candidate, user, 0, T)
|
||||
if("Artificer")
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder, candidate, user, 0, T)
|
||||
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
|
||||
uses--
|
||||
candidate.mmi = null
|
||||
qdel(candidate)
|
||||
else
|
||||
candidate.color = prev_color
|
||||
else
|
||||
uses--
|
||||
to_chat(user, "<span class='warning'>A dark cloud emanates from you hand and swirls around [candidate] - twisting it into a construct shell!</span>")
|
||||
new /obj/structure/constructshell(T)
|
||||
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
|
||||
convert_borg(target, user, proximity_flag, T)
|
||||
else if(istype(target,/obj/machinery/door/airlock))
|
||||
playsound(T, 'sound/machines/airlockforced.ogg', 50, 1)
|
||||
do_sparks(5, TRUE, target)
|
||||
if(do_after(user, 50, target = user))
|
||||
target.narsie_act()
|
||||
uses--
|
||||
user.visible_message("<span class='warning'>Black ribbons suddenly emanate from [user]'s hand and cling to the airlock - twisting and corrupting it!</span>")
|
||||
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
|
||||
convert_door(target, user, proximity_flag, T)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The spell will not work on [target]!</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/melee/blood_magic/construction/proc/convert_coat(atom/target, mob/user, proximity_flag, turf/T)
|
||||
set waitfor = FALSE
|
||||
if(do_after(user,30,target=target))
|
||||
new /obj/item/clothing/suit/hooded/wintercoat/narsie(T)
|
||||
qdel(target)
|
||||
to_chat(user, "<span class='warning'>A dark cloud emanates from you hand and swirls around [target], transforming it into a narsian winter coat!</span>")
|
||||
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
|
||||
post_cast(target, user, proximity_flag)
|
||||
|
||||
/obj/item/melee/blood_magic/construction/proc/convert_door(atom/target, mob/user, proximity_flag, turf/T)
|
||||
set waitfor = FALSE
|
||||
playsound(T, 'sound/machines/airlockforced.ogg', 50, 1)
|
||||
do_sparks(5, TRUE, target)
|
||||
if(do_after(user, 50, target = user))
|
||||
target.narsie_act()
|
||||
uses--
|
||||
user.visible_message("<span class='warning'>Black ribbons suddenly emanate from [user]'s hand and cling to the airlock - twisting and corrupting it!</span>")
|
||||
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
|
||||
post_cast(target, user, proximity_flag)
|
||||
|
||||
/obj/item/melee/blood_magic/construction/proc/convert_borg(atom/target, mob/user, proximity_flag, turf/T)
|
||||
set waitfor = FALSE
|
||||
var/mob/living/silicon/robot/candidate = target
|
||||
if(!iscultist(user, TRUE))
|
||||
to_chat(user, "<span class='warning'>You are not strongly connected enough to Nar'sie to use make constructs...</span>")
|
||||
return
|
||||
else if(candidate.mmi)
|
||||
user.visible_message("<span class='danger'>A dark cloud emanates from [user]'s hand and swirls around [candidate]!</span>")
|
||||
playsound(T, 'sound/machines/airlock_alien_prying.ogg', 80, 1)
|
||||
var/prev_color = candidate.color
|
||||
candidate.color = "black"
|
||||
if(do_after(user, 90, target = candidate))
|
||||
candidate.emp_act(80)
|
||||
var/construct_class = alert(user, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer")
|
||||
user.visible_message("<span class='danger'>The dark cloud receedes from what was formerly [candidate], revealing a\n [construct_class]!</span>")
|
||||
switch(construct_class)
|
||||
if("Juggernaut")
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/armored, candidate, user, 0, T)
|
||||
if("Wraith")
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/wraith, candidate, user, 0, T)
|
||||
if("Artificer")
|
||||
makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder, candidate, user, 0, T)
|
||||
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
|
||||
uses--
|
||||
candidate.mmi = null
|
||||
qdel(candidate)
|
||||
else
|
||||
candidate.color = prev_color
|
||||
else
|
||||
uses--
|
||||
to_chat(user, "<span class='warning'>A dark cloud emanates from you hand and swirls around [candidate] - twisting it into a construct shell!</span>")
|
||||
new /obj/structure/constructshell(T)
|
||||
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
|
||||
post_cast(target, user, proximity_flag)
|
||||
|
||||
//Armor: Gives the target a basic cultist combat loadout
|
||||
/obj/item/melee/blood_magic/armor
|
||||
name = "Bladed Aura"
|
||||
@@ -665,6 +689,7 @@
|
||||
C.put_in_hands(new /obj/item/melee/cultblade(user))
|
||||
C.put_in_hands(new /obj/item/restraints/legcuffs/bola/cult(user))
|
||||
..()
|
||||
post_cast(target, user, proximity)
|
||||
|
||||
/obj/item/melee/blood_magic/manipulator
|
||||
name = "Ritual Aura"
|
||||
@@ -693,7 +718,9 @@
|
||||
H.adjust_integration_blood(uses * 2)
|
||||
to_chat(user,"<span class='danger'>You use the last of your blood rites to restore what blood you could!</span>")
|
||||
uses = 0
|
||||
return ..()
|
||||
..()
|
||||
post_cast(target, user, proximity)
|
||||
return
|
||||
else
|
||||
H.blood_volume = (BLOOD_VOLUME_SAFE*H.blood_ratio)
|
||||
uses -= round(restore_blood/2)
|
||||
@@ -758,6 +785,7 @@
|
||||
if(istype(target, /obj/effect/decal/cleanable/blood))
|
||||
blood_draw(target, user)
|
||||
..()
|
||||
post_cast()
|
||||
|
||||
/obj/item/melee/blood_magic/manipulator/proc/blood_draw(atom/target, mob/living/carbon/human/user)
|
||||
var/temp = 0
|
||||
|
||||
@@ -660,40 +660,42 @@
|
||||
return
|
||||
|
||||
if(istype(A, /obj/item))
|
||||
|
||||
var/list/cultists = list()
|
||||
for(var/datum/mind/M in SSticker.mode.cult)
|
||||
if(M.current && M.current.stat != DEAD)
|
||||
cultists |= M.current
|
||||
var/mob/living/cultist_to_receive = input(user, "Who do you wish to call to [src]?", "Followers of the Geometer") as null|anything in (cultists - user)
|
||||
if(!Adjacent(user) || !src || QDELETED(src) || user.incapacitated())
|
||||
return
|
||||
if(!cultist_to_receive)
|
||||
to_chat(user, "<span class='cult italic'>You require a destination!</span>")
|
||||
log_game("Void torch failed - no target")
|
||||
return
|
||||
if(cultist_to_receive.stat == DEAD)
|
||||
to_chat(user, "<span class='cult italic'>[cultist_to_receive] has died!</span>")
|
||||
log_game("Void torch failed - target died")
|
||||
return
|
||||
if(!iscultist(cultist_to_receive))
|
||||
to_chat(user, "<span class='cult italic'>[cultist_to_receive] is not a follower of the Geometer!</span>")
|
||||
log_game("Void torch failed - target was deconverted")
|
||||
return
|
||||
if(A in user.GetAllContents())
|
||||
to_chat(user, "<span class='cult italic'>[A] must be on a surface in order to teleport it!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='cult italic'>You ignite [A] with \the [src], turning it to ash, but through the torch's flames you see that [A] has reached [cultist_to_receive]!")
|
||||
cultist_to_receive.put_in_hands(A)
|
||||
charges--
|
||||
to_chat(user, "\The [src] now has [charges] charge\s.")
|
||||
if(charges == 0)
|
||||
qdel(src)
|
||||
transmit_item(A, user, proximity)
|
||||
|
||||
else
|
||||
..()
|
||||
to_chat(user, "<span class='warning'>\The [src] can only transport items!</span>")
|
||||
|
||||
/obj/item/flashlight/flare/culttorch/proc/transmit_item(atom/movable/A, mob/user, proximity)
|
||||
set waitfor = FALSE
|
||||
var/list/cultists = list()
|
||||
for(var/datum/mind/M in SSticker.mode.cult)
|
||||
if(M.current && M.current.stat != DEAD)
|
||||
cultists |= M.current
|
||||
var/mob/living/cultist_to_receive = input(user, "Who do you wish to call to [src]?", "Followers of the Geometer") as null|anything in (cultists - user)
|
||||
if(!Adjacent(user) || !src || QDELETED(src) || user.incapacitated())
|
||||
return
|
||||
if(!cultist_to_receive)
|
||||
to_chat(user, "<span class='cult italic'>You require a destination!</span>")
|
||||
log_game("Void torch failed - no target")
|
||||
return
|
||||
if(cultist_to_receive.stat == DEAD)
|
||||
to_chat(user, "<span class='cult italic'>[cultist_to_receive] has died!</span>")
|
||||
log_game("Void torch failed - target died")
|
||||
return
|
||||
if(!iscultist(cultist_to_receive))
|
||||
to_chat(user, "<span class='cult italic'>[cultist_to_receive] is not a follower of the Geometer!</span>")
|
||||
log_game("Void torch failed - target was deconverted")
|
||||
return
|
||||
if(A in user.GetAllContents())
|
||||
to_chat(user, "<span class='cult italic'>[A] must be on a surface in order to teleport it!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='cult italic'>You ignite [A] with \the [src], turning it to ash, but through the torch's flames you see that [A] has reached [cultist_to_receive]!")
|
||||
cultist_to_receive.put_in_hands(A)
|
||||
charges--
|
||||
to_chat(user, "\The [src] now has [charges] charge\s.")
|
||||
if(charges == 0)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/cult_spear
|
||||
name = "blood halberd"
|
||||
|
||||
@@ -34,14 +34,16 @@
|
||||
|
||||
/obj/item/assembly/proc/on_attach()
|
||||
|
||||
/obj/item/assembly/proc/on_detach() //call this when detaching it from a device. handles any special functions that need to be updated ex post facto
|
||||
///Call this when detaching it from a device. handles any special functions that need to be updated ex post facto
|
||||
/obj/item/assembly/proc/on_detach()
|
||||
if(!holder)
|
||||
return FALSE
|
||||
forceMove(holder.drop_location())
|
||||
holder = null
|
||||
return TRUE
|
||||
|
||||
/obj/item/assembly/proc/holder_movement() //Called when the holder is moved
|
||||
///Called when the holder is moved
|
||||
/obj/item/assembly/proc/holder_movement()
|
||||
if(!holder)
|
||||
return FALSE
|
||||
setDir(holder.dir)
|
||||
@@ -53,7 +55,6 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
//Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs
|
||||
/obj/item/assembly/proc/pulsed(radio = FALSE)
|
||||
if(wire_type & WIRE_RECEIVE)
|
||||
@@ -62,7 +63,6 @@
|
||||
INVOKE_ASYNC(src, .proc/activate)
|
||||
return TRUE
|
||||
|
||||
|
||||
//Called when this device attempts to act on another device, var/radio determines if it was sent via radio or direct
|
||||
/obj/item/assembly/proc/pulse(radio = FALSE)
|
||||
if(connected && wire_type)
|
||||
@@ -74,7 +74,6 @@
|
||||
holder.process_activation(src, 0, 1)
|
||||
return TRUE
|
||||
|
||||
|
||||
// What the device does when turned on
|
||||
/obj/item/assembly/proc/activate()
|
||||
if(QDELETED(src) || !secured || (next_activate > world.time))
|
||||
@@ -82,13 +81,11 @@
|
||||
next_activate = world.time + activate_cooldown
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/assembly/proc/toggle_secure()
|
||||
secured = !secured
|
||||
update_icon()
|
||||
return secured
|
||||
|
||||
|
||||
/obj/item/assembly/attackby(obj/item/W, mob/user, params)
|
||||
if(isassembly(W))
|
||||
var/obj/item/assembly/A = W
|
||||
@@ -115,7 +112,6 @@
|
||||
. = ..()
|
||||
. += "<span class='notice'>\The [src] [secured? "is secured and ready to be used!" : "can be attached to other things."]</span>"
|
||||
|
||||
|
||||
/obj/item/assembly/attack_self(mob/user)
|
||||
if(!user)
|
||||
return FALSE
|
||||
@@ -125,3 +121,11 @@
|
||||
|
||||
/obj/item/assembly/interact(mob/user)
|
||||
return ui_interact(user)
|
||||
|
||||
/obj/item/assembly/ui_host(mob/user)
|
||||
if(holder)
|
||||
return holder
|
||||
return src
|
||||
|
||||
/obj/item/assembly/ui_state(mob/user)
|
||||
return GLOB.hands_state
|
||||
|
||||
@@ -88,14 +88,14 @@
|
||||
if(a_right)
|
||||
a_right.dropped(user)
|
||||
|
||||
/obj/item/assembly_holder/on_attack_hand()//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess
|
||||
/obj/item/assembly_holder/on_attack_hand(user, act_intent)//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(a_left)
|
||||
a_left.attack_hand()
|
||||
a_left.attack_hand(user, act_intent)
|
||||
if(a_right)
|
||||
a_right.attack_hand()
|
||||
a_right.attack_hand(user, act_intent)
|
||||
|
||||
/obj/item/assembly_holder/screwdriver_act(mob/user, obj/item/tool)
|
||||
if(..())
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
GLOBAL_VAR_INIT(save_area_executing, FALSE)
|
||||
|
||||
/datum/mapGenerator/save_area
|
||||
buildmode_name = "Save Area"
|
||||
modules = list(/datum/mapGeneratorModule/save_area)
|
||||
var/min_x = 0
|
||||
var/min_y = 0
|
||||
var/max_x = 0
|
||||
var/max_y = 0
|
||||
|
||||
/datum/mapGenerator/save_area/defineRegion(turf/Start, turf/End, replace = 0)
|
||||
min_x = min(Start.x,End.x)
|
||||
min_y = min(Start.y,End.y)
|
||||
max_x = max(Start.x,End.x)
|
||||
max_y = max(Start.y,End.y)
|
||||
..()
|
||||
|
||||
/datum/mapGeneratorModule/save_area
|
||||
var/areaName = "default.dm"
|
||||
|
||||
//This could be optimised by making turfs that are the same go in the same, but this is a quick bodge solution so yea, fun job for coder here :)
|
||||
/datum/mapGeneratorModule/save_area/generate()
|
||||
var/datum/mapGenerator/save_area/L = mother
|
||||
if(!istype(L))
|
||||
return
|
||||
//If someone somehow gets build mode, stop them from using this.
|
||||
if(!check_rights(R_ADMIN))
|
||||
message_admins("[ckey(usr)] tried to run the map save generator but was rejected due to insufficient perms.")
|
||||
to_chat(usr, "<span class='warning'>You must have R_ADMIN privellages to use this.</span>")
|
||||
return
|
||||
//Emergency check
|
||||
if(L.map.len > 1600)
|
||||
var/confirm = alert("Uhm, are you sure, the area is quiet large?", "Run generator", "Yes", "No")
|
||||
if(confirm != "Yes")
|
||||
return
|
||||
|
||||
if(GLOB.save_area_executing)
|
||||
to_chat(usr, "<span class='warning'>Someone is already running the generator! Try again in a bit.</span>")
|
||||
return
|
||||
|
||||
to_chat(usr, "<span class='warning'>Saving, please wait...</span>")
|
||||
GLOB.save_area_executing = TRUE
|
||||
|
||||
//Log just in case something happens
|
||||
log_game("[key_name(usr)] ran the save level map generator on [L.map.len] turfs.")
|
||||
message_admins("[key_name(usr)] ran the save level map generator on [L.map.len] turfs.")
|
||||
|
||||
//Step 1: Get the data (This can take a while)
|
||||
var/dat = "//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE\n"
|
||||
dat += convert_map_to_tgm(L.map)
|
||||
|
||||
//Step 2: Write the data to a file
|
||||
var/filedir = file("data/temp.dmm")
|
||||
if(fexists(filedir))
|
||||
fdel(filedir)
|
||||
WRITE_FILE(filedir, "[dat]")
|
||||
|
||||
//Step 3: Give the file to client for download
|
||||
usr << ftp(filedir)
|
||||
|
||||
//Step 4: Remove the file from the server (hopefully we can find a way to avoid step)
|
||||
fdel(filedir)
|
||||
log_game("[L.map.len] turfs have been saved by [ckey(usr)]")
|
||||
alert("Area saved successfully.", "Action Successful!", "Ok")
|
||||
GLOB.save_area_executing = FALSE
|
||||
@@ -21,8 +21,6 @@
|
||||
var/active_sound = null
|
||||
var/toggle_cooldown = null
|
||||
var/cooldown = 0
|
||||
var/obj/item/flashlight/F = null
|
||||
var/can_flashlight = 0
|
||||
|
||||
var/blocks_shove_knockdown = FALSE //Whether wearing the clothing item blocks the ability for shove to knock down.
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/obj/item/clothing/gloves/mittens
|
||||
desc = "These gloves will keep your hands warm!"
|
||||
name = "mittens"
|
||||
icon_state = "mittens"
|
||||
item_state = "wgloves"
|
||||
//item_color = "white"
|
||||
cold_protection = HANDS
|
||||
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
|
||||
resistance_flags = NONE
|
||||
|
||||
/obj/item/clothing/gloves/mittens/random
|
||||
|
||||
/obj/item/clothing/gloves/mittens/random/Initialize()
|
||||
..()
|
||||
var/colours = list("black", "yellow", "lightbrown", "brown", "orange", "red", "purple", "green", "blue", "kitten")
|
||||
var/picked_c = pick(colours)
|
||||
if(picked_c == "kitten")
|
||||
new /obj/item/clothing/gloves/mittens/kitten(loc)
|
||||
qdel(src)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
item_state = "[picked_c]gloves"
|
||||
//item_color = "[picked_c]"
|
||||
color = picked_c
|
||||
|
||||
/obj/item/clothing/gloves/mittens/kitten
|
||||
name = "Kitten mittens"
|
||||
desc = "These gloves will keep your hands warm, and feature cute kittens"
|
||||
icon_state = "kittenmittens"
|
||||
item_state = "blackgloves"
|
||||
//item_color = "black"
|
||||
@@ -16,17 +16,47 @@
|
||||
|
||||
dog_fashion = /datum/dog_fashion/head/helmet
|
||||
|
||||
var/can_flashlight = FALSE //if a flashlight can be mounted. if it has a flashlight and this is false, it is permanently attached.
|
||||
var/obj/item/flashlight/seclite/attached_light
|
||||
var/datum/action/item_action/toggle_helmet_flashlight/alight
|
||||
|
||||
/obj/item/clothing/head/helmet/Initialize(mapload)
|
||||
. = ..()
|
||||
if(attached_light)
|
||||
alight = new(src)
|
||||
|
||||
/obj/item/clothing/head/helmet/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/wearertargeting/earprotection, list(SLOT_HEAD))
|
||||
|
||||
/obj/item/clothing/head/helmet/examine(mob/user)
|
||||
. = ..()
|
||||
if(attached_light)
|
||||
. += "It has \a [attached_light] [can_flashlight ? "" : "permanently "]mounted on it."
|
||||
if(can_flashlight)
|
||||
. += "<span class='info'>[attached_light] looks like it can be <b>unscrewed</b> from [src].</span>"
|
||||
else if(can_flashlight)
|
||||
. += "It has a mounting point for a <b>seclite</b>."
|
||||
|
||||
/obj/item/clothing/head/helmet/Destroy()
|
||||
QDEL_NULL(attached_light)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/head/helmet/handle_atom_del(atom/A)
|
||||
if(A == attached_light)
|
||||
attached_light = null
|
||||
update_helmlight()
|
||||
update_icon()
|
||||
QDEL_NULL(alight)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/head/helmet/sec
|
||||
can_flashlight = 1
|
||||
|
||||
/obj/item/clothing/head/helmet/sec/attackby(obj/item/I, mob/user, params)
|
||||
if(issignaler(I))
|
||||
var/obj/item/assembly/signaler/S = I
|
||||
if(F) //Has a flashlight. Player must remove it, else it will be lost forever.
|
||||
if(attached_light) //Has a flashlight. Player must remove it, else it will be lost forever.
|
||||
to_chat(user, "<span class='warning'>The mounted flashlight is in the way, remove it first!</span>")
|
||||
return
|
||||
|
||||
@@ -280,8 +310,8 @@
|
||||
|
||||
/obj/item/clothing/head/helmet/update_icon_state()
|
||||
var/state = "[initial(icon_state)]"
|
||||
if(F)
|
||||
if(F.on)
|
||||
if(attached_light)
|
||||
if(attached_light.on)
|
||||
state += "-flight-on" //"helmet-flight-on" // "helmet-cam-flight-on"
|
||||
else
|
||||
state += "-flight" //etc.
|
||||
@@ -289,7 +319,7 @@
|
||||
icon_state = state
|
||||
|
||||
/obj/item/clothing/head/helmet/ui_action_click(mob/user, action)
|
||||
if(istype(action, /datum/action/item_action/toggle_helmet_flashlight))
|
||||
if(istype(action, alight))
|
||||
toggle_helmlight()
|
||||
else
|
||||
..()
|
||||
@@ -297,60 +327,60 @@
|
||||
/obj/item/clothing/head/helmet/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/flashlight/seclite))
|
||||
var/obj/item/flashlight/seclite/S = I
|
||||
if(can_flashlight)
|
||||
if(!F)
|
||||
if(!user.transferItemToLoc(S, src))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You click [S] into place on [src].</span>")
|
||||
if(S.on)
|
||||
set_light(0)
|
||||
F = S
|
||||
update_icon()
|
||||
update_helmlight(user)
|
||||
verbs += /obj/item/clothing/head/helmet/proc/toggle_helmlight
|
||||
var/datum/action/A = new /datum/action/item_action/toggle_helmet_flashlight(src)
|
||||
if(loc == user)
|
||||
A.Grant(user)
|
||||
if(can_flashlight && !attached_light)
|
||||
if(!user.transferItemToLoc(S, src))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You click [S] into place on [src].</span>")
|
||||
if(S.on)
|
||||
set_light(0)
|
||||
attached_light = S
|
||||
update_icon()
|
||||
update_helmlight()
|
||||
alight = new(src)
|
||||
if(loc == user)
|
||||
alight.Grant(user)
|
||||
return
|
||||
|
||||
if(I.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
if(F)
|
||||
for(var/obj/item/flashlight/seclite/S in src)
|
||||
to_chat(user, "<span class='notice'>You unscrew the seclite from [src].</span>")
|
||||
F = null
|
||||
S.forceMove(user.drop_location())
|
||||
update_helmlight(user)
|
||||
S.update_brightness(user)
|
||||
update_icon()
|
||||
usr.update_inv_head()
|
||||
verbs -= /obj/item/clothing/head/helmet/proc/toggle_helmlight
|
||||
for(var/datum/action/item_action/toggle_helmet_flashlight/THL in actions)
|
||||
qdel(THL)
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/head/helmet/screwdriver_act(mob/living/user, obj/item/I)
|
||||
..()
|
||||
if(can_flashlight && attached_light) //if it has a light but can_flashlight is false, the light is permanently attached.
|
||||
I.play_tool_sound(src)
|
||||
to_chat(user, "<span class='notice'>You unscrew [attached_light] from [src].</span>")
|
||||
attached_light.forceMove(drop_location())
|
||||
if(Adjacent(user) && !issilicon(user))
|
||||
user.put_in_hands(attached_light)
|
||||
|
||||
var/obj/item/flashlight/removed_light = attached_light
|
||||
attached_light = null
|
||||
update_helmlight()
|
||||
removed_light.update_brightness(user)
|
||||
update_icon()
|
||||
user.update_inv_head()
|
||||
QDEL_NULL(alight)
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/head/helmet/proc/toggle_helmlight()
|
||||
set name = "Toggle Helmetlight"
|
||||
set category = "Object"
|
||||
set desc = "Click to toggle your helmet's attached flashlight."
|
||||
|
||||
if(!F)
|
||||
if(!attached_light)
|
||||
return
|
||||
|
||||
var/mob/user = usr
|
||||
if(user.incapacitated())
|
||||
return
|
||||
F.on = !F.on
|
||||
to_chat(user, "<span class='notice'>You toggle the helmetlight [F.on ? "on":"off"].</span>")
|
||||
attached_light.on = !attached_light.on
|
||||
to_chat(user, "<span class='notice'>You toggle the helmet-light [attached_light.on ? "on":"off"].</span>")
|
||||
|
||||
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
|
||||
update_helmlight(user)
|
||||
|
||||
/obj/item/clothing/head/helmet/proc/update_helmlight(mob/user = null)
|
||||
if(F)
|
||||
if(F.on)
|
||||
set_light(F.brightness_on, F.flashlight_power, F.light_color)
|
||||
if(attached_light)
|
||||
if(attached_light.on)
|
||||
set_light(attached_light.brightness_on, attached_light.flashlight_power, attached_light.light_color)
|
||||
else
|
||||
set_light(0)
|
||||
update_icon()
|
||||
|
||||
@@ -53,5 +53,5 @@
|
||||
desc = "An ironically skimpy blue dress with gold markings denoting the rank of \"Captain\"."
|
||||
icon_state = "lewdcap"
|
||||
item_state = "lewdcap"
|
||||
can_adjust = FALSE
|
||||
alt_covers_chest = TRUE
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|USE_TAUR_CLIP_MASK
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#define RANDOM_EVENT_ADMIN_INTERVENTION_TIME 10
|
||||
#define RANDOM_EVENT_ADMIN_INTERVENTION_TIME 30
|
||||
|
||||
//this datum is used by the events controller to dictate how it selects events
|
||||
/datum/round_event_control
|
||||
|
||||
@@ -511,7 +511,150 @@
|
||||
. |= MOBILITY_MOVE
|
||||
mobility_flags = .
|
||||
|
||||
//Christmas car spawner
|
||||
|
||||
/mob/living/simple_animal/jacq/car_spawner
|
||||
name = "Jacqueline cars terminal"
|
||||
icon_state = "jacq_cars_spawner"
|
||||
AIStatus = AI_OFF
|
||||
spawn_cars = TRUE
|
||||
active = FALSE
|
||||
|
||||
/mob/living/simple_animal/jacq/car_spawner/Destroy()
|
||||
visible_message("The <b>[src]</b> gives out an error sound, <span class='spooky'>\"Ey! Bugger off!\"</span>")
|
||||
fully_heal(FALSE)
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/jacq/car_spawner/death()
|
||||
visible_message("The <b>[src]</b> gives out an error sound, <span class='spooky'>\"Ey! Bugger off!\"</span>")
|
||||
fully_heal(FALSE)
|
||||
|
||||
/mob/living/simple_animal/jacq/car_spawner/poof()
|
||||
if(!active)//if disabled, don't poof
|
||||
return
|
||||
var/datum/reagents/R = new/datum/reagents(100)//Hey, just in case.
|
||||
var/datum/effect_system/smoke_spread/chem/s = new()
|
||||
R.add_reagent(/datum/reagent/fermi/secretcatchem, 10)
|
||||
s.set_up(R, 0, loc)
|
||||
s.start()
|
||||
stopmove()
|
||||
health = 25
|
||||
|
||||
/mob/living/simple_animal/jacq/car_spawner/spawn_cars(mob/living/carbon/C)
|
||||
visible_message("<b>[src]</b> boots up and displays jacq's glowing smile, <span class='spooky'>\"Hallo there user! Merry Christmas! What ken type o' craft ken Ah offer ye? I can magic up a vectorcraft in manual, automatic or customise it if yer feeling technical.\"</span>")
|
||||
jacqrunes("Hallo there user! What ken type o' craft ken Ah offer ye? I can magic up a vectorcraft in manual, automatic or customise it if yer feeling technical.", C)
|
||||
|
||||
var/choices_reward = list("Manual", "Automatic", "Customise", "Are you a computer now Jacq?", "Nothing, thanks")
|
||||
var/choice_reward = input(usr, "Merry Trick_or_Treat.exe initiated!", "Merry Trick_or_Treat.exe initiated!") in choices_reward
|
||||
|
||||
switch(choice_reward)
|
||||
if("Manual")
|
||||
visible_message("The <b>[src]</b> makes a magical booping sound, <span class='spooky'>\"Great choice! 'Ere's yer car.\"</span>")
|
||||
jacqrunes("Great choice! 'Ere's yer car.", C)
|
||||
new /obj/vehicle/sealed/vectorcraft(loc)
|
||||
if("Automatic")
|
||||
visible_message("<b>[src]</b> makes a magical booping sound, <span class='spooky'>\"'Ere's yer car. Not as fast as an automatic mind.\"</span>")
|
||||
jacqrunes("'Ere's yer car. Not as fast as an automatic mind.", C)
|
||||
new /obj/vehicle/sealed/vectorcraft/auto(loc)
|
||||
if("Are you a computer now Jacq?")
|
||||
visible_message("<b>[src]</b> makes a frustrated error sound, <span class='spooky'>\"Nae, are ye daft? Ah built these thingies tae magic up cars fer ye. Well, I got a speccy four eyes tae do it fer me, but me names on it like cause it was me idea.\"</span>")
|
||||
jacqrunes("Nae, are ye daft? Ah built these thingies tae magic up cars fer ye. Well, I got a speccy four eyes tae do it fer me, but me names on it like cause it was me idea.", C)
|
||||
if("Customise")
|
||||
visible_message("The <b>[src]</b> pings, <span class='spooky'>\"Arright, Manual or Automatic?\"</span>")
|
||||
var/choices_transm = list("Manual", "Automatic")
|
||||
var/choice_transm = input(usr, "Choose transmission", "Choose transmission") in choices_transm
|
||||
var/points = 0
|
||||
var/obj/vehicle/sealed/vectorcraft/VC
|
||||
switch(choice_transm)
|
||||
if("Manual")
|
||||
VC = new /obj/vehicle/sealed/vectorcraft(loc)
|
||||
if("Automatic")
|
||||
VC = new /obj/vehicle/sealed/vectorcraft/auto(loc)
|
||||
points += 500
|
||||
|
||||
visible_message("The <b>[src]</b> pings, <span class='spooky'>\"Maximum acceleration? (default [VC.max_acceleration], max 10)\"</span>")
|
||||
var/max_accl = text2num(input(usr, "Maximum acceleration? (default [VC.max_acceleration], max 10)", "[VC.max_acceleration]"))
|
||||
max_accl = clamp(max_accl, 0, 10)
|
||||
VC.max_acceleration = max_accl
|
||||
VC.i_m_acell = max_accl
|
||||
points += max_accl*10
|
||||
|
||||
/* This is internally used
|
||||
visible_message("The <b>[src]</b> pings, <span class='spooky'>\"Acceleration step? (default 0.3, max 1)\"</span>")
|
||||
var/max_accl_s = text2num(input(usr, "Acceleration step? (default 0.3, max 1)", "[VC.accel_step]"))
|
||||
max_accl_s = clamp(max_accl_s, 0, 1)
|
||||
VC.max_acceleration = max_accl_s
|
||||
points += max_accl_s*100
|
||||
*/
|
||||
|
||||
visible_message("The <b>[src]</b> pings, <span class='spooky'>\"Acceleration? (default [VC.acceleration], max 2)\"</span>")
|
||||
var/accl = text2num(input(usr, "Acceleration? (default [VC.acceleration], max 2)", "[VC.acceleration]"))
|
||||
accl = clamp(accl, 0, 2)
|
||||
VC.acceleration = accl
|
||||
VC.i_acell = accl
|
||||
points += accl*100
|
||||
|
||||
visible_message("The <b>[src]</b> pings, <span class='spooky'>\"Maximum deceleration? (default [VC.max_deceleration], max 15)\"</span>")
|
||||
var/deaccl = text2num(input(usr, "Max_deceleration? (default [VC.max_deceleration], max 15)", "[VC.max_deceleration]"))
|
||||
deaccl = clamp(deaccl, 0, 15)
|
||||
VC.max_deceleration = deaccl
|
||||
VC.i_m_decell = deaccl
|
||||
points += deaccl*10
|
||||
|
||||
visible_message("The <b>[src]</b> pings, <span class='spooky'>\"Maximum velocity? (default [VC.max_velocity], max 200)\"</span>")
|
||||
var/m_velo = text2num(input(usr, "Maximum velocity? (default [VC.max_velocity], max 200)", "[VC.max_velocity]"))
|
||||
m_velo = clamp(m_velo, 0, 200)
|
||||
VC.max_velocity = m_velo
|
||||
points += m_velo
|
||||
|
||||
visible_message("The <b>[src]</b> pings, <span class='spooky'>\"Boost power? (default [VC.boost_power], max 200)\"</span>")
|
||||
var/boost = text2num(input(usr, "Boost power? (default [VC.boost_power], max 200)", "[VC.boost_power]"))
|
||||
boost = clamp(boost, 0, 200)
|
||||
VC.boost_power = boost
|
||||
VC.i_boost = boost
|
||||
points += boost
|
||||
|
||||
visible_message("The <b>[src]</b> pings, <span class='spooky'>\"Health points? (default [VC.max_integrity], max 1000)\"</span>")
|
||||
var/health = text2num(input(usr, "Health points? (default [VC.max_integrity], max 1000)", "[VC.max_integrity]"))
|
||||
health = clamp(health, 0, 500)
|
||||
VC.max_integrity = health
|
||||
points += health/2
|
||||
|
||||
visible_message("The <b>[src]</b> pings, <span class='spooky'>\"Arright, 'ow do ye want it tae look?\"</span>")
|
||||
var/choices_icon = list("Racer", "Truck", "Cyber", "Ambulance", "Pod", "Clown")
|
||||
var/choice_icon = input(usr, "Choose body", "Choose body") in choices_icon
|
||||
switch(choice_icon)
|
||||
if("Truck")
|
||||
VC.icon_state = "truck"
|
||||
|
||||
if("Cyber")
|
||||
VC.icon_state = "cyber"
|
||||
|
||||
if("Ambulance")
|
||||
VC.icon_state = "ambutruck"
|
||||
|
||||
if("Pod")
|
||||
VC.icon_state = "engineering_pod"
|
||||
|
||||
if("Clown")
|
||||
VC.icon_state = "clowncar"
|
||||
|
||||
visible_message("The <b>[src]</b> pings, <span class='spooky'>\"Finally; what name are ye gonna give it?\"</span>")
|
||||
var/choice_name = input(usr, "Pick a name!", "")
|
||||
choice_name += " (Points cost:[points])"
|
||||
VC.name = choice_name
|
||||
|
||||
visible_message("The <b>[src]</b> gives a final boop, <span class='spooky'>\"There ye be, enjoy!\"</span>")
|
||||
|
||||
if("How do Automatics work?")
|
||||
visible_message("The image of Jacq on the <b>[src]</b> smiles, <span class='spooky'>\"Hold wasd to gain speed in a direction, c to enable/disable the clutch, 1 2 3 4 to change gears (help is gear 1, disarm is gear 2, grab is gear 3 and harm is gear 4) while holding a direction (make sure the clutch is enabled when you change gears, you should hear a sound when you've successfully changed gears), r to toggle handbrake, hold alt for brake and press shift for boost (the machine will beep when the boost is recharged)! If you hear an ebbing sound like \"brbrbrbrbr\" you need to gear down, the whining sound means you need to gear up. Hearing a pleasant \"whumwhumwhum\" is optimal gearage! It can be a lil slow to start, so make sure you're in the 1st gear, andusing a boost to get you started is a good idea. If you've got a good speed you'll likely never need to dip down to gear 1 again, and make sure to hold the acceleration pedal down while changing gears (hold a direction). 1st gear is for slow movement, and it's a good idea to mvoe to 2nd gear as quick as you can, you can coldstart a car from gear one by slowly moving, then using the boost to jump you up to gear 2 speeds. The upper gears are for unlimiting your top speed.\"</span>")
|
||||
jacqrunes("They're a bit tricky, aye. Basically;", C)
|
||||
if("Nothing, thanks")
|
||||
visible_message("The image of Jacq on the <b>[src]</b> shrugs, <span class='spooky'>\"Suit yerself.\"</span>")
|
||||
jacqrunes("Suit yerself.", C)
|
||||
|
||||
visible_message("The <b>[src]</b> beeps, <span class='spooky'>\"Oh and look after the crafts, aye? They can get a wee bit... explosive if banged up a tad too much. They move slower damaged too like. Ye can repair 'em with the welders o'er there.\"</span>")
|
||||
jacqrunes("Oh and look after the crafts, aye? They can get a wee bit... explosive if banged up a tad too much. They move slower damaged too like. Ye can repair 'em with the welders o'er there. ", C)
|
||||
|
||||
/obj/item/clothing/head/hardhat/pumpkinhead/jaqc
|
||||
name = "Jacq o' latern"
|
||||
@@ -588,9 +731,13 @@
|
||||
|
||||
/obj/item/reagent_containers/potion_container/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
|
||||
..()
|
||||
delayed_release_smoke()
|
||||
|
||||
/obj/item/reagent_containers/potion_container/proc/delayed_release_smoke()
|
||||
set waitfor = FALSE
|
||||
sleep(20)
|
||||
var/datum/effect_system/smoke_spread/chem/s = new()
|
||||
s.set_up(src.reagents, 3, src.loc)
|
||||
s.set_up(src.reagents, 3, get_turf(src))
|
||||
s.start()
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
//Map exporter
|
||||
//Inputting a list of turfs into convert_map_to_tgm() will output a string
|
||||
//with the turfs and their objects / areas on said turf into the TGM mapping format
|
||||
//for .dmm files. This file can then be opened in the map editor or imported
|
||||
//back into the game.
|
||||
//============================
|
||||
//This has been made semi-modular so you should be able to use these functions
|
||||
//elsewhere in code if you ever need to get a file in the .dmm format
|
||||
/atom/proc/get_save_vars()
|
||||
return
|
||||
|
||||
GLOBAL_LIST_INIT(save_file_chars, list(
|
||||
"a","b","c","d","e",
|
||||
"f","g","h","i","j",
|
||||
"k","l","m","n","o",
|
||||
"p","q","r","s","t",
|
||||
"u","v","w","x","y",
|
||||
"z","A","B","C","D",
|
||||
"E","F","G","H","I",
|
||||
"J","K","L","M","N",
|
||||
"O","P","Q","R","S",
|
||||
"T","U","V","W","X",
|
||||
"Y","Z"
|
||||
))
|
||||
|
||||
//Converts a list of turfs into TGM file format
|
||||
/proc/convert_map_to_tgm(list/map,\
|
||||
save_flag = SAVE_ALL, \
|
||||
shuttle_area_flag = SAVE_SHUTTLEAREA_DONTCARE, \
|
||||
list/vars_to_save = list("pixel_x", "pixel_y", "dir", "name", "req_access", "req_access_txt", "piping_layer", "color", "icon_state", "pipe_color", "amount"),\
|
||||
list/obj_blacklist = list())
|
||||
//Calculate the bounds
|
||||
var/minx = 1024
|
||||
var/miny = 1024
|
||||
var/maxx = -1
|
||||
var/maxy = -1
|
||||
for(var/turf/place in map)
|
||||
minx = min(place.x, minx)
|
||||
miny = min(place.y, miny)
|
||||
maxx = max(place.x, maxx)
|
||||
maxy = max(place.y, maxy)
|
||||
var/width = maxx - minx + 1
|
||||
var/height = maxy - miny + 1
|
||||
|
||||
//Sort the map so weird shaped / bad inputted maps can be handled
|
||||
var/list/sortedmap = sort_map(map, minx, miny, maxx, maxy)
|
||||
|
||||
//Step 0: Calculate the amount of letters we need (26 ^ n > turf count)
|
||||
var/turfsNeeded = width * height
|
||||
var/layers = FLOOR(log(GLOB.save_file_chars.len, turfsNeeded) + 0.999,1)
|
||||
|
||||
//Step 1: Run through the area and generate file data
|
||||
var/list/header_chars = list() //The characters of the header
|
||||
var/list/header_dat = list() //The data of the header, lines up with chars
|
||||
var/header = "" //The actual header in text
|
||||
var/contents = "" //The contents in text (bit at the end)
|
||||
var/index = 1
|
||||
for(var/x in 1 to width)
|
||||
contents += "\n([x],1,1) = {\"\n"
|
||||
for(var/y in height to 1 step -1)
|
||||
//====Get turfs Data====
|
||||
var/turf/place = sortedmap[x][y]
|
||||
var/area/location
|
||||
var/list/objects
|
||||
//If there is nothing there, save as a noop (For odd shapes)
|
||||
if(!place)
|
||||
place = /turf/template_noop
|
||||
location = /area/template_noop
|
||||
objects = list()
|
||||
//Ignore things in space, must be a space turf and the area has to be empty space
|
||||
else if(istype(place, /turf/open/space) && istype(get_area(place), /area/space) && !(save_flag & SAVE_SPACE))
|
||||
place = /turf/template_noop
|
||||
location = /area/template_noop
|
||||
//Stuff to add
|
||||
else
|
||||
var/area/location_type = get_area(place)
|
||||
location = location_type.type
|
||||
objects = place
|
||||
place = place.type
|
||||
//====Saving shuttles only / non shuttles only====
|
||||
var/is_shuttle_area = istype(location, /area/shuttle)
|
||||
if((is_shuttle_area && shuttle_area_flag == SAVE_SHUTTLEAREA_IGNORE) || (!is_shuttle_area && shuttle_area_flag == SAVE_SHUTTLEAREA_ONLY))
|
||||
place = /turf/template_noop
|
||||
location = /area/template_noop
|
||||
objects = list()
|
||||
//====For toggling not saving areas and turfs====
|
||||
if(!(save_flag & SAVE_AREAS))
|
||||
location = /area/template_noop
|
||||
if(!(save_flag & SAVE_TURFS))
|
||||
place = /turf/template_noop
|
||||
//====Generate Header Character====
|
||||
var/header_char = calculate_tgm_header_index(index, layers) //The characters of the header
|
||||
var/current_header = "(\n" //The actual stuff inside the header
|
||||
//Add objects to the header file
|
||||
var/empty = TRUE
|
||||
//====SAVING OBJECTS====
|
||||
if(save_flag & SAVE_OBJECTS)
|
||||
for(var/obj/thing in objects)
|
||||
if(thing.type in obj_blacklist)
|
||||
continue
|
||||
var/metadata = generate_tgm_metadata(thing, vars_to_save)
|
||||
current_header += "[empty?"":",\n"][thing.type][metadata]"
|
||||
empty = FALSE
|
||||
//====SAVING SPECIAL DATA====
|
||||
//This is what causes lockers and machines to save stuff inside of them
|
||||
if(save_flag & SAVE_OBJECT_PROPERTIES)
|
||||
var/custom_data = thing.on_object_saved()
|
||||
current_header += "[custom_data ? ",\n[custom_data]" : ""]"
|
||||
//====SAVING MOBS====
|
||||
if(save_flag & SAVE_MOBS)
|
||||
for(var/mob/living/thing in objects)
|
||||
if(istype(thing, /mob/living/carbon)) //Ignore people, but not animals
|
||||
continue
|
||||
var/metadata = generate_tgm_metadata(thing, vars_to_save)
|
||||
current_header += "[empty?"":",\n"][thing.type][metadata]"
|
||||
empty = FALSE
|
||||
current_header += "[empty?"":",\n"][place],\n[location])\n"
|
||||
//====Fill the contents file====
|
||||
//Compression is done here
|
||||
var/position_of_header = header_dat.Find(current_header)
|
||||
if(position_of_header)
|
||||
//If the header has already been saved, change the character to the other saved header
|
||||
header_char = header_chars[position_of_header]
|
||||
else
|
||||
header += "\"[header_char]\" = [current_header]"
|
||||
header_chars += header_char
|
||||
header_dat += current_header
|
||||
index ++
|
||||
contents += "[header_char]\n"
|
||||
contents += "\"}"
|
||||
return "[header][contents]"
|
||||
|
||||
//Sorts maps in terms of their positions, so scrambled / odd shaped maps can be saved
|
||||
/proc/sort_map(list/map, minx, miny, maxx, maxy)
|
||||
var/width = maxx - minx + 1
|
||||
var/height = maxy - miny + 1
|
||||
var/allTurfs = new/list(width, height)
|
||||
for(var/turf/place in map)
|
||||
allTurfs[place.x - minx + 1][place.y - miny + 1] = place
|
||||
return allTurfs
|
||||
|
||||
//vars_to_save = list() to save all vars
|
||||
/proc/generate_tgm_metadata(atom/O, list/vars_to_save = list("pixel_x", "pixel_y", "dir", "name", "req_access", "req_access_txt", "piping_layer", "color", "icon_state", "pipe_color", "amount"))
|
||||
var/dat = ""
|
||||
var/data_to_add = list()
|
||||
for(var/V in O.vars)
|
||||
if(O.get_save_vars())
|
||||
if(!(V in O.get_save_vars()))
|
||||
continue
|
||||
else
|
||||
if(!(V in vars_to_save) && vars_to_save)
|
||||
continue
|
||||
var/value = O.vars[V]
|
||||
if(!value)
|
||||
continue
|
||||
if(value == initial(O.vars[V]) || !issaved(O.vars[V]))
|
||||
continue
|
||||
var/symbol = ""
|
||||
if(istext(value))
|
||||
symbol = "\""
|
||||
value = sanitize_simple(value, list("{"="", "}"="", "\""="", ";"="", ","=""))
|
||||
else if(isicon(value) || isfile(value))
|
||||
symbol = "'"
|
||||
else if(!(isnum(value) || ispath(value)))
|
||||
continue
|
||||
//Prevent symbols from being because otherwise you can name something [";},/obj/item/gun/energy/laser/instakill{name="da epic gun] and spawn yourself an instakill gun.
|
||||
data_to_add += "[V] = [symbol][value][symbol]"
|
||||
//Process data to add
|
||||
var/first = TRUE
|
||||
for(var/data in data_to_add)
|
||||
dat += "[first ? "" : ";\n"]\t[data]"
|
||||
first = FALSE
|
||||
if(dat)
|
||||
dat = "{\n[dat]\n\t}"
|
||||
return dat
|
||||
|
||||
/proc/calculate_tgm_header_index(index, layers)
|
||||
var/output = ""
|
||||
for(var/i in 1 to layers)
|
||||
var/l = GLOB.save_file_chars.len
|
||||
var/c = FLOOR((index-1) / (l ** (i - 1)), 1)
|
||||
c = (c % l) + 1
|
||||
output = "[GLOB.save_file_chars[c]][output]"
|
||||
return output
|
||||
@@ -190,6 +190,10 @@
|
||||
icon = 'icons/obj/lavaland/survival_pod.dmi'
|
||||
icon_state = "bed"
|
||||
|
||||
/obj/structure/bed/double/pod
|
||||
icon = 'icons/obj/lavaland/survival_pod.dmi'
|
||||
icon_state = "bed_double"
|
||||
|
||||
//Survival Storage Unit
|
||||
/obj/machinery/smartfridge/survival_pod
|
||||
name = "survival pod storage"
|
||||
|
||||
@@ -60,83 +60,86 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons)
|
||||
return
|
||||
if(A.anchored || (A.move_resist > max_force_fulton))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start attaching the pack to [A]...</span>")
|
||||
if(do_after(user,50,target=A))
|
||||
to_chat(user, "<span class='notice'>You attach the pack to [A] and activate it.</span>")
|
||||
if(loc == user && istype(user.back, /obj/item/storage/backpack))
|
||||
var/obj/item/storage/backpack/B = user.back
|
||||
SEND_SIGNAL(B, COMSIG_TRY_STORAGE_INSERT, src, user, FALSE, FALSE)
|
||||
uses_left--
|
||||
if(uses_left <= 0)
|
||||
user.transferItemToLoc(src, A, TRUE)
|
||||
var/mutable_appearance/balloon
|
||||
var/mutable_appearance/balloon2
|
||||
var/mutable_appearance/balloon3
|
||||
if(isliving(A))
|
||||
var/mob/living/M = A
|
||||
M.DefaultCombatKnockdown(320) // Keep them from moving during the duration of the extraction
|
||||
M.buckled = 0 // Unbuckle them to prevent anchoring problems
|
||||
else
|
||||
A.anchored = TRUE
|
||||
A.density = FALSE
|
||||
var/obj/effect/extraction_holder/holder_obj = new(A.loc)
|
||||
holder_obj.appearance = A.appearance
|
||||
A.forceMove(holder_obj)
|
||||
balloon2 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_expand")
|
||||
balloon2.pixel_y = 10
|
||||
balloon2.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
|
||||
holder_obj.add_overlay(balloon2)
|
||||
sleep(4)
|
||||
balloon = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_balloon")
|
||||
balloon.pixel_y = 10
|
||||
balloon.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
|
||||
holder_obj.cut_overlay(balloon2)
|
||||
holder_obj.add_overlay(balloon)
|
||||
playsound(holder_obj.loc, 'sound/items/fulext_deploy.wav', 50, 1, -3)
|
||||
animate(holder_obj, pixel_z = 10, time = 20)
|
||||
sleep(20)
|
||||
animate(holder_obj, pixel_z = 15, time = 10)
|
||||
sleep(10)
|
||||
animate(holder_obj, pixel_z = 10, time = 10)
|
||||
sleep(10)
|
||||
animate(holder_obj, pixel_z = 15, time = 10)
|
||||
sleep(10)
|
||||
animate(holder_obj, pixel_z = 10, time = 10)
|
||||
sleep(10)
|
||||
playsound(holder_obj.loc, 'sound/items/fultext_launch.wav', 50, 1, -3)
|
||||
animate(holder_obj, pixel_z = 1000, time = 30)
|
||||
if(ishuman(A))
|
||||
var/mob/living/carbon/human/L = A
|
||||
L.SetUnconscious(0)
|
||||
L.drowsyness = 0
|
||||
L.SetSleeping(0)
|
||||
sleep(30)
|
||||
var/list/flooring_near_beacon = list()
|
||||
for(var/turf/open/floor in orange(1, beacon))
|
||||
flooring_near_beacon += floor
|
||||
holder_obj.forceMove(pick(flooring_near_beacon))
|
||||
animate(holder_obj, pixel_z = 10, time = 50)
|
||||
sleep(50)
|
||||
animate(holder_obj, pixel_z = 15, time = 10)
|
||||
sleep(10)
|
||||
animate(holder_obj, pixel_z = 10, time = 10)
|
||||
sleep(10)
|
||||
balloon3 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_retract")
|
||||
balloon3.pixel_y = 10
|
||||
balloon3.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
|
||||
holder_obj.cut_overlay(balloon)
|
||||
holder_obj.add_overlay(balloon3)
|
||||
sleep(4)
|
||||
holder_obj.cut_overlay(balloon3)
|
||||
A.anchored = FALSE // An item has to be unanchored to be extracted in the first place.
|
||||
A.density = initial(A.density)
|
||||
animate(holder_obj, pixel_z = 0, time = 5)
|
||||
sleep(5)
|
||||
A.forceMove(holder_obj.loc)
|
||||
qdel(holder_obj)
|
||||
if(uses_left <= 0)
|
||||
qdel(src)
|
||||
attach_fulton(A, user, flag, params)
|
||||
|
||||
/obj/item/extraction_pack/proc/attach_fulton(atom/movable/A, mob/living/carbon/human/user, flag, params)
|
||||
set waitfor = FALSE
|
||||
to_chat(user, "<span class='notice'>You start attaching the pack to [A]...</span>")
|
||||
if(do_after(user,50,target=A))
|
||||
to_chat(user, "<span class='notice'>You attach the pack to [A] and activate it.</span>")
|
||||
if(loc == user && istype(user.back, /obj/item/storage/backpack))
|
||||
var/obj/item/storage/backpack/B = user.back
|
||||
SEND_SIGNAL(B, COMSIG_TRY_STORAGE_INSERT, src, user, FALSE, FALSE)
|
||||
uses_left--
|
||||
if(uses_left <= 0)
|
||||
user.transferItemToLoc(src, A, TRUE)
|
||||
var/mutable_appearance/balloon
|
||||
var/mutable_appearance/balloon2
|
||||
var/mutable_appearance/balloon3
|
||||
if(isliving(A))
|
||||
var/mob/living/M = A
|
||||
M.DefaultCombatKnockdown(320) // Keep them from moving during the duration of the extraction
|
||||
M.buckled = 0 // Unbuckle them to prevent anchoring problems
|
||||
else
|
||||
A.anchored = TRUE
|
||||
A.density = FALSE
|
||||
var/obj/effect/extraction_holder/holder_obj = new(A.loc)
|
||||
holder_obj.appearance = A.appearance
|
||||
A.forceMove(holder_obj)
|
||||
balloon2 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_expand")
|
||||
balloon2.pixel_y = 10
|
||||
balloon2.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
|
||||
holder_obj.add_overlay(balloon2)
|
||||
sleep(4)
|
||||
balloon = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_balloon")
|
||||
balloon.pixel_y = 10
|
||||
balloon.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
|
||||
holder_obj.cut_overlay(balloon2)
|
||||
holder_obj.add_overlay(balloon)
|
||||
playsound(holder_obj.loc, 'sound/items/fulext_deploy.wav', 50, 1, -3)
|
||||
animate(holder_obj, pixel_z = 10, time = 20)
|
||||
sleep(20)
|
||||
animate(holder_obj, pixel_z = 15, time = 10)
|
||||
sleep(10)
|
||||
animate(holder_obj, pixel_z = 10, time = 10)
|
||||
sleep(10)
|
||||
animate(holder_obj, pixel_z = 15, time = 10)
|
||||
sleep(10)
|
||||
animate(holder_obj, pixel_z = 10, time = 10)
|
||||
sleep(10)
|
||||
playsound(holder_obj.loc, 'sound/items/fultext_launch.wav', 50, 1, -3)
|
||||
animate(holder_obj, pixel_z = 1000, time = 30)
|
||||
if(ishuman(A))
|
||||
var/mob/living/carbon/human/L = A
|
||||
L.SetUnconscious(0)
|
||||
L.drowsyness = 0
|
||||
L.SetSleeping(0)
|
||||
sleep(30)
|
||||
var/list/flooring_near_beacon = list()
|
||||
for(var/turf/open/floor in orange(1, beacon))
|
||||
flooring_near_beacon += floor
|
||||
holder_obj.forceMove(pick(flooring_near_beacon))
|
||||
animate(holder_obj, pixel_z = 10, time = 50)
|
||||
sleep(50)
|
||||
animate(holder_obj, pixel_z = 15, time = 10)
|
||||
sleep(10)
|
||||
animate(holder_obj, pixel_z = 10, time = 10)
|
||||
sleep(10)
|
||||
balloon3 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_retract")
|
||||
balloon3.pixel_y = 10
|
||||
balloon3.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
|
||||
holder_obj.cut_overlay(balloon)
|
||||
holder_obj.add_overlay(balloon3)
|
||||
sleep(4)
|
||||
holder_obj.cut_overlay(balloon3)
|
||||
A.anchored = FALSE // An item has to be unanchored to be extracted in the first place.
|
||||
A.density = initial(A.density)
|
||||
animate(holder_obj, pixel_z = 0, time = 5)
|
||||
sleep(5)
|
||||
A.forceMove(holder_obj.loc)
|
||||
qdel(holder_obj)
|
||||
if(uses_left <= 0)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/fulton_core
|
||||
name = "extraction beacon signaller"
|
||||
|
||||
@@ -243,3 +243,17 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
|
||||
sep = ", "
|
||||
msg += "[amount < 0 ? "-" : "+"][val] [M.name]"
|
||||
formatted = msg.Join()
|
||||
|
||||
/obj/machinery/ore_silo/on_object_saved(var/depth = 0)
|
||||
if(depth >= 10)
|
||||
return ""
|
||||
var/dat
|
||||
var/datum/component/material_container/material_holder = GetComponent(/datum/component/material_container)
|
||||
for(var/each in material_holder.materials)
|
||||
var/amount = material_holder.materials[each] / MINERAL_MATERIAL_AMOUNT
|
||||
var/datum/material/material_datum = each
|
||||
while(amount > 0)
|
||||
var/amount_in_stack = max(1, min(50, amount))
|
||||
amount -= amount_in_stack
|
||||
dat += "[dat ? ",\n" : ""][material_datum.sheet_type]{\n\tamount = [amount_in_stack]\n\t}"
|
||||
return dat
|
||||
|
||||
@@ -2193,9 +2193,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.throw_alert("tempfeel", /atom/movable/screen/alert/cold, 2)
|
||||
if(-35 to -20)
|
||||
H.throw_alert("tempfeel", /atom/movable/screen/alert/cold, 1)
|
||||
if(-20 to 0) //This is the sweet spot where air is considered normal
|
||||
if(-20 to 1) //This is the sweet spot where air is considered normal
|
||||
H.clear_alert("tempfeel")
|
||||
if(0 to 15) //When the air around you matches your body's temperature, you'll start to feel warm.
|
||||
if(1 to 15) //When the air around you matches your body's temperature, you'll start to feel warm.
|
||||
H.throw_alert("tempfeel", /atom/movable/screen/alert/hot, 1)
|
||||
if(15 to 30)
|
||||
H.throw_alert("tempfeel", /atom/movable/screen/alert/hot, 2)
|
||||
|
||||
@@ -48,3 +48,4 @@
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
|
||||
allowed_limb_ids = list("mammal","aquatic","avian", "human")
|
||||
species_category = "robot"
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
//Procs called while dead
|
||||
/mob/living/carbon/proc/handle_death()
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
if(R.chemical_flags & REAGENT_DEAD_PROCESS)
|
||||
if(R.chemical_flags & REAGENT_DEAD_PROCESS && !is_reagent_processing_invalid(R, src))
|
||||
R.on_mob_dead(src)
|
||||
|
||||
///////////////
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
if(IS_STAMCRIT(src))
|
||||
to_chat(src, "<span class='warning'>You're too exhausted to crawl [(CHECK_MOBILITY(L, MOBILITY_STAND)) ? "under": "over"] [L].</span>")
|
||||
return TRUE
|
||||
combat_flags &= COMBAT_FLAG_ATTEMPTING_CRAWL
|
||||
combat_flags |= COMBAT_FLAG_ATTEMPTING_CRAWL
|
||||
visible_message("<span class='notice'>[src] is attempting to crawl [(CHECK_MOBILITY(L, MOBILITY_STAND)) ? "under" : "over"] [L].</span>",
|
||||
"<span class='notice'>You are now attempting to crawl [(CHECK_MOBILITY(L, MOBILITY_STAND)) ? "under": "over"] [L].</span>",
|
||||
target = L, target_message = "<span class='notice'>[src] is attempting to crawl [(CHECK_MOBILITY(L, MOBILITY_STAND)) ? "under" : "over"] you.</span>")
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
if(ismob(mover))
|
||||
if(mover in buckled_mobs)
|
||||
return TRUE
|
||||
if(HAS_TRAIT(mover, TRAIT_BEING_CARRIED))
|
||||
return TRUE //We're being carried and our carrier managed to pass, ergo, let us pass aswell.
|
||||
var/mob/living/L = mover //typecast first, check isliving and only check this if living using short circuit
|
||||
if(isliving(L) && lying && L.lying) //if we're both lying down and aren't already being thrown/shipped around, don't pass
|
||||
return FALSE
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
/datum/movespeed_modifier/hunger
|
||||
variable = TRUE
|
||||
blacklisted_movetypes = FLOATING|FLYING
|
||||
|
||||
/datum/movespeed_modifier/slaughter
|
||||
multiplicative_slowdown = -1
|
||||
|
||||
@@ -148,6 +148,10 @@
|
||||
/obj/item/pen/afterattack(obj/O, mob/living/user, proximity)
|
||||
. = ..()
|
||||
//Changing name/description of items. Only works if they have the UNIQUE_RENAME object flag set
|
||||
try_modify_object(O, user, proximity)
|
||||
|
||||
/obj/item/pen/proc/try_modify_object(obj/O, mob/living/user, proximity)
|
||||
set waitfor = FALSE
|
||||
if(isobj(O) && proximity && (O.obj_flags & UNIQUE_RENAME))
|
||||
var/penchoice = input(user, "What would you like to edit?", "Rename, change description or reset both?") as null|anything in list("Rename","Change description","Reset")
|
||||
if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE))
|
||||
|
||||
@@ -235,10 +235,10 @@
|
||||
if(POOL_SCALDING) //Scalding
|
||||
M.adjust_bodytemperature(50,0,500)
|
||||
if(POOL_WARM) //Warm
|
||||
M.adjust_bodytemperature(20,0,360) //Heats up mobs till the thermometer shows up
|
||||
M.adjust_bodytemperature(20,0,323.15) //Heats up mobs till the thermometer shows up
|
||||
//Normal temp does nothing, because it's just room temperature water.
|
||||
if(POOL_COOL)
|
||||
M.adjust_bodytemperature(-20,250) //Cools mobs till the thermometer shows up
|
||||
M.adjust_bodytemperature(-20,274.15) //Cools mobs till the thermometer shows up
|
||||
if(POOL_FRIGID) //Freezing
|
||||
M.adjust_bodytemperature(-60) //cool mob at -35k per cycle, less would not affect the mob enough.
|
||||
if(M.bodytemperature <= 50 && !M.stat)
|
||||
|
||||
+158
-36
@@ -1,5 +1,6 @@
|
||||
|
||||
#define DUALWIELD_PENALTY_EXTRA_MULTIPLIER 1.4
|
||||
#define FIRING_PIN_REMOVAL_DELAY 50
|
||||
|
||||
/obj/item/gun
|
||||
name = "gun"
|
||||
@@ -63,7 +64,7 @@
|
||||
var/obj/item/firing_pin/pin = /obj/item/firing_pin //standard firing pin for most guns
|
||||
var/no_pin_required = FALSE //whether the gun can be fired without a pin
|
||||
|
||||
var/obj/item/flashlight/gun_light
|
||||
var/obj/item/flashlight/seclite/gun_light
|
||||
var/can_flashlight = FALSE
|
||||
var/gunlight_state = "flight"
|
||||
var/obj/item/kitchen/knife/bayonet
|
||||
@@ -115,23 +116,28 @@
|
||||
QDEL_NULL(chambered)
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/CheckParts(list/parts_list)
|
||||
..()
|
||||
var/obj/item/gun/G = locate(/obj/item/gun) in contents
|
||||
if(G)
|
||||
G.forceMove(loc)
|
||||
QDEL_NULL(G.pin)
|
||||
visible_message("[G] can now fit a new pin, but the old one was destroyed in the process.", null, null, 3)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/gun/examine(mob/user)
|
||||
. = ..()
|
||||
if(no_pin_required)
|
||||
return
|
||||
if(pin)
|
||||
. += "It has \a [pin] installed."
|
||||
else
|
||||
. += "It doesn't have a firing pin installed, and won't fire."
|
||||
if(!no_pin_required)
|
||||
if(pin)
|
||||
. += "It has \a [pin] installed."
|
||||
. += "<span class='info'>[pin] looks like it could be removed with some <b>tools</b>.</span>"
|
||||
else
|
||||
. += "It doesn't have a firing pin installed, and won't fire."
|
||||
|
||||
if(gun_light)
|
||||
. += "It has \a [gun_light] [can_flashlight ? "" : "permanently "]mounted on it."
|
||||
if(can_flashlight) //if it has a light and this is false, the light is permanent.
|
||||
. += "<span class='info'>[gun_light] looks like it can be <b>unscrewed</b> from [src].</span>"
|
||||
else if(can_flashlight)
|
||||
. += "It has a mounting point for a <b>seclite</b>."
|
||||
|
||||
if(bayonet)
|
||||
. += "It has \a [bayonet] [can_bayonet ? "" : "permanently "]affixed to it."
|
||||
if(can_bayonet) //if it has a bayonet and this is false, the bayonet is permanent.
|
||||
. += "<span class='info'>[bayonet] looks like it can be <b>unscrewed</b> from [src].</span>"
|
||||
else if(can_bayonet)
|
||||
. += "It has a <b>bayonet</b> lug on it."
|
||||
|
||||
/obj/item/gun/equipped(mob/living/user, slot)
|
||||
. = ..()
|
||||
@@ -239,7 +245,7 @@
|
||||
return
|
||||
|
||||
if(weapon_weight == WEAPON_HEAVY && user.get_inactive_held_item())
|
||||
to_chat(user, "<span class='userdanger'>You need both hands free to fire \the [src]!</span>")
|
||||
to_chat(user, "<span class='userdanger'>You need both hands free to fire [src]!</span>")
|
||||
return
|
||||
|
||||
user.DelayNextAction()
|
||||
@@ -417,12 +423,12 @@
|
||||
if(!gun_light)
|
||||
if(!user.transferItemToLoc(I, src))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You click \the [S] into place on \the [src].</span>")
|
||||
to_chat(user, "<span class='notice'>You click [S] into place on [src].</span>")
|
||||
if(S.on)
|
||||
set_light(0)
|
||||
gun_light = S
|
||||
set_gun_light(S)
|
||||
update_gunlight(user)
|
||||
alight = new /datum/action/item_action/toggle_gunlight(src)
|
||||
alight = new(src)
|
||||
if(loc == user)
|
||||
alight.Grant(user)
|
||||
else if(istype(I, /obj/item/kitchen/knife))
|
||||
@@ -431,27 +437,133 @@
|
||||
return ..()
|
||||
if(!user.transferItemToLoc(I, src))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You attach \the [K] to the front of \the [src].</span>")
|
||||
to_chat(user, "<span class='notice'>You attach [K] to [src]'s bayonet lug.</span>")
|
||||
bayonet = K
|
||||
update_icon()
|
||||
else if(I.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
if(gun_light)
|
||||
var/obj/item/flashlight/seclite/S = gun_light
|
||||
to_chat(user, "<span class='notice'>You unscrew the seclite from \the [src].</span>")
|
||||
gun_light = null
|
||||
S.forceMove(get_turf(user))
|
||||
update_gunlight(user)
|
||||
S.update_brightness(user)
|
||||
QDEL_NULL(alight)
|
||||
if(bayonet)
|
||||
to_chat(user, "<span class='notice'>You unscrew the bayonet from \the [src].</span>")
|
||||
var/obj/item/kitchen/knife/K = bayonet
|
||||
K.forceMove(get_turf(user))
|
||||
bayonet = null
|
||||
update_icon()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/screwdriver_act(mob/living/user, obj/item/I)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
if((can_flashlight && gun_light) && (can_bayonet && bayonet)) //give them a choice instead of removing both
|
||||
var/list/possible_items = list(gun_light, bayonet)
|
||||
var/obj/item/item_to_remove = input(user, "Select an attachment to remove", "Attachment Removal") as null|obj in possible_items
|
||||
if(!item_to_remove || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
return remove_gun_attachment(user, I, item_to_remove)
|
||||
|
||||
else if(gun_light && can_flashlight) //if it has a gun_light and can_flashlight is false, the flashlight is permanently attached.
|
||||
return remove_gun_attachment(user, I, gun_light, "unscrewed")
|
||||
|
||||
else if(bayonet && can_bayonet) //if it has a bayonet, and the bayonet can be removed
|
||||
return remove_gun_attachment(user, I, bayonet, "unfix")
|
||||
|
||||
else if(pin && user.is_holding(src))
|
||||
user.visible_message(span_warning("[user] attempts to remove [pin] from [src] with [I]."),
|
||||
span_notice("You attempt to remove [pin] from [src]. (It will take [DisplayTimeText(FIRING_PIN_REMOVAL_DELAY)].)"), null, 3)
|
||||
if(I.use_tool(src, user, FIRING_PIN_REMOVAL_DELAY, volume = 50))
|
||||
if(!pin) //check to see if the pin is still there, or we can spam messages by clicking multiple times during the tool delay
|
||||
return
|
||||
user.visible_message(span_notice("[pin] is pried out of [src] by [user], destroying the pin in the process."),
|
||||
span_warning("You pry [pin] out with [I], destroying the pin in the process."), null, 3)
|
||||
QDEL_NULL(pin)
|
||||
return TRUE
|
||||
|
||||
/obj/item/gun/welder_act(mob/living/user, obj/item/I)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
if(pin && user.is_holding(src))
|
||||
user.visible_message(span_warning("[user] attempts to remove [pin] from [src] with [I]."),
|
||||
span_notice("You attempt to remove [pin] from [src]. (It will take [DisplayTimeText(FIRING_PIN_REMOVAL_DELAY)].)"), null, 3)
|
||||
if(I.use_tool(src, user, FIRING_PIN_REMOVAL_DELAY, 5, volume = 50))
|
||||
if(!pin) //check to see if the pin is still there, or we can spam messages by clicking multiple times during the tool delay
|
||||
return
|
||||
user.visible_message(span_notice("[pin] is spliced out of [src] by [user], melting part of the pin in the process."),
|
||||
span_warning("You splice [pin] out of [src] with [I], melting part of the pin in the process."), null, 3)
|
||||
QDEL_NULL(pin)
|
||||
return TRUE
|
||||
|
||||
/obj/item/gun/wirecutter_act(mob/living/user, obj/item/I)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
|
||||
return
|
||||
if(pin && user.is_holding(src))
|
||||
user.visible_message(span_warning("[user] attempts to remove [pin] from [src] with [I]."),
|
||||
span_notice("You attempt to remove [pin] from [src]. (It will take [DisplayTimeText(FIRING_PIN_REMOVAL_DELAY)].)"), null, 3)
|
||||
if(I.use_tool(src, user, FIRING_PIN_REMOVAL_DELAY, volume = 50))
|
||||
if(!pin) //check to see if the pin is still there, or we can spam messages by clicking multiple times during the tool delay
|
||||
return
|
||||
user.visible_message(span_notice("[pin] is ripped out of [src] by [user], mangling the pin in the process."),
|
||||
span_warning("You rip [pin] out of [src] with [I], mangling the pin in the process."), null, 3)
|
||||
QDEL_NULL(pin)
|
||||
return TRUE
|
||||
|
||||
/obj/item/gun/proc/remove_gun_attachment(mob/living/user, obj/item/tool_item, obj/item/item_to_remove, removal_verb)
|
||||
if(tool_item)
|
||||
tool_item.play_tool_sound(src)
|
||||
to_chat(user, span_notice("You [removal_verb ? removal_verb : "remove"] [item_to_remove] from [src]."))
|
||||
item_to_remove.forceMove(drop_location())
|
||||
|
||||
if(Adjacent(user) && !issilicon(user))
|
||||
user.put_in_hands(item_to_remove)
|
||||
|
||||
if(item_to_remove == bayonet)
|
||||
return clear_bayonet()
|
||||
else if(item_to_remove == gun_light)
|
||||
return clear_gunlight()
|
||||
|
||||
/obj/item/gun/proc/clear_bayonet()
|
||||
if(!bayonet)
|
||||
return
|
||||
bayonet = null
|
||||
update_appearance()
|
||||
return TRUE
|
||||
|
||||
/obj/item/gun/proc/clear_gunlight()
|
||||
if(!gun_light)
|
||||
return
|
||||
var/obj/item/flashlight/seclite/removed_light = gun_light
|
||||
set_gun_light(null)
|
||||
update_gunlight()
|
||||
removed_light.update_brightness()
|
||||
QDEL_NULL(alight)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Swaps the gun's seclight, dropping the old seclight if it has not been qdel'd.
|
||||
*
|
||||
* Returns the former gun_light that has now been replaced by this proc.
|
||||
* Arguments:
|
||||
* * new_light - The new light to attach to the weapon. Can be null, which will mean the old light is removed with no replacement.
|
||||
*/
|
||||
/obj/item/gun/proc/set_gun_light(obj/item/flashlight/seclite/new_light)
|
||||
// Doesn't look like this should ever happen? We're replacing our old light with our old light?
|
||||
if(gun_light == new_light)
|
||||
CRASH("Tried to set a new gun light when the old gun light was also the new gun light.")
|
||||
|
||||
. = gun_light
|
||||
|
||||
// If there's an old gun light that isn't being QDELETED, detatch and drop it to the floor.
|
||||
if(!QDELETED(gun_light))
|
||||
if(gun_light.loc == src)
|
||||
gun_light.forceMove(get_turf(src))
|
||||
|
||||
// If there's a new gun light to be added, attach and move it to the gun.
|
||||
if(new_light)
|
||||
if(new_light.loc != src)
|
||||
new_light.forceMove(src)
|
||||
|
||||
gun_light = new_light
|
||||
|
||||
/obj/item/gun/ui_action_click(mob/user, action)
|
||||
if(istype(action, /datum/action/item_action/toggle_scope_zoom))
|
||||
zoom(user, user.dir)
|
||||
@@ -606,9 +718,16 @@
|
||||
user.client.view_size.zoomIn()
|
||||
|
||||
/obj/item/gun/handle_atom_del(atom/A)
|
||||
if(A == pin)
|
||||
pin = null
|
||||
if(A == chambered)
|
||||
chambered = null
|
||||
update_icon()
|
||||
if(A == bayonet)
|
||||
clear_bayonet()
|
||||
if(A == gun_light)
|
||||
clear_gunlight()
|
||||
return ..()
|
||||
|
||||
/obj/item/gun/proc/getinaccuracy(mob/living/user, bonus_spread, stamloss)
|
||||
return 0 // Replacement TBD: Exponential curved aim instability system.
|
||||
@@ -642,3 +761,6 @@
|
||||
. = recoil
|
||||
if(user && !user.has_gravity())
|
||||
. = recoil*5
|
||||
|
||||
#undef FIRING_PIN_REMOVAL_DELAY
|
||||
#undef DUALWIELD_PENALTY_EXTRA_MULTIPLIER
|
||||
|
||||
@@ -215,7 +215,7 @@
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
hit_limb = L.check_limb_hit(def_zone)
|
||||
SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_ON_HIT, firer, target, Angle, hit_limb)
|
||||
SEND_SIGNAL(src, COMSIG_PROJECTILE_SELF_ON_HIT, firer, target, Angle, hit_limb, blocked)
|
||||
var/turf/target_loca = get_turf(target)
|
||||
|
||||
var/hitx
|
||||
|
||||
@@ -345,6 +345,8 @@
|
||||
if(owner && reagent)
|
||||
if(!owner.reagent_check(reagent, delta_time, times_fired) != TRUE)
|
||||
return
|
||||
if(is_reagent_processing_invalid(reagent, owner))
|
||||
return reagent.on_invalid_process(owner, delta_time, times_fired)
|
||||
if(liverless && !reagent.self_consuming) //need to be metabolized
|
||||
return
|
||||
if(!reagent.metabolizing)
|
||||
|
||||
@@ -398,14 +398,23 @@
|
||||
state = "Gas"
|
||||
var/const/P = 3 //The number of seconds between life ticks
|
||||
var/T = initial(R.metabolization_rate) * (60 / P)
|
||||
var/processtype
|
||||
if(CHECK_MULTIPLE_BITFIELDS(R.chemical_flags, (REAGENT_ROBOTIC_PROCESS | REAGENT_ORGANIC_PROCESS)))
|
||||
processtype = "Both robots and organics"
|
||||
else if(R.chemical_flags & REAGENT_ROBOTIC_PROCESS)
|
||||
processtype = "Robots only"
|
||||
else if(R.chemical_flags & REAGENT_ORGANIC_PROCESS)
|
||||
processtype = "Organics only"
|
||||
else
|
||||
processtype = "Noone?! (Report this to Nanotrasen's spacetime department immediately)"
|
||||
if(istype(R, /datum/reagent/fermi))
|
||||
fermianalyze = TRUE
|
||||
var/datum/chemical_reaction/Rcr = get_chemical_reaction(reagent)
|
||||
var/pHpeakCache = (Rcr.OptimalpHMin + Rcr.OptimalpHMax)/2
|
||||
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = R.purity, "inverseRatioF" = initial(R.inverse_chem_val), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
|
||||
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "processType" = processtype, "purityF" = R.purity, "inverseRatioF" = initial(R.inverse_chem_val), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
|
||||
else
|
||||
fermianalyze = FALSE
|
||||
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = R.purity)
|
||||
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "processType" = processtype, "purityF" = R.purity)
|
||||
screen = "analyze"
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
|
||||
var/inverse_chem_val = 0 // If the impurity is below 0.5, replace ALL of the chem with inverse_chemupon metabolising
|
||||
var/inverse_chem // What chem is metabolised when purity is below inverse_chem_val, this shouldn't be made, but if it does, well, I guess I'll know about it.
|
||||
var/metabolizing = FALSE
|
||||
var/chemical_flags // See fermi/readme.dm REAGENT_DEAD_PROCESS, REAGENT_DONOTSPLIT, REAGENT_ONLYINVERSE, REAGENT_ONMOBMERGE, REAGENT_INVISIBLE, REAGENT_FORCEONNEW, REAGENT_SNEAKYNAME
|
||||
var/chemical_flags = REAGENT_ORGANIC_PROCESS // See fermi/readme.dm REAGENT_DEAD_PROCESS, REAGENT_DONOTSPLIT, REAGENT_ONLYINVERSE, REAGENT_ONMOBMERGE, REAGENT_INVISIBLE, REAGENT_FORCEONNEW, REAGENT_SNEAKYNAME, REAGENT_ORGANIC_PROCESS, REAGENT_ROBOTIC_PROCESS
|
||||
var/value = REAGENT_VALUE_NONE //How much does it sell for in cargo?
|
||||
var/datum/material/material //are we made of material?
|
||||
|
||||
@@ -87,6 +87,11 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
|
||||
if(holder)
|
||||
holder.remove_reagent(type, metabolization_rate * M.metabolism_efficiency) //By default it slowly disappears.
|
||||
|
||||
//Called when an reagent is incompatible with its processing carbon (e.g. robot carbon and reagent with only organic processing)
|
||||
/datum/reagent/proc/on_invalid_process(mob/living/carbon/M)
|
||||
if(holder)
|
||||
holder.remove_reagent(type, INVALID_REAGENT_DISSIPATION) //Not influenced by normal metab rate nor efficiency.
|
||||
|
||||
//called when a mob processes chems when dead.
|
||||
/datum/reagent/proc/on_mob_dead(mob/living/carbon/M)
|
||||
if(!(chemical_flags & REAGENT_DEAD_PROCESS)) //justincase
|
||||
|
||||
@@ -41,10 +41,6 @@ All effects don't start immediately, but rather get worse over time; the rate is
|
||||
if(!iscarbon(L))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/C = L
|
||||
if(HAS_TRAIT(C, TRAIT_ROBOTIC_ORGANISM))
|
||||
C.reagents.remove_reagent(type, amount, FALSE)
|
||||
|
||||
/datum/reagent/consumable/ethanol/on_mob_life(mob/living/carbon/C)
|
||||
if(HAS_TRAIT(C, TRAIT_TOXIC_ALCOHOL))
|
||||
C.adjustToxLoss((boozepwr/25)*REAGENTS_EFFECT_MULTIPLIER,forced = TRUE)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//Invert = Whole conversion
|
||||
|
||||
/datum/reagent/impure
|
||||
chemical_flags = REAGENT_INVISIBLE | REAGENT_SNEAKYNAME //by default, it will stay hidden on splitting, but take the name of the source on inverting
|
||||
chemical_flags = REAGENT_INVISIBLE | REAGENT_SNEAKYNAME | REAGENT_ORGANIC_PROCESS //by default, it will stay hidden on splitting, but take the name of the source on inverting
|
||||
|
||||
|
||||
/datum/reagent/impure/fermiTox
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
/datum/reagent/medicine/leporazine
|
||||
name = "Leporazine"
|
||||
description = "Leporazine will effectively regulate a patient's body temperature, ensuring it never leaves safe levels."
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
pH = 8.4
|
||||
color = "#82b8aa"
|
||||
value = REAGENT_VALUE_COMMON
|
||||
@@ -32,6 +33,7 @@
|
||||
name = "Adminordrazine"
|
||||
description = "It's magic. We don't have to explain it."
|
||||
color = "#ffffff"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
can_synth = FALSE
|
||||
taste_description = "badmins"
|
||||
value = REAGENT_VALUE_GLORIOUS
|
||||
@@ -103,6 +105,7 @@
|
||||
name = "Synaptizine"
|
||||
description = "Increases resistance to stuns as well as reducing drowsiness and hallucinations."
|
||||
color = "#FF00FF"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
pH = 4
|
||||
|
||||
/datum/reagent/medicine/synaptizine/on_mob_life(mob/living/carbon/M)
|
||||
@@ -121,6 +124,7 @@
|
||||
name = "Diphen-Synaptizine"
|
||||
description = "Reduces drowsiness, hallucinations, and Histamine from body."
|
||||
color = "#EC536D" // rgb: 236, 83, 109
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
pH = 5.2
|
||||
value = REAGENT_VALUE_COMMON
|
||||
|
||||
@@ -140,6 +144,7 @@
|
||||
name = "Inacusiate"
|
||||
description = "Instantly restores all hearing to the patient, but does not cure deafness."
|
||||
color = "#6600FF" // rgb: 100, 165, 255
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
pH = 2
|
||||
value = 10
|
||||
|
||||
@@ -152,6 +157,7 @@
|
||||
description = "A chemical mixture with almost magical healing powers. Its main limitation is that the patient's body temperature must be under 270K for it to metabolise correctly."
|
||||
color = "#0000C8"
|
||||
taste_description = "sludge"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
pH = 11
|
||||
value = REAGENT_VALUE_COMMON
|
||||
|
||||
@@ -183,6 +189,7 @@
|
||||
color = "#0000C8"
|
||||
taste_description = "muscle"
|
||||
metabolization_rate = 1.5 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
pH = 13
|
||||
value = REAGENT_VALUE_COMMON
|
||||
|
||||
@@ -199,6 +206,7 @@
|
||||
description = "A mixture of cryoxadone and slime jelly, that apparently inverses the requirement for its activation."
|
||||
color = "#f7832a"
|
||||
taste_description = "spicy jelly"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
pH = 12
|
||||
value = REAGENT_VALUE_UNCOMMON
|
||||
|
||||
@@ -232,6 +240,7 @@
|
||||
description = "A powder derived from fish toxin, Rezadone can effectively treat genetic damage as well as restoring minor wounds. Overdose will cause intense nausea and minor toxin damage."
|
||||
reagent_state = SOLID
|
||||
color = "#669900" // rgb: 102, 153, 0
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
overdose_threshold = 30
|
||||
taste_description = "fish"
|
||||
pH = 12.2
|
||||
@@ -265,6 +274,7 @@
|
||||
description = "Spaceacillin will prevent a patient from conventionally spreading any diseases they are currently infected with. Also reduces infection in serious burns."
|
||||
color = "#f2f2f2"
|
||||
metabolization_rate = 0.1 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
pH = 8.1
|
||||
|
||||
//Goon Chems. Ported mainly from Goonstation. Easily mixable (or not so easily) and provide a variety of effects.
|
||||
@@ -394,6 +404,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#DCDCDC"
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
overdose_threshold = 60
|
||||
taste_description = "sweetness and salt"
|
||||
var/extra_regen = 0.25 // in addition to acting as temporary blood, also add this much to their actual blood per tick
|
||||
@@ -527,6 +538,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#000000"
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
taste_description = "ash"
|
||||
pH = 5
|
||||
|
||||
@@ -578,6 +590,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#19C832"
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
taste_description = "acid"
|
||||
pH = 1.5
|
||||
|
||||
@@ -597,6 +610,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#14FF3C"
|
||||
metabolization_rate = 2 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
pH = 12 //It's a reducing agent
|
||||
|
||||
/datum/reagent/medicine/potass_iodide/on_mob_life(mob/living/carbon/M)
|
||||
@@ -610,6 +624,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#003153" // RGB 0, 49, 83
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
pH = 8.9
|
||||
value = REAGENT_VALUE_COMMON //uncraftable
|
||||
|
||||
@@ -624,6 +639,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#E6FFF0"
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
pH = 1 //One of the best buffers, NEVERMIND!
|
||||
value = REAGENT_VALUE_UNCOMMON
|
||||
var/healtoxinlover = FALSE
|
||||
@@ -677,6 +693,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#00FFFF"
|
||||
metabolization_rate = 0.25 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
pH = 2
|
||||
|
||||
/datum/reagent/medicine/salbutamol/on_mob_life(mob/living/carbon/M)
|
||||
@@ -693,6 +710,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#FF6464"
|
||||
metabolization_rate = 0.25 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
pH = 11
|
||||
|
||||
/datum/reagent/medicine/perfluorodecalin/on_mob_life(mob/living/carbon/human/M)
|
||||
@@ -871,6 +889,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#FFFFFF"
|
||||
metabolization_rate = 0.25 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
taste_description = "dull toxin"
|
||||
pH = 10
|
||||
|
||||
@@ -901,6 +920,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#000000"
|
||||
metabolization_rate = 0.25 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
overdose_threshold = 35
|
||||
pH = 12
|
||||
value = REAGENT_VALUE_UNCOMMON
|
||||
@@ -931,6 +951,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#D2FFFA"
|
||||
metabolization_rate = 0.25 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
overdose_threshold = 30
|
||||
pH = 10.2
|
||||
|
||||
@@ -966,6 +987,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#A0E85E"
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
taste_description = "magnets"
|
||||
pH = 0
|
||||
value = REAGENT_VALUE_RARE
|
||||
@@ -1031,6 +1053,7 @@
|
||||
description = "Efficiently restores brain damage."
|
||||
color = "#DCDCFF"
|
||||
pH = 10.4
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
|
||||
/datum/reagent/medicine/mannitol/on_mob_life(mob/living/carbon/C)
|
||||
C.adjustOrganLoss(ORGAN_SLOT_BRAIN, -2*REAGENTS_EFFECT_MULTIPLIER)
|
||||
@@ -1042,6 +1065,7 @@
|
||||
name = "Neurine"
|
||||
description = "Reacts with neural tissue, helping reform damaged connections. Can cure minor traumas."
|
||||
color = "#EEFF8F"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
|
||||
/datum/reagent/medicine/neurine/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
|
||||
if(!(method == INJECT))
|
||||
@@ -1071,6 +1095,7 @@
|
||||
color = "#5096C8"
|
||||
taste_description = "acid"
|
||||
pH = 2
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
|
||||
/datum/reagent/medicine/mutadone/on_mob_life(mob/living/carbon/M)
|
||||
M.jitteriness = 0
|
||||
@@ -1106,6 +1131,7 @@
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
overdose_threshold = 60
|
||||
pH = 8.7
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
value = REAGENT_VALUE_RARE
|
||||
|
||||
/datum/reagent/medicine/stimulants/on_mob_metabolize(mob/living/L)
|
||||
@@ -1144,6 +1170,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#FFFFF0"
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
pH = 6.7
|
||||
|
||||
/datum/reagent/medicine/insulin/on_mob_life(mob/living/carbon/M)
|
||||
@@ -1176,6 +1203,7 @@
|
||||
description = "Restores oxygen loss. Overdose causes it instead."
|
||||
reagent_state = LIQUID
|
||||
color = "#13d2f0"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
overdose_threshold = 30
|
||||
pH = 9.7
|
||||
|
||||
@@ -1239,6 +1267,7 @@
|
||||
reagent_state = LIQUID
|
||||
pH = 8.5
|
||||
color = "#5dc1f0"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
|
||||
/datum/reagent/medicine/inaprovaline/on_mob_life(mob/living/carbon/M)
|
||||
if(M.losebreath >= 5)
|
||||
@@ -1292,6 +1321,7 @@
|
||||
reagent_state = SOLID
|
||||
color = "#555555"
|
||||
pH = 11
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
value = REAGENT_VALUE_EXCEPTIONAL
|
||||
|
||||
/datum/reagent/medicine/syndicate_nanites/on_mob_life(mob/living/carbon/M)
|
||||
@@ -1313,6 +1343,7 @@
|
||||
reagent_state = SOLID
|
||||
color = "#555555"
|
||||
pH = 11
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
value = REAGENT_VALUE_VERY_RARE
|
||||
|
||||
/datum/reagent/medicine/lesser_syndicate_nanites/on_mob_life(mob/living/carbon/M)
|
||||
@@ -1447,6 +1478,7 @@
|
||||
color = "#C1151D"
|
||||
overdose_threshold = 30
|
||||
value = REAGENT_VALUE_VERY_RARE
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
|
||||
/datum/reagent/medicine/changelingadrenaline/on_mob_life(mob/living/carbon/metabolizer, delta_time, times_fired)
|
||||
..()
|
||||
@@ -1480,6 +1512,7 @@
|
||||
description = "Drastically increases movement speed."
|
||||
color = "#AE151D"
|
||||
metabolization_rate = 2.5 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
|
||||
/datum/reagent/medicine/changelinghaste/on_mob_metabolize(mob/living/L)
|
||||
..()
|
||||
@@ -1495,6 +1528,7 @@
|
||||
name = "Corazone"
|
||||
description = "A medication used to treat pain, fever, and inflammation, along with heart attacks."
|
||||
color = "#F5F5F5"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
self_consuming = TRUE
|
||||
pH = 12.5
|
||||
|
||||
@@ -1594,6 +1628,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#07E79E"
|
||||
metabolization_rate = 0.25 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
overdose_threshold = 30
|
||||
pH = 9.12
|
||||
value = REAGENT_VALUE_COMMON
|
||||
@@ -1629,6 +1664,7 @@
|
||||
reagent_state = SOLID
|
||||
color = "#FFFFD0"
|
||||
metabolization_rate = 1.5 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
value = REAGENT_VALUE_UNCOMMON
|
||||
|
||||
/datum/reagent/medicine/silibinin/on_mob_life(mob/living/carbon/M)
|
||||
@@ -1642,6 +1678,7 @@
|
||||
reagent_state = SOLID
|
||||
color = "#9423FF"
|
||||
metabolization_rate = 0.25 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
overdose_threshold = 50
|
||||
taste_description = "numbing bitterness"
|
||||
value = REAGENT_VALUE_RARE
|
||||
@@ -1671,6 +1708,7 @@
|
||||
taste_mult = 4
|
||||
can_synth = FALSE
|
||||
overdose_threshold = 30
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
value = REAGENT_VALUE_UNCOMMON // while it's 'rare', it can be milked from the wisdom cow
|
||||
|
||||
/datum/reagent/medicine/liquid_wisdom/on_mob_life(mob/living/carbon/C) //slightly stronger mannitol, from the wisdom cow
|
||||
@@ -1688,6 +1726,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#bb2424"
|
||||
metabolization_rate = 0.25 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
overdose_threshold = 20
|
||||
/// How much base clotting we do per bleeding wound, multiplied by the below number for each bleeding wound
|
||||
var/clot_rate = 0.25
|
||||
@@ -1742,18 +1781,21 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#D7C9C6"
|
||||
metabolization_rate = 0.2 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
overdose_threshold = 30
|
||||
|
||||
/datum/reagent/medicine/system_cleaner/on_mob_life(mob/living/carbon/M)
|
||||
. = ..()
|
||||
if(HAS_TRAIT(M, TRAIT_ROBOTIC_ORGANISM))
|
||||
M.adjustToxLoss(-0.2, toxins_type = TOX_SYSCORRUPT)
|
||||
M.adjustToxLoss(-0.4*REAGENTS_EFFECT_MULTIPLIER, toxins_type = TOX_SYSCORRUPT)
|
||||
else
|
||||
M.adjustToxLoss(0.5)
|
||||
M.adjustToxLoss(0.5*REAGENTS_EFFECT_MULTIPLIER)
|
||||
. = 1
|
||||
|
||||
/datum/reagent/medicine/system_cleaner/overdose_process(mob/living/carbon/M)
|
||||
. = ..()
|
||||
if(HAS_TRAIT(M, TRAIT_ROBOTIC_ORGANISM))
|
||||
M.adjustToxLoss(0.4, toxins_type = TOX_SYSCORRUPT) //inverts its positive effect on overdose, for organics it's just more toxic
|
||||
M.adjustToxLoss(0.8*REAGENTS_EFFECT_MULTIPLIER, toxins_type = TOX_SYSCORRUPT) //inverts its positive effect on overdose, for organics it's just more toxic
|
||||
else
|
||||
M.adjustToxLoss(0.5)
|
||||
M.adjustToxLoss(0.5*REAGENTS_EFFECT_MULTIPLIER)
|
||||
. = 1
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/reagent/blood
|
||||
data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"= null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null,"quirks"=null)
|
||||
name = "Blood"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
value = REAGENT_VALUE_UNCOMMON // $$$ blood ""donations"" $$$
|
||||
color = BLOOD_COLOR_HUMAN // rgb: 200, 0, 0
|
||||
description = "Blood from some creature."
|
||||
@@ -223,6 +224,7 @@
|
||||
/datum/reagent/vaccine
|
||||
//data must contain virus type
|
||||
name = "Vaccine"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
color = "#C81040" // rgb: 200, 16, 64
|
||||
taste_description = "slime"
|
||||
|
||||
@@ -243,6 +245,7 @@
|
||||
description = "An ubiquitous chemical substance that is composed of hydrogen and oxygen."
|
||||
color = "#AAAAAA77" // rgb: 170, 170, 170, 77 (alpha)
|
||||
taste_description = "water"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
overdose_threshold = 150 //Imagine drinking a gallon of water
|
||||
var/cooling_temperature = 2
|
||||
glass_icon_state = "glass_clear"
|
||||
@@ -339,6 +342,7 @@
|
||||
name = "Holy Water"
|
||||
description = "Water blessed by some deity."
|
||||
color = "#E0E8EF" // rgb: 224, 232, 239
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
glass_icon_state = "glass_clear"
|
||||
glass_name = "glass of holy water"
|
||||
glass_desc = "A glass of holy water."
|
||||
@@ -474,6 +478,7 @@
|
||||
name = "Hell Water"
|
||||
description = "YOUR FLESH! IT BURNS!"
|
||||
taste_description = "burning"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
value = REAGENT_VALUE_VERY_RARE
|
||||
|
||||
/datum/reagent/hellwater/on_mob_life(mob/living/carbon/M)
|
||||
@@ -533,6 +538,7 @@
|
||||
/datum/reagent/lube
|
||||
name = "Space Lube"
|
||||
description = "Lubricant is a substance introduced between two moving surfaces to reduce the friction and wear between them. giggity."
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
color = "#009CA8" // rgb: 0, 156, 168
|
||||
taste_description = "cherry" // by popular demand
|
||||
var/lube_kind = TURF_WET_LUBE ///What kind of slipperiness gets added to turfs.
|
||||
@@ -644,6 +650,7 @@
|
||||
description = "A humanizing toxin."
|
||||
color = "#5EFF3B" //RGB: 94, 255, 59
|
||||
metabolization_rate = INFINITY //So it instantly removes all of itself
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
taste_description = "slime"
|
||||
value = REAGENT_VALUE_RARE
|
||||
var/datum/species/race = /datum/species/human
|
||||
@@ -808,6 +815,7 @@
|
||||
/datum/reagent/slime_toxin
|
||||
name = "Slime Mutation Toxin"
|
||||
description = "A toxin that turns organic material into slime."
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
color = "#5EFF3B" //RGB: 94, 255, 59
|
||||
taste_description = "slime"
|
||||
metabolization_rate = 0.2
|
||||
@@ -847,6 +855,7 @@
|
||||
description = "This toxin will rapidly change the DNA of human beings. Commonly used by Syndicate spies and assassins in need of an emergency ID change."
|
||||
color = "#5EFF3B" //RGB: 94, 255, 59
|
||||
metabolization_rate = INFINITY
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
taste_description = "slime"
|
||||
value = REAGENT_VALUE_RARE
|
||||
|
||||
@@ -873,6 +882,7 @@
|
||||
name = "Gluttony's Blessing"
|
||||
description = "An advanced corruptive toxin produced by something terrible."
|
||||
color = "#5EFF3B" //RGB: 94, 255, 59
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
can_synth = FALSE
|
||||
taste_description = "decay"
|
||||
value = REAGENT_VALUE_GLORIOUS
|
||||
@@ -1086,6 +1096,7 @@
|
||||
/datum/reagent/radium
|
||||
name = "Radium"
|
||||
description = "Radium is an alkaline earth metal. It is extremely radioactive."
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
reagent_state = SOLID
|
||||
color = "#C7C7C7" // rgb: 199,199,199
|
||||
taste_description = "the colour blue and regret"
|
||||
@@ -1112,6 +1123,7 @@
|
||||
/datum/reagent/space_cleaner/sterilizine
|
||||
name = "Sterilizine"
|
||||
description = "Sterilizes wounds in preparation for surgery."
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
color = "#e6f1f5" // rgb: 200, 165, 220
|
||||
taste_description = "bitterness"
|
||||
pH = 10.5
|
||||
@@ -1138,6 +1150,7 @@
|
||||
reagent_state = SOLID
|
||||
taste_description = "iron"
|
||||
pH = 6
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
overdose_threshold = 30
|
||||
color = "#c2391d"
|
||||
material = /datum/material/iron
|
||||
@@ -1190,6 +1203,7 @@
|
||||
/datum/reagent/uranium
|
||||
name ="Uranium"
|
||||
description = "A silvery-white metallic chemical element in the actinide series, weakly radioactive."
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
reagent_state = SOLID
|
||||
color = "#B8B8C0" // rgb: 184, 184, 192
|
||||
taste_description = "the inside of a reactor"
|
||||
@@ -1219,6 +1233,7 @@
|
||||
/datum/reagent/bluespace
|
||||
name = "Bluespace Dust"
|
||||
description = "A dust composed of microscopic bluespace crystals, with minor space-warping properties."
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
reagent_state = SOLID
|
||||
color = "#0000CC"
|
||||
taste_description = "fizzling blue"
|
||||
@@ -1245,6 +1260,7 @@
|
||||
/datum/reagent/telecrystal
|
||||
name = "Telecrystal Dust"
|
||||
description = "A blood-red dust comprised of something that was much more useful when it was intact."
|
||||
chemical_flags = REAGENT_ALL_PROCESS //Sure?
|
||||
reagent_state = SOLID
|
||||
color = "#660000" // rgb: 102, 0, 0.
|
||||
taste_description = "contraband"
|
||||
@@ -1269,6 +1285,7 @@
|
||||
name = "Welding fuel"
|
||||
description = "Required for welders. Flamable."
|
||||
color = "#660000" // rgb: 102, 0, 0
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
taste_description = "gross metal"
|
||||
glass_icon_state = "dr_gibb_glass"
|
||||
glass_name = "glass of welder fuel"
|
||||
@@ -1357,6 +1374,7 @@
|
||||
name = "EZ Clean"
|
||||
description = "A powerful, acidic cleaner sold by Waffle Co. Affects organic matter while leaving other objects unaffected."
|
||||
metabolization_rate = 1.5 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
taste_description = "acid"
|
||||
pH = 2
|
||||
value = REAGENT_VALUE_RARE
|
||||
@@ -1559,6 +1577,7 @@
|
||||
description = "An unstable experimental gas that greatly increases the energy of those that inhale it"
|
||||
reagent_state = GAS
|
||||
metabolization_rate = 1.5 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
color = "E1A116"
|
||||
taste_description = "sourness"
|
||||
value = REAGENT_VALUE_EXCEPTIONAL
|
||||
@@ -1827,6 +1846,7 @@
|
||||
/datum/reagent/colorful_reagent
|
||||
name = "Colorful Reagent"
|
||||
description = "Thoroughly sample the rainbow."
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
reagent_state = LIQUID
|
||||
color = "#FFFF00"
|
||||
var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d11141","#00b159","#00aedb","#f37735","#ffc425","#008744","#0057e7","#d62d20","#ffa700")
|
||||
@@ -2117,6 +2137,7 @@
|
||||
color = "#123524" // RGB (18, 53, 36)
|
||||
metabolization_rate = INFINITY
|
||||
can_synth = FALSE
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
taste_description = "brains"
|
||||
pH = 0.5
|
||||
value = REAGENT_VALUE_GLORIOUS
|
||||
@@ -2132,6 +2153,7 @@
|
||||
name = "Magillitis"
|
||||
description = "An experimental serum which causes rapid muscular growth in Hominidae. Side-affects may include hypertrichosis, violent outbursts, and an unending affinity for bananas."
|
||||
reagent_state = LIQUID
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
color = "#00f041"
|
||||
value = REAGENT_VALUE_EXCEPTIONAL
|
||||
|
||||
@@ -2145,6 +2167,7 @@
|
||||
description = "A commercial chemical designed to help older men in the bedroom."//not really it just makes you a giant
|
||||
color = "#ff0000"//strong red. rgb 255, 0, 0
|
||||
var/current_size = RESIZE_DEFAULT_SIZE
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
value = REAGENT_VALUE_COMMON
|
||||
taste_description = "bitterness" // apparently what viagra tastes like
|
||||
|
||||
@@ -2233,6 +2256,7 @@
|
||||
color = "#FAFF00"
|
||||
taste_description = "acrid cinnamon"
|
||||
metabolization_rate = 0.2 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS //Sorry robot lings, but you still get this.
|
||||
value = REAGENT_VALUE_UNCOMMON
|
||||
|
||||
/datum/reagent/bz_metabolites/on_mob_metabolize(mob/living/L)
|
||||
@@ -2320,7 +2344,7 @@
|
||||
can_synth = FALSE
|
||||
var/datum/dna/original_dna
|
||||
var/reagent_ticks = 0
|
||||
chemical_flags = REAGENT_INVISIBLE
|
||||
chemical_flags = REAGENT_INVISIBLE | REAGENT_ALL_PROCESS
|
||||
value = REAGENT_VALUE_GLORIOUS
|
||||
|
||||
/datum/reagent/changeling_string/on_mob_metabolize(mob/living/carbon/C)
|
||||
@@ -2377,6 +2401,7 @@
|
||||
description = "A powerful preservation agent, utilizing the preservative effects of formaldehyde with significantly less of the histamine."
|
||||
reagent_state = LIQUID
|
||||
color = "#f7685e"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
metabolization_rate = REAGENTS_METABOLISM * 0.25
|
||||
|
||||
|
||||
@@ -2428,6 +2453,7 @@
|
||||
color = "#050096" // rgb: 5, 0, 150
|
||||
taste_mult = 0 // oderless and tasteless
|
||||
metabolization_rate = 0.1 * REAGENTS_METABOLISM //20 times as long, so it's actually viable to use
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
var/time_multiplier = 1 MINUTES //1 minute per unit of gravitum on objects. Seems overpowered, but the whole thing is very niche
|
||||
|
||||
/datum/reagent/gravitum/reaction_obj(obj/O, volume)
|
||||
@@ -2507,6 +2533,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#D2FFFA"
|
||||
metabolization_rate = 0.75 * REAGENTS_METABOLISM // 5u (WOUND_DETERMINATION_CRITICAL) will last for ~17 ticks
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
/// Whether we've had at least WOUND_DETERMINATION_SEVERE (2.5u) of determination at any given time. No damage slowdown immunity or indication we're having a second wind if it's just a single moderate wound
|
||||
var/significant = FALSE
|
||||
self_consuming = TRUE
|
||||
@@ -2540,6 +2567,7 @@
|
||||
name = "Eldritch Essence"
|
||||
description = "Strange liquid that defies the laws of physics"
|
||||
taste_description = "Ag'hsj'saje'sh"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
color = "#1f8016"
|
||||
|
||||
/datum/reagent/eldritch/on_mob_life(mob/living/carbon/M)
|
||||
@@ -2624,6 +2652,7 @@
|
||||
description = "A unknown red liquid, linked to healing of most moral wounds."
|
||||
color = "#c10000"
|
||||
metabolization_rate = REAGENTS_METABOLISM * 2.5
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
|
||||
/datum/reagent/red_ichor/on_mob_life(mob/living/carbon/M)
|
||||
M.adjustBruteLoss(-50)
|
||||
@@ -2641,6 +2670,7 @@
|
||||
description = "A unknown green liquid, linked to healing of most internal wounds."
|
||||
color = "#158c00"
|
||||
metabolization_rate = REAGENTS_METABOLISM * 2.5
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
|
||||
/datum/reagent/green_ichor/on_mob_life(mob/living/carbon/M)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_LUNGS, -100)
|
||||
@@ -2658,6 +2688,7 @@
|
||||
description = "A unknown blue liquid, linked to healing the mind."
|
||||
color = "#0914e0"
|
||||
metabolization_rate = REAGENTS_METABOLISM * 2.5
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
|
||||
/datum/reagent/blue_ichor/on_mob_life(mob/living/carbon/M)
|
||||
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -100)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/datum/reagent/thermite
|
||||
name = "Thermite"
|
||||
description = "Thermite produces an aluminothermic reaction known as a thermite reaction. Can be used to melt walls."
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
reagent_state = SOLID
|
||||
color = "#550000"
|
||||
taste_description = "sweet tasting metal"
|
||||
@@ -44,6 +45,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#FFC8C8"
|
||||
metabolization_rate = 4
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
taste_description = "burning"
|
||||
value = REAGENT_VALUE_COMMON
|
||||
|
||||
@@ -146,6 +148,7 @@
|
||||
/datum/reagent/phlogiston
|
||||
name = "Phlogiston"
|
||||
description = "Catches you on fire and makes you ignite."
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
reagent_state = LIQUID
|
||||
color = "#FA00AF"
|
||||
taste_description = "burning"
|
||||
@@ -168,6 +171,7 @@
|
||||
/datum/reagent/napalm
|
||||
name = "Napalm"
|
||||
description = "Very flammable."
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
reagent_state = LIQUID
|
||||
color = "#FA00AF"
|
||||
taste_description = "burning"
|
||||
@@ -197,6 +201,7 @@
|
||||
color = "#0000DC"
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
taste_description = "bitterness"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
value = REAGENT_VALUE_COMMON
|
||||
|
||||
/datum/reagent/cryostylane/on_mob_life(mob/living/carbon/M) //TODO: code freezing into an ice cube
|
||||
@@ -215,6 +220,7 @@
|
||||
description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Pyrosium slowly heats all other reagents in the container."
|
||||
color = "#64FAC8"
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
taste_description = "bitterness"
|
||||
value = REAGENT_VALUE_COMMON
|
||||
|
||||
@@ -230,6 +236,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#20324D" //RGB: 32, 50, 77
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
taste_description = "charged metal"
|
||||
var/shock_timer = 0
|
||||
value = REAGENT_VALUE_VERY_RARE
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
name = "Unstable mutagen"
|
||||
description = "Might cause unpredictable mutations. Keep away from children."
|
||||
color = "#00FF00"
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
toxpwr = 0
|
||||
taste_description = "slime"
|
||||
taste_mult = 0.9
|
||||
@@ -448,6 +449,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#787878"
|
||||
metabolization_rate = 0.125 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
toxpwr = 0
|
||||
value = REAGENT_VALUE_VERY_RARE
|
||||
|
||||
@@ -495,6 +497,7 @@
|
||||
reagent_state = LIQUID
|
||||
color = "#B4004B"
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
chemical_flags = REAGENT_ALL_PROCESS
|
||||
toxpwr = 1
|
||||
|
||||
/datum/reagent/toxin/formaldehyde/on_mob_life(mob/living/carbon/M)
|
||||
@@ -869,6 +872,7 @@
|
||||
description = "A strong mineral acid with the molecular formula H2SO4."
|
||||
color = "#00FF32"
|
||||
toxpwr = 1
|
||||
chemical_flags = REAGENT_ALL_PROCESS //Ever injected acid into a robot?
|
||||
var/acidpwr = 10 //the amount of protection removed from the armour
|
||||
taste_description = "acid"
|
||||
self_consuming = TRUE
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
var/list/research_logs = list() //IC logs.
|
||||
var/largest_bomb_value = 0
|
||||
var/organization = "Third-Party" //Organization name, used for display.
|
||||
var/list/next_income = list() //To be applied on the next passive techweb income
|
||||
var/list/last_bitcoins = list() //Current per-second production, used for display only.
|
||||
var/list/discovered_mutations = list() //Mutations discovered by genetics, this way they are shared and cant be destroyed by destroying a single console
|
||||
var/list/tiers = list() //Assoc list, id = number, 1 is available, 2 is all reqs are 1, so on
|
||||
@@ -105,10 +106,15 @@
|
||||
V.rescan_views()
|
||||
V.updateUsrDialog()
|
||||
|
||||
/datum/techweb/proc/add_point_list(list/pointlist)
|
||||
for(var/i in pointlist)
|
||||
if(SSresearch.point_types[i] && pointlist[i] > 0)
|
||||
research_points[i] += pointlist[i]
|
||||
/datum/techweb/proc/add_point_list(list/pointlist, income = TRUE)
|
||||
if(income) // i DO NOT TRUST byond to optimize this way properly
|
||||
for(var/i in pointlist)
|
||||
if(SSresearch.point_types[i] && pointlist[i] > 0)
|
||||
next_income[i] += pointlist[i]
|
||||
else
|
||||
for(var/i in pointlist)
|
||||
if(SSresearch.point_types[i] && pointlist[i] > 0)
|
||||
research_points[i] += pointlist[i]
|
||||
|
||||
/datum/techweb/proc/add_points_all(amount)
|
||||
var/list/l = SSresearch.point_types.Copy()
|
||||
@@ -116,6 +122,12 @@
|
||||
l[i] = amount
|
||||
add_point_list(l)
|
||||
|
||||
/datum/techweb/proc/commit_income()
|
||||
. = next_income.Copy()
|
||||
add_point_list(next_income, income = FALSE)
|
||||
for(var/i in next_income)
|
||||
next_income[i] = 0
|
||||
|
||||
/datum/techweb/proc/remove_point_list(list/pointlist)
|
||||
for(var/i in pointlist)
|
||||
if(SSresearch.point_types[i] && pointlist[i] > 0)
|
||||
@@ -170,16 +182,22 @@
|
||||
/datum/techweb/proc/get_researched_nodes()
|
||||
return researched_nodes - hidden_nodes
|
||||
|
||||
/datum/techweb/proc/add_point_type(type, amount)
|
||||
/datum/techweb/proc/add_point_type(type, amount, income = TRUE)
|
||||
if(!SSresearch.point_types[type] || (amount <= 0))
|
||||
return FALSE
|
||||
research_points[type] += amount
|
||||
if(income)
|
||||
next_income[type] += amount
|
||||
else
|
||||
research_points[type] += amount
|
||||
return TRUE
|
||||
|
||||
/datum/techweb/proc/modify_point_type(type, amount)
|
||||
/datum/techweb/proc/modify_point_type(type, amount, income = TRUE)
|
||||
if(!SSresearch.point_types[type])
|
||||
return FALSE
|
||||
research_points[type] = max(0, research_points[type] + amount)
|
||||
if(income && amount > 0)
|
||||
next_income[type] += amount
|
||||
else
|
||||
research_points[type] = max(0, research_points[type] + amount)
|
||||
return TRUE
|
||||
|
||||
/datum/techweb/proc/remove_point_type(type, amount)
|
||||
|
||||
@@ -92,6 +92,10 @@
|
||||
icon_state = "capturedevice"
|
||||
|
||||
/obj/item/capturedevice/attack(mob/living/M, mob/user)
|
||||
try_catching(M, user)
|
||||
|
||||
/obj/item/capturedevice/proc/try_catching(mob/living/M, mob/user)
|
||||
set waitfor = FALSE
|
||||
if(length(contents))
|
||||
to_chat(user, "<span class='warning'>The device already has something inside.</span>")
|
||||
return
|
||||
@@ -116,7 +120,7 @@
|
||||
to_chat(user, "<span class='warning'>This creature is too aggressive to capture.</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You store [M] in the capture device.</span>")
|
||||
store(M)
|
||||
store(M, user)
|
||||
|
||||
/obj/item/capturedevice/attack_self(mob/user)
|
||||
if(contents.len)
|
||||
@@ -125,7 +129,10 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The device is empty...</span>")
|
||||
|
||||
/obj/item/capturedevice/proc/store(var/mob/living/M)
|
||||
/obj/item/capturedevice/proc/store(var/mob/living/M, mob/user)
|
||||
if(length(contents))
|
||||
to_chat(user, "<span class='warning'>The device already has something inside.</span>")
|
||||
return
|
||||
M.forceMove(src)
|
||||
|
||||
/obj/item/capturedevice/proc/release()
|
||||
|
||||
@@ -735,7 +735,10 @@
|
||||
if(jb)
|
||||
to_chat(user, "<span class='warning'>Your mind goes blank as you attempt to use the potion.</span>")
|
||||
return
|
||||
try_transfer_mind(SM, user)
|
||||
|
||||
/obj/item/slimepotion/transference/proc/try_transfer_mind(mob/living/simple_animal/SM, mob/user)
|
||||
set waitfor = FALSE
|
||||
prompted = 1
|
||||
if(alert("This will permanently transfer your consciousness to [SM]. Are you sure you want to do this?",,"Yes","No")=="No")
|
||||
prompted = 0
|
||||
|
||||
@@ -223,7 +223,6 @@
|
||||
var/alert_type = null
|
||||
if(ispath(breathing_class))
|
||||
breathing_class = breathing_classes[breathing_class]
|
||||
var/list/gases = breathing_class.gases
|
||||
alert_category = breathing_class.high_alert_category
|
||||
alert_type = breathing_class.high_alert_datum
|
||||
danger_reagent = breathing_class.danger_reagent
|
||||
|
||||
@@ -13,3 +13,24 @@
|
||||
desc = "A keyring with a small steel key, and a pink fob reading \"Pussy Wagon\"."
|
||||
icon_state = "keyjanitor"
|
||||
|
||||
//START VECTORCARKEYS
|
||||
/obj/item/key/CMO
|
||||
desc = "A keyring with a small steel key to the CMO\'s race hovercar."
|
||||
|
||||
/obj/item/key/RD
|
||||
desc = "A keyring with a small steel key to the RD\'s race hovercar."
|
||||
|
||||
/obj/item/key/hop
|
||||
desc = "A keyring with a small steel key to the HOP\'s race hovercar."
|
||||
|
||||
/obj/item/key/hos
|
||||
desc = "A keyring with a small steel key to the HOS\'s race hovercar."
|
||||
|
||||
/obj/item/key/CE
|
||||
desc = "A keyring with a small steel key to the CE\'s race hovercar."
|
||||
|
||||
/obj/item/key/QM
|
||||
desc = "A keyring with a small steel key to the QM\'s race hovercar."
|
||||
|
||||
/obj/item/key/CAPT
|
||||
desc = "A keyring with a small steel key to the Captain\'s race hovercar."
|
||||
|
||||
Reference in New Issue
Block a user