mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-19 02:54:41 +01:00
Merge remote-tracking branch 'upstream/master' into advanced-camera-fixup
This commit is contained in:
@@ -447,7 +447,7 @@
|
||||
new/obj/machinery/door/airlock(get_turf(object))
|
||||
else if(istype(object,/turf) && ctrl_click && left_click)
|
||||
var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object))
|
||||
WIN.set_dir(build_dir)
|
||||
WIN.setDir(build_dir)
|
||||
log_admin("Build Mode: [key_name(user)] built a window at ([object.x],[object.y],[object.z])")
|
||||
|
||||
if(ADV_BUILDMODE)
|
||||
@@ -458,7 +458,7 @@
|
||||
T.ChangeTurf(objholder)
|
||||
else
|
||||
var/obj/A = new objholder (get_turf(object))
|
||||
A.set_dir(build_dir)
|
||||
A.setDir(build_dir)
|
||||
log_admin("Build Mode: [key_name(user)] modified [A]'s ([A.x],[A.y],[A.z]) dir to [build_dir]")
|
||||
else if(right_click)
|
||||
if(isobj(object))
|
||||
@@ -547,7 +547,7 @@
|
||||
T.ChangeTurf(objholder)
|
||||
else
|
||||
var/obj/A = new objholder(T)
|
||||
A.set_dir(build_dir)
|
||||
A.setDir(build_dir)
|
||||
deselect_region()
|
||||
return
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
name = "\improper Clown Planet"
|
||||
icon_state = "honk"
|
||||
luminosity = 1
|
||||
lighting_use_dynamic = 0
|
||||
dynamic_lighting = 0
|
||||
requires_power = 0
|
||||
report_alerts = 0
|
||||
|
||||
|
||||
/area/awaymission/clownplanet/miningtown
|
||||
name = "\improper Clown Planet - Bananium-o-Rama"
|
||||
icon_state = "away1"
|
||||
|
||||
@@ -13,13 +13,6 @@ var/global/list/potentialRandomZlevels = generateMapList(filename = "config/away
|
||||
air_master.setup_allturfs(turfs)
|
||||
log_debug("\tTook [stop_watch(subtimer)]s")
|
||||
|
||||
subtimer = start_watch()
|
||||
log_debug("Initializing lighting")
|
||||
for(var/turf/T in turfs)
|
||||
if(T.dynamic_lighting)
|
||||
T.lighting_build_overlays()
|
||||
log_debug("\tTook [stop_watch(subtimer)]s")
|
||||
|
||||
subtimer = start_watch()
|
||||
log_debug("Smoothing tiles")
|
||||
for(var/turf/T in smoothTurfs)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/area/awaymission/upperlevel
|
||||
name = "Open Space"
|
||||
color = "#888"
|
||||
lighting_use_dynamic = 0
|
||||
dynamic_lighting = 0
|
||||
requires_power = 0
|
||||
|
||||
// Used by /turf/unsimulated/floor/upperlevel as a reference for where the other floor is
|
||||
|
||||
@@ -92,4 +92,6 @@
|
||||
var/datum/chatOutput/chatOutput
|
||||
|
||||
// Donator stuff.
|
||||
var/donator_level = DONATOR_LEVEL_NONE
|
||||
var/donator_level = DONATOR_LEVEL_NONE
|
||||
|
||||
var/var_edited = FALSE
|
||||
|
||||
@@ -233,6 +233,10 @@
|
||||
return 0
|
||||
return 1
|
||||
|
||||
//Like for /atoms, but clients are their own snowflake FUCK
|
||||
/client/proc/setDir(newdir)
|
||||
dir = newdir
|
||||
|
||||
/client/proc/handle_spam_prevention(var/message, var/mute_type, var/throttle = 0)
|
||||
if(throttle)
|
||||
if((last_message_time + throttle > world.time) && !check_rights(R_ADMIN, 0))
|
||||
@@ -621,3 +625,9 @@
|
||||
if(lang.flags & RESTRICTED)
|
||||
message += " (RESTRICTED)"
|
||||
to_chat(world, "[message]")
|
||||
|
||||
/client/proc/colour_transition(var/list/colour_to = null, var/time = 10) //Call this with no parameters to reset to default.
|
||||
animate(src, color=colour_to, time=time, easing=SINE_EASING)
|
||||
|
||||
/client/proc/on_varedit()
|
||||
var_edited = TRUE
|
||||
|
||||
@@ -817,6 +817,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
HTML += ShowDisabilityState(user,DISABILITY_FLAG_EPILEPTIC,"Seizures")
|
||||
HTML += ShowDisabilityState(user,DISABILITY_FLAG_DEAF,"Deaf")
|
||||
HTML += ShowDisabilityState(user,DISABILITY_FLAG_BLIND,"Blind")
|
||||
HTML += ShowDisabilityState(user,DISABILITY_FLAG_COLOURBLIND,"Colourblind")
|
||||
HTML += ShowDisabilityState(user,DISABILITY_FLAG_MUTE,"Mute")
|
||||
|
||||
|
||||
@@ -1339,9 +1340,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
//Reset prosthetics.
|
||||
organ_data = list()
|
||||
rlimb_data = list()
|
||||
if("speciesprefs")//oldvox code
|
||||
speciesprefs = !speciesprefs
|
||||
|
||||
if("speciesprefs")
|
||||
speciesprefs = !speciesprefs //Starts 0, so if someone clicks the button up top there, this won't be 0 anymore. If they click it again, it'll go back to 0.
|
||||
if("language")
|
||||
// var/languages_available
|
||||
var/list/new_languages = list("None")
|
||||
@@ -2168,6 +2168,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
if(disabilities & DISABILITY_FLAG_BLIND)
|
||||
character.dna.SetSEState(BLINDBLOCK,1,1)
|
||||
|
||||
if(disabilities & DISABILITY_FLAG_COLOURBLIND)
|
||||
character.dna.SetSEState(COLOURBLINDBLOCK,1,1)
|
||||
|
||||
if(disabilities & DISABILITY_FLAG_MUTE)
|
||||
character.dna.SetSEState(MUTEBLOCK,1,1)
|
||||
|
||||
|
||||
@@ -232,8 +232,6 @@
|
||||
name = "noir sunglasses"
|
||||
desc = "Somehow these seem even more out-of-date than normal sunglasses."
|
||||
actions_types = list(/datum/action/item_action/noir)
|
||||
var/noir_mode = 0
|
||||
color_view = MATRIX_GREYSCALE
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/noir/attack_self()
|
||||
toggle_noir()
|
||||
@@ -243,36 +241,8 @@
|
||||
return 1
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/noir/proc/toggle_noir()
|
||||
var/list/difference = difflist(usr.client.color, color_view)
|
||||
|
||||
if(!noir_mode)
|
||||
if(color_view && usr.client && (!usr.client.color || difference))
|
||||
animate(usr.client, color = color_view, time = 10)
|
||||
noir_mode = 1
|
||||
else
|
||||
if(usr.client && usr.client.color && !difference)
|
||||
animate(usr.client, color = initial(usr.client.color), time = 10)
|
||||
noir_mode = 0
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/noir/equipped(mob/user, slot)
|
||||
var/list/difference = difflist(user.client.color, color_view)
|
||||
|
||||
if(slot == slot_glasses)
|
||||
if(noir_mode)
|
||||
if(color_view && user.client && (!user.client.color || difference.len))
|
||||
animate(user.client, color = color_view, time = 10)
|
||||
else
|
||||
if(user.client && user.client.color && !difference.len)
|
||||
animate(user.client, color = initial(user.client.color), time = 10)
|
||||
..(user, slot)
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/noir/dropped(mob/living/carbon/human/user)
|
||||
var/list/difference = difflist(user.client.color, color_view)
|
||||
|
||||
if(istype(user) && user.glasses == src)
|
||||
if(user.client && user.client.color && !difference.len)
|
||||
animate(user.client, color = initial(user.client.color), time = 10)
|
||||
..(user)
|
||||
color_view = color_view ? null : MATRIX_GREYSCALE //Toggles between null and grayscale, with null being the default option.
|
||||
usr.update_client_colour()
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/yeah
|
||||
name = "agreeable glasses"
|
||||
@@ -498,3 +468,28 @@
|
||||
name = "gar glasses"
|
||||
icon_state = "gar"
|
||||
item_state = "gar"
|
||||
|
||||
/obj/item/clothing/glasses/godeye
|
||||
name = "eye of god"
|
||||
desc = "A strange eye, said to have been torn from an omniscient creature that used to roam the wastes."
|
||||
icon_state = "godeye"
|
||||
item_state = "godeye"
|
||||
vision_flags = SEE_TURFS|SEE_MOBS|SEE_OBJS
|
||||
darkness_view = 8
|
||||
scan_reagents = 1
|
||||
flags = NODROP
|
||||
invis_view = SEE_INVISIBLE_MINIMUM
|
||||
|
||||
/obj/item/clothing/glasses/godeye/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if(istype(W, src) && W != src && W.loc == user)
|
||||
if(W.icon_state == "godeye")
|
||||
W.icon_state = "doublegodeye"
|
||||
W.item_state = "doublegodeye"
|
||||
W.desc = "A pair of strange eyes, said to have been torn from an omniscient creature that used to roam the wastes. There's no real reason to have two, but that isn't stopping you."
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.update_inv_wear_mask()
|
||||
else
|
||||
to_chat(user, "<span class='notice'>The eye winks at you and vanishes into the abyss, you feel really unlucky.</span>")
|
||||
qdel(src)
|
||||
..()
|
||||
@@ -7,20 +7,21 @@
|
||||
armor = list(melee = 45, bullet = 25, laser = 30, energy = 10, bomb = 25, bio = 100, rad = 50)
|
||||
rig_restrict_helmet = 0 // ERT helmets can be taken on and off at will.
|
||||
var/obj/machinery/camera/camera
|
||||
var/has_camera = TRUE
|
||||
strip_delay = 130
|
||||
|
||||
/obj/item/clothing/head/helmet/space/rig/ert/attack_self(mob/user)
|
||||
if(camera)
|
||||
if(camera || !has_camera)
|
||||
..(user)
|
||||
else
|
||||
camera = new /obj/machinery/camera(src)
|
||||
camera.network = list("ERT")
|
||||
cameranet.removeCamera(camera)
|
||||
camera.c_tag = user.name
|
||||
to_chat(user, "\blue User scanned as [camera.c_tag]. Camera activated.")
|
||||
to_chat(user, "<span class='notice'>User scanned as [camera.c_tag]. Camera activated.</span>")
|
||||
|
||||
/obj/item/clothing/head/helmet/space/rig/ert/examine(mob/user)
|
||||
if(..(user, 1))
|
||||
if(..(user, 1) && has_camera)
|
||||
to_chat(user, "This helmet has a built-in camera. It's [camera ? "" : "in"]active.")
|
||||
|
||||
/obj/item/clothing/suit/space/rig/ert
|
||||
@@ -101,6 +102,7 @@
|
||||
desc = "A suit worn by the janitorial of a Nanotrasen Emergency Response Team. Has purple highlights. Armoured, space ready, and fire resistant."
|
||||
icon_state = "ert_janitor"
|
||||
|
||||
//Paranormal
|
||||
/obj/item/clothing/head/helmet/space/rig/ert/paranormal
|
||||
name = "paranormal response unit helmet"
|
||||
desc = "A helmet worn by those who deal with paranormal threats for a living."
|
||||
@@ -108,16 +110,39 @@
|
||||
item_color = "ert_paranormal"
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT
|
||||
sprite_sheets = null
|
||||
icon_override = 'icons/mob/clothing/paranormal_hardsuit.dmi'
|
||||
actions_types = list()
|
||||
has_camera = 0
|
||||
|
||||
/obj/item/clothing/suit/space/rig/ert/paranormal
|
||||
name = "paranormal response team suit"
|
||||
desc = "Powerful wards are built into this hardsuit, protecting the user from all manner of paranormal threats."
|
||||
icon_state = "knight_grey"
|
||||
item_state = "knight_grey"
|
||||
icon_state = "rig-paranormal"
|
||||
max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
|
||||
sprite_sheets = null
|
||||
|
||||
icon_override = 'icons/mob/clothing/paranormal_hardsuit.dmi'
|
||||
actions_types = list()
|
||||
|
||||
/obj/item/clothing/suit/space/rig/ert/paranormal/New()
|
||||
..()
|
||||
new /obj/item/weapon/nullrod(src)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/rig/ert/paranormal/inquisitor
|
||||
name = "inquisitor's helmet"
|
||||
icon_state = "rig0-inquisitor"
|
||||
item_color = "inquisitor"
|
||||
|
||||
/obj/item/clothing/suit/space/rig/ert/paranormal/inquisitor
|
||||
name = "inquisitor's hardsuit"
|
||||
icon_state = "rig-inquisitor"
|
||||
|
||||
/obj/item/clothing/head/helmet/space/rig/ert/paranormal/berserker
|
||||
name = "champion's helmet"
|
||||
desc = "Peering into the eyes of the helmet is enough to seal damnation."
|
||||
icon_state = "rig0-berserker"
|
||||
item_color = "berserker"
|
||||
|
||||
/obj/item/clothing/suit/space/rig/ert/paranormal/berserker
|
||||
name = "champion's hardsuit"
|
||||
desc = "Voices echo from the hardsuit, driving the user insane."
|
||||
icon_state = "rig-berserker"
|
||||
@@ -101,8 +101,13 @@ var/list/event_last_fired = list()
|
||||
playercount_modifier = 1
|
||||
if(26 to 35)
|
||||
playercount_modifier = 0.9
|
||||
if(36 to 100000)
|
||||
if(36 to 50)
|
||||
playercount_modifier = 0.8
|
||||
if(50 to 80)
|
||||
playercount_modifier = 0.7
|
||||
if(80 to 10000)
|
||||
playercount_modifier = 0.6
|
||||
|
||||
playercount_modifier = playercount_modifier * delay_modifier
|
||||
|
||||
var/event_delay = rand(config.event_delay_lower[severity], config.event_delay_upper[severity]) * playercount_modifier
|
||||
@@ -155,6 +160,7 @@ var/list/event_last_fired = list()
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ion_storm, 0, list(ASSIGNMENT_AI = 50, ASSIGNMENT_CYBORG = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Borer Infestation", /datum/event/borer_infestation, 40, list(ASSIGNMENT_SECURITY = 30), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Immovable Rod", /datum/event/immovable_rod, 0, list(ASSIGNMENT_ENGINEER = 30), 1),
|
||||
//new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 15), 1),
|
||||
// NON-BAY EVENTS
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Mass Hallucination", /datum/event/mass_hallucination, 300),
|
||||
@@ -170,7 +176,7 @@ var/list/event_last_fired = list()
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Gravitational Anomaly", /datum/event/anomaly/anomaly_grav, 200),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Revenant", /datum/event/revenant, 150),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Swarmer Spawn", /datum/event/spawn_swarmer, 150, is_one_shot = 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Morph Spawn", /datum/event/spawn_morph, 0, is_one_shot = 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Morph Spawn", /datum/event/spawn_morph, 40, is_one_shot = 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Disease Outbreak", /datum/event/disease_outbreak, 0, list(ASSIGNMENT_MEDICAL = 150), 1)
|
||||
)
|
||||
|
||||
@@ -185,6 +191,7 @@ var/list/event_last_fired = list()
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Abductor Visit", /datum/event/abductor, 80, is_one_shot = 1),
|
||||
new /datum/event_meta/alien(EVENT_LEVEL_MAJOR, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 30), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Traders", /datum/event/traders, 0, is_one_shot = 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Slaughter Demon", /datum/event/spawn_slaughter, 15, is_one_shot = 1),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -34,10 +34,19 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
loc = start
|
||||
z_original = z
|
||||
destination = end
|
||||
notify_ghosts("\A [src] is inbound!",
|
||||
enter_link="<a href=?src=[UID()];follow=1>(Click to follow)</a>",
|
||||
source=src, action=NOTIFY_FOLLOW)
|
||||
poi_list |= src
|
||||
if(end && end.z==z_original)
|
||||
walk_towards(src, destination, 1)
|
||||
|
||||
|
||||
/obj/effect/immovablerod/Topic(href, href_list)
|
||||
if(href_list["follow"])
|
||||
var/mob/dead/observer/ghost = usr
|
||||
if(istype(ghost))
|
||||
ghost.ManualFollow(src)
|
||||
|
||||
/obj/effect/immovablerod/Destroy()
|
||||
poi_list.Remove(src)
|
||||
return ..()
|
||||
@@ -70,4 +79,4 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
H.adjustBruteLoss(160)
|
||||
if(clong.density || prob(10))
|
||||
clong.ex_act(2)
|
||||
return
|
||||
return
|
||||
@@ -37,8 +37,8 @@
|
||||
player_mind.transfer_to(S)
|
||||
player_mind.assigned_role = "Slaughter Demon"
|
||||
player_mind.special_role = SPECIAL_ROLE_SLAUGHTER_DEMON
|
||||
message_admins("[key_of_slaughter] has been made into a Slaughter Demon by an event.")
|
||||
log_game("[key_of_slaughter] was spawned as a Slaughter Demon by an event.")
|
||||
message_admins("[key_name_admin(S)] has been made into a Slaughter Demon by an event.")
|
||||
log_game("[key_name_admin(S)] was spawned as a Slaughter Demon by an event.")
|
||||
return 1
|
||||
|
||||
/datum/event/spawn_slaughter/start()
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
to_chat(user, "<span class='warning'> [src] is full.</span>")
|
||||
return
|
||||
|
||||
var/trans = target.reagents.trans_to(src, target:amount_per_transfer_from_this)
|
||||
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
|
||||
to_chat(user, "<span class='notice'> You fill [src] with [trans] units of the contents of [target].</span>")
|
||||
|
||||
else if(target.is_open_container()) //Something like a glass. Player probably wants to transfer TO it.
|
||||
@@ -332,7 +332,7 @@
|
||||
desc = "A cup with the british flag emblazoned on it."
|
||||
icon_state = "britcup"
|
||||
volume = 30
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/drinks/mushroom_bowl
|
||||
name = "mushroom bowl"
|
||||
desc = "A bowl made out of mushrooms. Not food, though it might have contained some at some point."
|
||||
|
||||
@@ -1213,25 +1213,18 @@
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/afterattack(obj/O, mob/user, proximity)
|
||||
if(!proximity)
|
||||
return
|
||||
if(istype(O,/obj/structure/sink) && !wrapped)
|
||||
if(istype(O, /obj/structure/sink))
|
||||
to_chat(user, "<span class='notice'>You place [src] under a stream of water...</span>")
|
||||
user.drop_item()
|
||||
forceMove(get_turf(O))
|
||||
return Expand()
|
||||
..()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/attack_self(mob/user)
|
||||
if(wrapped)
|
||||
Unwrap(user)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/water_act(volume, temperature)
|
||||
if(volume >= 5)
|
||||
return Expand()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wash(mob/user, atom/source)
|
||||
if(wrapped)
|
||||
..()
|
||||
return
|
||||
if(do_after(user, 40, target = source))
|
||||
return 1
|
||||
|
||||
@@ -1241,49 +1234,22 @@
|
||||
new/mob/living/carbon/human(get_turf(src),monkey_type)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/proc/Unwrap(mob/user)
|
||||
icon_state = "monkeycube"
|
||||
desc = "Just add water!"
|
||||
to_chat(user, "<span class='notice'>You unwrap the cube.</span>")
|
||||
wrapped = 0
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped
|
||||
desc = "Still wrapped in some paper."
|
||||
icon_state = "monkeycubewrap"
|
||||
wrapped = 1
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/farwacube
|
||||
name = "farwa cube"
|
||||
monkey_type = "Farwa"
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/farwacube
|
||||
name = "farwa cube"
|
||||
monkey_type = "Farwa"
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wolpincube
|
||||
name = "wolpin cube"
|
||||
monkey_type = "Wolpin"
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/wolpincube
|
||||
name = "wolpin cube"
|
||||
monkey_type = "Wolpin"
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/stokcube
|
||||
name = "stok cube"
|
||||
monkey_type = "Stok"
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/stokcube
|
||||
name = "stok cube"
|
||||
monkey_type = "Stok"
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/neaeracube
|
||||
name = "neaera cube"
|
||||
monkey_type = "Neara"
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/neaeracube
|
||||
name = "neaera cube"
|
||||
monkey_type = "Neara"
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/spellburger
|
||||
name = "Spell Burger"
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
var/locked = 0
|
||||
var/scan_id = 1
|
||||
var/is_secure = 0
|
||||
var/can_dry = FALSE
|
||||
var/drying = FALSE
|
||||
var/datum/wires/smartfridge/wires = null
|
||||
|
||||
/obj/machinery/smartfridge/New()
|
||||
@@ -195,7 +197,7 @@
|
||||
|
||||
/obj/machinery/smartfridge/default_deconstruction_screwdriver(mob/user, obj/item/weapon/screwdriver/S)
|
||||
. = ..(user, icon_state, icon_state, S)
|
||||
|
||||
|
||||
overlays.Cut()
|
||||
if(panel_open)
|
||||
overlays += image(icon, "[initial(icon_state)]-panel")
|
||||
@@ -332,6 +334,8 @@
|
||||
data["shoot_inventory"] = shoot_inventory
|
||||
data["locked"] = locked
|
||||
data["secure"] = is_secure
|
||||
data["can_dry"] = can_dry
|
||||
data["drying"] = drying
|
||||
|
||||
var/list/items[0]
|
||||
for(var/i=1 to length(item_quants))
|
||||
@@ -372,6 +376,7 @@
|
||||
for(var/obj/O in contents)
|
||||
if(O.name == K)
|
||||
O.forceMove(loc)
|
||||
update_icon()
|
||||
i--
|
||||
if(i <= 0)
|
||||
return 1
|
||||
@@ -394,6 +399,7 @@
|
||||
if(T.name == O)
|
||||
T.forceMove(loc)
|
||||
throw_item = T
|
||||
update_icon()
|
||||
break
|
||||
break
|
||||
if(!throw_item)
|
||||
@@ -416,7 +422,7 @@
|
||||
active_power_usage = 200
|
||||
icon_on = "drying_rack_on"
|
||||
icon_off = "drying_rack"
|
||||
var/drying = FALSE
|
||||
can_dry = TRUE
|
||||
|
||||
/obj/machinery/smartfridge/drying_rack/New()
|
||||
..()
|
||||
@@ -443,6 +449,22 @@
|
||||
/obj/machinery/smartfridge/drying_rack/default_deconstruction_crowbar(obj/item/weapon/crowbar/C, ignore_panel = 1)
|
||||
..()
|
||||
|
||||
/obj/machinery/smartfridge/drying_rack/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(href_list["dryingOn"])
|
||||
drying = TRUE
|
||||
use_power = 2
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
if(href_list["dryingOff"])
|
||||
drying = FALSE
|
||||
use_power = 1
|
||||
update_icon()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/machinery/smartfridge/drying_rack/power_change()
|
||||
if(powered() && anchored)
|
||||
stat &= ~NOPOWER
|
||||
@@ -451,9 +473,10 @@
|
||||
toggle_drying(TRUE)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/smartfridge/drying_rack/load() //For updating the filled overlay
|
||||
..()
|
||||
update_icon()
|
||||
/obj/machinery/smartfridge/drying_rack/load(obj/I, mob/user) //For updating the filled overlay
|
||||
if(..())
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/obj/machinery/smartfridge/drying_rack/update_icon()
|
||||
..()
|
||||
@@ -470,11 +493,11 @@
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/smartfridge/drying_rack/accept_check(obj/item/O)
|
||||
if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/))
|
||||
if(istype(O, /obj/item/weapon/reagent_containers/food/snacks))
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/S = O
|
||||
if(S.dried_type)
|
||||
return TRUE
|
||||
if(istype(O,/obj/item/stack/sheet/wetleather/))
|
||||
if(istype(O, /obj/item/stack/sheet/wetleather))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -492,16 +515,21 @@
|
||||
if(S.dried_type == S.type)//if the dried type is the same as the object's type, don't bother creating a whole new item...
|
||||
S.color = "#ad7257"
|
||||
S.dry = TRUE
|
||||
item_quants[S.name]--
|
||||
S.forceMove(get_turf(src))
|
||||
else
|
||||
var/dried = S.dried_type
|
||||
new dried(loc)
|
||||
item_quants[S.name]--
|
||||
qdel(S)
|
||||
nanomanager.update_uis(src)
|
||||
return TRUE
|
||||
for(var/obj/item/stack/sheet/wetleather/WL in contents)
|
||||
var/obj/item/stack/sheet/leather/L = new(loc)
|
||||
L.amount = WL.amount
|
||||
item_quants[WL.name]--
|
||||
qdel(WL)
|
||||
nanomanager.update_uis(src)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -509,21 +537,6 @@
|
||||
..()
|
||||
atmos_spawn_air(SPAWN_HEAT)
|
||||
|
||||
/obj/machinery/smartfridge/drying_rack/verb/adjust_drying()
|
||||
set category = "Object"
|
||||
set name = "Toggle Drying"
|
||||
set src in view(1)
|
||||
|
||||
if(!iscarbon(usr))
|
||||
to_chat(usr, "<span class='warning'>You can't do that!</span>")
|
||||
return
|
||||
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
|
||||
toggle_drying(FALSE)
|
||||
update_icon()
|
||||
|
||||
/************************
|
||||
* Secure SmartFridges
|
||||
*************************/
|
||||
|
||||
@@ -219,10 +219,10 @@
|
||||
var/S = 0
|
||||
for(var/obj/item/weapon/reagent_containers/food/snacks/grown/I in contents)
|
||||
S += 5
|
||||
if(I.reagents.get_reagent_amount("nutriment") < 0.1)
|
||||
if(I.reagents.get_reagent_amount("nutriment")+I.reagents.get_reagent_amount("plantmatter") < 0.1)
|
||||
points += 1*productivity
|
||||
else
|
||||
points += I.reagents.get_reagent_amount("nutriment")*10*productivity
|
||||
points += (I.reagents.get_reagent_amount("nutriment")+I.reagents.get_reagent_amount("plantmatter"))*10*productivity
|
||||
qdel(I)
|
||||
if(S)
|
||||
processing = 1
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
icon_dead = "ambrosia-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/ambrosia/deus)
|
||||
reagents_add = list("space_drugs" = 0.15, "bicaridine" = 0.1, "kelotane" = 0.1, "vitamin" = 0.04, "nutriment" = 0.05, "toxin" = 0.1)
|
||||
reagents_add = list("space_drugs" = 0.15, "bicaridine" = 0.1, "kelotane" = 0.1, "vitamin" = 0.04, "plantmatter" = 0.05, "toxin" = 0.1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris
|
||||
seed = /obj/item/seeds/ambrosia
|
||||
@@ -40,7 +40,7 @@
|
||||
plantname = "Ambrosia Deus"
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/deus
|
||||
mutatelist = list(/obj/item/seeds/ambrosia/gaia)
|
||||
reagents_add = list("weak_omnizine" = 0.15, "synaptizine" = 0.15, "space_drugs" = 0.1, "vitamin" = 0.04, "nutriment" = 0.05)
|
||||
reagents_add = list("weak_omnizine" = 0.15, "synaptizine" = 0.15, "space_drugs" = 0.1, "vitamin" = 0.04, "plantmatter" = 0.05)
|
||||
rarity = 40
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/deus
|
||||
@@ -80,7 +80,7 @@
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/cruciatus
|
||||
potency = 10
|
||||
mutatelist = list()
|
||||
reagents_add = list("thc" = 0.15, "kelotane" = 0.15, "bicaridine" = 0.1, "bath_salts" = 0.20, "nutriment" = 0.05)
|
||||
reagents_add = list("thc" = 0.15, "kelotane" = 0.15, "bicaridine" = 0.1, "bath_salts" = 0.20, "plantmatter" = 0.05)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/cruciatus
|
||||
seed = /obj/item/seeds/ambrosia/cruciatus
|
||||
@@ -14,7 +14,7 @@
|
||||
icon_dead = "apple-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/apple/gold)
|
||||
reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1)
|
||||
reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/apple
|
||||
seed = /obj/item/seeds/apple
|
||||
@@ -28,7 +28,7 @@
|
||||
/obj/item/seeds/apple/poisoned
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/apple/poisoned
|
||||
mutatelist = list()
|
||||
reagents_add = list("cyanide" = 0.5, "vitamin" = 0.04, "nutriment" = 0.1)
|
||||
reagents_add = list("cyanide" = 0.5, "vitamin" = 0.04, "plantmatter" = 0.1)
|
||||
rarity = 50 // Source of cyanide, and hard (almost impossible) to obtain normally.
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/apple/poisoned
|
||||
@@ -45,7 +45,7 @@
|
||||
maturation = 10
|
||||
production = 10
|
||||
mutatelist = list()
|
||||
reagents_add = list("gold" = 0.2, "vitamin" = 0.04, "nutriment" = 0.1)
|
||||
reagents_add = list("gold" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.1)
|
||||
rarity = 40 // Alchemy!
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/apple/gold
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
icon_dead = "banana-dead"
|
||||
genes = list(/datum/plant_gene/trait/slip, /datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/banana/mime, /obj/item/seeds/banana/bluespace)
|
||||
reagents_add = list("banana" = 0.1, "potassium" = 0.1, "vitamin" = 0.04, "nutriment" = 0.02)
|
||||
reagents_add = list("banana" = 0.1, "potassium" = 0.1, "vitamin" = 0.04, "plantmatter" = 0.02)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/banana
|
||||
seed = /obj/item/seeds/banana
|
||||
@@ -92,7 +92,7 @@
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/banana/bluespace
|
||||
mutatelist = list()
|
||||
genes = list(/datum/plant_gene/trait/slip, /datum/plant_gene/trait/teleport, /datum/plant_gene/trait/repeated_harvest)
|
||||
reagents_add = list("singulo" = 0.2, "banana" = 0.1, "vitamin" = 0.04, "nutriment" = 0.02)
|
||||
reagents_add = list("singulo" = 0.2, "banana" = 0.1, "vitamin" = 0.04, "plantmatter" = 0.02)
|
||||
rarity = 30
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/banana/bluespace
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
icon_dead = "soybean-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/soya/koi)
|
||||
reagents_add = list("vitamin" = 0.04, "nutriment" = 0.05)
|
||||
reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.05)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/soybeans
|
||||
seed = /obj/item/seeds/soya
|
||||
@@ -36,7 +36,7 @@
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/koibeans
|
||||
potency = 10
|
||||
mutatelist = list()
|
||||
reagents_add = list("carpotoxin" = 0.1, "vitamin" = 0.04, "nutriment" = 0.05)
|
||||
reagents_add = list("carpotoxin" = 0.1, "vitamin" = 0.04, "plantmatter" = 0.05)
|
||||
rarity = 20
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/koibeans
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
icon_dead = "berry-dead" // Same for the dead icon
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/berry/glow, /obj/item/seeds/berry/poison)
|
||||
reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1)
|
||||
reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/berries
|
||||
seed = /obj/item/seeds/berry
|
||||
@@ -35,7 +35,7 @@
|
||||
plantname = "Poison-Berry Bush"
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/berries/poison
|
||||
mutatelist = list(/obj/item/seeds/berry/death)
|
||||
reagents_add = list("cyanide" = 0.15, "tirizene" = 0.2, "vitamin" = 0.04, "nutriment" = 0.1)
|
||||
reagents_add = list("cyanide" = 0.15, "tirizene" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.1)
|
||||
rarity = 10 // Mildly poisonous berries are common in reality
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/berries/poison
|
||||
@@ -56,7 +56,7 @@
|
||||
lifespan = 30
|
||||
potency = 50
|
||||
mutatelist = list()
|
||||
reagents_add = list("coniine" = 0.08, "tirizene" = 0.1, "vitamin" = 0.04, "nutriment" = 0.1)
|
||||
reagents_add = list("coniine" = 0.08, "tirizene" = 0.1, "vitamin" = 0.04, "plantmatter" = 0.1)
|
||||
rarity = 30
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/berries/death
|
||||
@@ -78,7 +78,7 @@
|
||||
endurance = 25
|
||||
mutatelist = list()
|
||||
genes = list(/datum/plant_gene/trait/glow/berry , /datum/plant_gene/trait/noreact, /datum/plant_gene/trait/repeated_harvest)
|
||||
reagents_add = list("uranium" = 0.25, "iodine" = 0.2, "vitamin" = 0.04, "nutriment" = 0.1)
|
||||
reagents_add = list("uranium" = 0.25, "iodine" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.1)
|
||||
rarity = 20
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/berries/glow
|
||||
@@ -108,7 +108,7 @@
|
||||
icon_dead = "cherry-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/cherry/blue)
|
||||
reagents_add = list("nutriment" = 0.07, "sugar" = 0.07)
|
||||
reagents_add = list("plantmatter" = 0.07, "sugar" = 0.07)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/cherries
|
||||
seed = /obj/item/seeds/cherry
|
||||
@@ -128,7 +128,7 @@
|
||||
plantname = "Blue Cherry Tree"
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries
|
||||
mutatelist = list()
|
||||
reagents_add = list("nutriment" = 0.07, "sugar" = 0.07)
|
||||
reagents_add = list("plantmatter" = 0.07, "sugar" = 0.07)
|
||||
rarity = 10
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries
|
||||
@@ -158,7 +158,7 @@
|
||||
icon_dead = "grape-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/grape/green)
|
||||
reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1, "sugar" = 0.1)
|
||||
reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.1, "sugar" = 0.1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/grapes
|
||||
seed = /obj/item/seeds/grape
|
||||
@@ -177,7 +177,7 @@
|
||||
species = "greengrape"
|
||||
plantname = "Green-Grape Vine"
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/grapes/green
|
||||
reagents_add = list("kelotane" = 0.2, "vitamin" = 0.04, "nutriment" = 0.1, "sugar" = 0.1)
|
||||
reagents_add = list("kelotane" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.1, "sugar" = 0.1)
|
||||
// No rarity: technically it's a beneficial mutant, but it's not exactly "new"...
|
||||
mutatelist = list()
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
potency = 15
|
||||
icon_dead = "wheat-dead"
|
||||
mutatelist = list(/obj/item/seeds/wheat/oat, /obj/item/seeds/wheat/meat)
|
||||
reagents_add = list("nutriment" = 0.04)
|
||||
reagents_add = list("plantmatter" = 0.04)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/wheat
|
||||
seed = /obj/item/seeds/wheat
|
||||
@@ -70,6 +70,7 @@
|
||||
plantname = "Meatwheat"
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/meatwheat
|
||||
mutatelist = list()
|
||||
reagents_add = list("protein" = 0.04)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/meatwheat
|
||||
name = "meatwheat"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
icon_dead = "chili-dead" // Same for the dead icon
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/chili/ice, /obj/item/seeds/chili/ghost)
|
||||
reagents_add = list("capsaicin" = 0.25, "vitamin" = 0.04, "nutriment" = 0.04)
|
||||
reagents_add = list("capsaicin" = 0.25, "vitamin" = 0.04, "plantmatter" = 0.04)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/chili
|
||||
seed = /obj/item/seeds/chili
|
||||
@@ -39,7 +39,7 @@
|
||||
production = 4
|
||||
rarity = 20
|
||||
mutatelist = list()
|
||||
reagents_add = list("frostoil" = 0.25, "vitamin" = 0.02, "nutriment" = 0.02)
|
||||
reagents_add = list("frostoil" = 0.25, "vitamin" = 0.02, "plantmatter" = 0.02)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/icepepper
|
||||
seed = /obj/item/seeds/chili/ice
|
||||
@@ -64,7 +64,7 @@
|
||||
yield = 3
|
||||
rarity = 20
|
||||
mutatelist = list()
|
||||
reagents_add = list("condensedcapsaicin" = 0.3, "capsaicin" = 0.55, "nutriment" = 0.04)
|
||||
reagents_add = list("condensedcapsaicin" = 0.3, "capsaicin" = 0.55, "plantmatter" = 0.04)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/ghost_chili
|
||||
seed = /obj/item/seeds/chili/ghost
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi'
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/orange)
|
||||
reagents_add = list("vitamin" = 0.04, "nutriment" = 0.05)
|
||||
reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.05)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lime
|
||||
seed = /obj/item/seeds/lime
|
||||
@@ -47,7 +47,7 @@
|
||||
icon_dead = "lime-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/lime)
|
||||
reagents_add = list("vitamin" = 0.04, "nutriment" = 0.05)
|
||||
reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.05)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange
|
||||
seed = /obj/item/seeds/orange
|
||||
@@ -72,7 +72,7 @@
|
||||
icon_dead = "lime-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/firelemon)
|
||||
reagents_add = list("vitamin" = 0.04, "nutriment" = 0.05)
|
||||
reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.05)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lemon
|
||||
seed = /obj/item/seeds/lemon
|
||||
@@ -96,7 +96,7 @@
|
||||
lifespan = 55
|
||||
endurance = 45
|
||||
yield = 4
|
||||
reagents_add = list("nutriment" = 0.05)
|
||||
reagents_add = list("plantmatter" = 0.05)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/firelemon
|
||||
seed = /obj/item/seeds/firelemon
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
icon_dead = "cocoapod-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/cocoapod/vanillapod)
|
||||
reagents_add = list("cocoa" = 0.25, "nutriment" = 0.1)
|
||||
reagents_add = list("cocoa" = 0.25, "plantmatter" = 0.1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/cocoapod
|
||||
seed = /obj/item/seeds/cocoapod
|
||||
@@ -36,7 +36,7 @@
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/vanillapod
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list()
|
||||
reagents_add = list("vanilla" = 0.25, "nutriment" = 0.1)
|
||||
reagents_add = list("vanilla" = 0.25, "plantmatter" = 0.1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/vanillapod
|
||||
seed = /obj/item/seeds/cocoapod/vanillapod
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
icon_grow = "corn-grow" // Uses one growth icons set for all the subtypes
|
||||
icon_dead = "corn-dead" // Same for the dead icon
|
||||
mutatelist = list(/obj/item/seeds/corn/snapcorn)
|
||||
reagents_add = list("cornoil" = 0.2, "vitamin" = 0.04, "nutriment" = 0.1)
|
||||
reagents_add = list("cornoil" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/corn
|
||||
seed = /obj/item/seeds/corn
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
icon_dead = "eggplant-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/eggplant/eggy)
|
||||
reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1)
|
||||
reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/eggplant
|
||||
seed = /obj/item/seeds/eggplant
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
icon_grow = "poppy-grow"
|
||||
icon_dead = "poppy-dead"
|
||||
mutatelist = list(/obj/item/seeds/poppy/geranium, /obj/item/seeds/poppy/lily)
|
||||
reagents_add = list("bicaridine" = 0.2, "nutriment" = 0.05)
|
||||
reagents_add = list("bicaridine" = 0.2, "plantmatter" = 0.05)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/poppy
|
||||
seed = /obj/item/seeds/poppy
|
||||
@@ -78,7 +78,7 @@
|
||||
growthstages = 4
|
||||
genes = list(/datum/plant_gene/trait/plant_type/weed_hardy)
|
||||
growing_icon = 'icons/obj/hydroponics/growing_flowers.dmi'
|
||||
reagents_add = list("nutriment" = 0.04)
|
||||
reagents_add = list("plantmatter" = 0.04)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/harebell
|
||||
seed = /obj/item/seeds/harebell
|
||||
@@ -106,7 +106,7 @@
|
||||
icon_grow = "sunflower-grow"
|
||||
icon_dead = "sunflower-dead"
|
||||
mutatelist = list(/obj/item/seeds/sunflower/moonflower, /obj/item/seeds/sunflower/novaflower)
|
||||
reagents_add = list("cornoil" = 0.08, "nutriment" = 0.04)
|
||||
reagents_add = list("cornoil" = 0.08, "plantmatter" = 0.04)
|
||||
|
||||
/obj/item/weapon/grown/sunflower // FLOWER POWER!
|
||||
seed = /obj/item/seeds/sunflower
|
||||
@@ -134,7 +134,7 @@
|
||||
plantname = "Moonflowers"
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/moonflower
|
||||
mutatelist = list()
|
||||
reagents_add = list("moonshine" = 0.2, "vitamin" = 0.02, "nutriment" = 0.02)
|
||||
reagents_add = list("moonshine" = 0.2, "vitamin" = 0.02, "plantmatter" = 0.02)
|
||||
rarity = 15
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/moonflower
|
||||
@@ -155,7 +155,7 @@
|
||||
plantname = "Novaflowers"
|
||||
product = /obj/item/weapon/grown/novaflower
|
||||
mutatelist = list()
|
||||
reagents_add = list("condensedcapsaicin" = 0.25, "capsaicin" = 0.3, "nutriment" = 0)
|
||||
reagents_add = list("condensedcapsaicin" = 0.25, "capsaicin" = 0.3, "plantmatter" = 0)
|
||||
rarity = 20
|
||||
|
||||
/obj/item/weapon/grown/novaflower
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
icon_dead = "grass-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/grass/carpet)
|
||||
reagents_add = list("nutriment" = 0.02, "hydrogen" = 0.05)
|
||||
reagents_add = list("plantmatter" = 0.02, "hydrogen" = 0.05)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/grass
|
||||
seed = /obj/item/seeds/grass
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
maturation = 3
|
||||
growthstages = 1
|
||||
growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi'
|
||||
reagents_add = list("nutriment" = 0.1)
|
||||
reagents_add = list("styptic_powder" = 0.1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/comfrey
|
||||
seed = /obj/item/seeds/comfrey
|
||||
@@ -35,7 +35,7 @@
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/aloe
|
||||
yield = 2
|
||||
icon_dead = "ambrosia-dead"
|
||||
reagents_add = list("nutriment" = 0.1)
|
||||
reagents_add = list("silver_sulfadiazine" = 0.1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/aloe
|
||||
seed = /obj/item/seeds/aloe
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
growthstages = 4
|
||||
rarity = 30
|
||||
var/list/mutations = list()
|
||||
reagents_add = list("charcoal" = 0.04, "nutriment" = 0.02)
|
||||
reagents_add = list("charcoal" = 0.04, "plantmatter" = 0.02)
|
||||
|
||||
/obj/item/seeds/kudzu/Copy()
|
||||
var/obj/item/seeds/kudzu/S = ..()
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
icon_dead = "watermelon-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/watermelon/holy)
|
||||
reagents_add = list("water" = 0.2, "vitamin" = 0.04, "nutriment" = 0.2)
|
||||
reagents_add = list("water" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.2)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/watermelon
|
||||
seed = /obj/item/seeds/watermelon
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi'
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/replicapod)
|
||||
reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1)
|
||||
reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/cabbage
|
||||
seed = /obj/item/seeds/cabbage
|
||||
@@ -106,7 +106,7 @@
|
||||
plantname = "Cherry Bomb Tree"
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb
|
||||
mutatelist = list()
|
||||
reagents_add = list("nutriment" = 0.1, "sugar" = 0.1, "blackpowder" = 0.7)
|
||||
reagents_add = list("plantmatter" = 0.1, "sugar" = 0.1, "blackpowder" = 0.7)
|
||||
rarity = 60 //See above
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
growthstages = 3
|
||||
genes = list(/datum/plant_gene/trait/plant_type/fungal_metabolism)
|
||||
growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi'
|
||||
reagents_add = list("psilocybin" = 0.04, "amanitin" = 0.1, "nutriment" = 0, "amanitin" = 0.2)
|
||||
reagents_add = list("psilocybin" = 0.04, "nutriment" = 0, "amanitin" = 0.3)
|
||||
rarity = 30
|
||||
origin_tech = "biotech=5"
|
||||
|
||||
@@ -291,4 +291,4 @@
|
||||
name = "fungus"
|
||||
desc = "A fungus ideal for making antibacterials."
|
||||
icon_state = "angel"
|
||||
color = "#4f4331"
|
||||
color = "#4f4331"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
maturation = 10
|
||||
production = 1
|
||||
yield = 1
|
||||
reagents_add = list("nutriment" = 0.1)
|
||||
reagents_add = list("plantmatter" = 0.1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/nymph_pod
|
||||
seed = /obj/item/seeds/nymph
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
icon_grow = "potato-grow"
|
||||
icon_dead = "potato-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
reagents_add = list("nutriment" = 0.1)
|
||||
reagents_add = list("plantmatter" = 0.1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/peanuts
|
||||
seed = /obj/item/seeds/peanuts
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
icon_dead = "potato-dead"
|
||||
genes = list(/datum/plant_gene/trait/battery)
|
||||
mutatelist = list(/obj/item/seeds/potato/sweet)
|
||||
reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1)
|
||||
reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/potato
|
||||
seed = /obj/item/seeds/potato
|
||||
@@ -56,7 +56,7 @@
|
||||
plantname = "Sweet Potato Plants"
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/potato/sweet
|
||||
mutatelist = list()
|
||||
reagents_add = list("vitamin" = 0.1, "sugar" = 0.1, "nutriment" = 0.1)
|
||||
reagents_add = list("vitamin" = 0.1, "sugar" = 0.1, "plantmatter" = 0.1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/potato/sweet
|
||||
seed = /obj/item/seeds/potato/sweet
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
icon_dead = "pumpkin-dead"
|
||||
genes = list(/datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/pumpkin/blumpkin)
|
||||
reagents_add = list("vitamin" = 0.04, "nutriment" = 0.2)
|
||||
reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.2)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin
|
||||
seed = /obj/item/seeds/pumpkin
|
||||
@@ -42,7 +42,7 @@
|
||||
plantname = "Blumpkin Vines"
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/blumpkin
|
||||
mutatelist = list()
|
||||
reagents_add = list("ammonia" = 0.2, "chlorine" = 0.1, "nutriment" = 0.2)
|
||||
reagents_add = list("ammonia" = 0.2, "chlorine" = 0.1, "plasma" = 0.1, "plantmatter" = 0.2)
|
||||
rarity = 20
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/blumpkin
|
||||
|
||||
@@ -91,6 +91,8 @@
|
||||
podman.ckey = ckey_holder
|
||||
podman.gender = blood_gender
|
||||
podman.faction |= factions
|
||||
podman.faction |= "plants"
|
||||
podman.faction |= "vines" //Pod grown Diona are allied with plants and vines alike.
|
||||
|
||||
else //else, one packet of seeds. maybe two
|
||||
var/seed_count = 1
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
growthstages = 3
|
||||
growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi'
|
||||
mutatelist = list(/obj/item/seeds/carrot/parsnip)
|
||||
reagents_add = list("oculine" = 0.25, "vitamin" = 0.04, "nutriment" = 0.05)
|
||||
reagents_add = list("oculine" = 0.25, "vitamin" = 0.04, "plantmatter" = 0.05)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/carrot
|
||||
seed = /obj/item/seeds/carrot
|
||||
@@ -43,7 +43,7 @@
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/parsnip
|
||||
icon_dead = "carrot-dead"
|
||||
mutatelist = list()
|
||||
reagents_add = list("vitamin" = 0.05, "nutriment" = 0.05)
|
||||
reagents_add = list("vitamin" = 0.05, "plantmatter" = 0.05)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/parsnip
|
||||
seed = /obj/item/seeds/carrot/parsnip
|
||||
@@ -67,7 +67,7 @@
|
||||
growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi'
|
||||
icon_dead = "whitebeet-dead"
|
||||
mutatelist = list(/obj/item/seeds/redbeet)
|
||||
reagents_add = list("vitamin" = 0.04, "sugar" = 0.2, "nutriment" = 0.05)
|
||||
reagents_add = list("vitamin" = 0.04, "sugar" = 0.2, "plantmatter" = 0.05)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/whitebeet
|
||||
seed = /obj/item/seeds/whitebeet
|
||||
@@ -91,7 +91,7 @@
|
||||
growing_icon = 'icons/obj/hydroponics/growing_vegetables.dmi'
|
||||
icon_dead = "whitebeet-dead"
|
||||
genes = list(/datum/plant_gene/trait/maxchem)
|
||||
reagents_add = list("vitamin" = 0.05, "nutriment" = 0.05)
|
||||
reagents_add = list("vitamin" = 0.05, "plantmatter" = 0.05)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/redbeet
|
||||
seed = /obj/item/seeds/redbeet
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
growthstages = 3
|
||||
icon_dead = "tobacco-dead"
|
||||
mutatelist = list(/obj/item/seeds/tobacco/space)
|
||||
reagents_add = list("nicotine" = 0.03, "nutriment" = 0.03)
|
||||
reagents_add = list("nicotine" = 0.03, "plantmatter" = 0.03)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/tobacco
|
||||
seed = /obj/item/seeds/tobacco
|
||||
@@ -31,7 +31,7 @@
|
||||
plantname = "Space Tobacco Plant"
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/tobacco/space
|
||||
mutatelist = list()
|
||||
reagents_add = list("salbutamol" = 0.05, "nicotine" = 0.08, "nutriment" = 0.03)
|
||||
reagents_add = list("salbutamol" = 0.05, "nicotine" = 0.08, "plantmatter" = 0.03)
|
||||
rarity = 20
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/tobacco/space
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
icon_grow = "tomato-grow"
|
||||
icon_dead = "tomato-dead"
|
||||
genes = list(/datum/plant_gene/trait/squash, /datum/plant_gene/trait/repeated_harvest)
|
||||
mutatelist = list(/obj/item/seeds/tomato/blue, /obj/item/seeds/tomato/blood, /obj/item/seeds/tomato/killer)
|
||||
reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1)
|
||||
mutatelist = list(/obj/item/seeds/tomato/blue, /obj/item/seeds/tomato/blood)
|
||||
reagents_add = list("vitamin" = 0.04, "plantmatter" = 0.1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/tomato
|
||||
seed = /obj/item/seeds/tomato
|
||||
@@ -31,8 +31,8 @@
|
||||
species = "bloodtomato"
|
||||
plantname = "Blood-Tomato Plants"
|
||||
product = /obj/item/weapon/reagent_containers/food/snacks/grown/tomato/blood
|
||||
mutatelist = list()
|
||||
reagents_add = list("blood" = 0.2, "vitamin" = 0.04, "nutriment" = 0.1)
|
||||
mutatelist = list(/obj/item/seeds/tomato/killer)
|
||||
reagents_add = list("blood" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.1)
|
||||
rarity = 20
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/tomato/blood
|
||||
@@ -57,7 +57,7 @@
|
||||
icon_grow = "bluetomato-grow"
|
||||
mutatelist = list(/obj/item/seeds/tomato/blue/bluespace)
|
||||
genes = list(/datum/plant_gene/trait/slip, /datum/plant_gene/trait/repeated_harvest)
|
||||
reagents_add = list("lube" = 0.2, "vitamin" = 0.04, "nutriment" = 0.1)
|
||||
reagents_add = list("lube" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.1)
|
||||
rarity = 20
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/tomato/blue
|
||||
@@ -80,7 +80,7 @@
|
||||
yield = 2
|
||||
mutatelist = list()
|
||||
genes = list(/datum/plant_gene/trait/squash, /datum/plant_gene/trait/slip, /datum/plant_gene/trait/teleport, /datum/plant_gene/trait/repeated_harvest)
|
||||
reagents_add = list("lube" = 0.2, "singulo" = 0.2, "vitamin" = 0.04, "nutriment" = 0.1)
|
||||
reagents_add = list("lube" = 0.2, "singulo" = 0.2, "vitamin" = 0.04, "plantmatter" = 0.1)
|
||||
rarity = 50
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/tomato/blue/bluespace
|
||||
@@ -106,6 +106,7 @@
|
||||
icon_harvest = "killertomato-harvest"
|
||||
icon_dead = "killertomato-dead"
|
||||
mutatelist = list()
|
||||
reagents_add = list("vitamin" = 0.04, "protein" = 0.1)
|
||||
rarity = 30
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/tomato/killer
|
||||
|
||||
@@ -521,6 +521,12 @@
|
||||
mutmod = 0
|
||||
adjustNutri(round(S.get_reagent_amount("robustharvestnutriment") *1 ))
|
||||
|
||||
|
||||
//Fish Water is both an excellent fertilizer and waters
|
||||
if(S.has_reagent("fishwater", 1))
|
||||
adjustNutri(round(S.get_reagent_amount("fishwater") * 0.75))
|
||||
adjustWater(round(S.get_reagent_amount("fishwater") * 1))
|
||||
|
||||
// Antitoxin binds shit pretty well. So the tox goes significantly down
|
||||
if(S.has_reagent("charcoal", 1))
|
||||
adjustToxic(-round(S.get_reagent_amount("charcoal") * 2))
|
||||
@@ -657,6 +663,10 @@
|
||||
adjustHealth(round(S.get_reagent_amount("nutriment") * 0.5))
|
||||
adjustNutri(round(S.get_reagent_amount("nutriment") * 1))
|
||||
|
||||
if(S.has_reagent("plantmatter", 1))
|
||||
adjustHealth(round(S.get_reagent_amount("plantmatter") * 0.5))
|
||||
adjustNutri(round(S.get_reagent_amount("plantmatter") * 1))
|
||||
|
||||
// Compost for EVERYTHING
|
||||
if(S.has_reagent("virusfood", 1))
|
||||
adjustNutri(round(S.get_reagent_amount("virusfood") * 0.5))
|
||||
@@ -958,6 +968,30 @@
|
||||
var/mob/living/simple_animal/hostile/C = new chosen
|
||||
C.faction = list("plants")
|
||||
|
||||
///Diona Nymph Related Procs///
|
||||
/obj/machinery/hydroponics/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) //So nymphs can climb over top of trays.
|
||||
if(air_group || (height==0))
|
||||
return 1
|
||||
|
||||
if(istype(mover) && mover.checkpass(PASSTABLE))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/machinery/hydroponics/attack_animal(mob/living/user)
|
||||
if(istype(user, /mob/living/simple_animal/diona))
|
||||
if(weedlevel > 0)
|
||||
user.nutrition += weedlevel * 15
|
||||
adjustWeeds(-10)
|
||||
update_icon()
|
||||
visible_message("<span class='danger'>[user] begins rooting through [src], ripping out weeds and eating them noisily.</span>","<span class='danger'>You begin rooting through [src], ripping out weeds and eating them noisily.</span>")
|
||||
else if(nutrilevel < 10)
|
||||
user.nutrition -= ((10 - nutrilevel) * 5)
|
||||
adjustNutri(10)
|
||||
update_icon()
|
||||
visible_message("<span class='danger'>[user] secretes a trickle of green liquid from its tail, refilling [src]'s nutrient tray.</span>","<span class='danger'>You secrete a trickle of green liquid from your tail, refilling [src]'s nutrient tray.</span>")
|
||||
else
|
||||
..()
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/obj/machinery/hydroponics/soil //Not actually hydroponics at all! Honk!
|
||||
|
||||
@@ -1,257 +0,0 @@
|
||||
/datum/light_source
|
||||
var/atom/top_atom
|
||||
var/atom/source_atom
|
||||
|
||||
var/turf/source_turf
|
||||
var/light_power
|
||||
var/light_range
|
||||
var/light_color // string, decomposed by parse_light_color()
|
||||
|
||||
var/lum_r
|
||||
var/lum_g
|
||||
var/lum_b
|
||||
|
||||
var/tmp/applied_lum_r
|
||||
var/tmp/applied_lum_g
|
||||
var/tmp/applied_lum_b
|
||||
|
||||
var/list/effect_str
|
||||
var/list/effect_turf
|
||||
|
||||
var/applied
|
||||
|
||||
var/vis_update //Whetever we should smartly recalculate visibility. and then only update tiles that became (in) visible to us
|
||||
var/needs_update
|
||||
var/destroyed
|
||||
var/force_update
|
||||
|
||||
/datum/light_source/New(atom/owner, atom/top)
|
||||
source_atom = owner
|
||||
if(!source_atom.light_sources) source_atom.light_sources = list()
|
||||
source_atom.light_sources += src
|
||||
top_atom = top
|
||||
if(top_atom != source_atom)
|
||||
if(!top.light_sources) top.light_sources = list()
|
||||
top_atom.light_sources += src
|
||||
|
||||
source_turf = top_atom
|
||||
light_power = source_atom.light_power
|
||||
light_range = source_atom.light_range
|
||||
light_color = source_atom.light_color
|
||||
|
||||
parse_light_color()
|
||||
|
||||
effect_str = list()
|
||||
effect_turf = list()
|
||||
|
||||
update()
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/light_source/proc/destroy()
|
||||
destroyed = 1
|
||||
force_update()
|
||||
if(source_atom && source_atom.light_sources) source_atom.light_sources -= src
|
||||
if(top_atom && top_atom.light_sources) top_atom.light_sources -= src
|
||||
|
||||
/datum/light_source/proc/update(atom/new_top_atom)
|
||||
if(new_top_atom && new_top_atom != top_atom)
|
||||
if(top_atom != source_atom) top_atom.light_sources -= src
|
||||
top_atom = new_top_atom
|
||||
if(top_atom != source_atom)
|
||||
if(!top_atom.light_sources) top_atom.light_sources = list()
|
||||
top_atom.light_sources += src
|
||||
|
||||
if(!needs_update) //Incase we're already updating either way.
|
||||
lighting_update_lights += src
|
||||
needs_update = 1
|
||||
|
||||
/datum/light_source/proc/force_update()
|
||||
force_update = 1
|
||||
if(!needs_update) //Incase we're already updating either way.
|
||||
needs_update = 1
|
||||
lighting_update_lights += src
|
||||
|
||||
/datum/light_source/proc/vis_update()
|
||||
if(!needs_update)
|
||||
needs_update = 1
|
||||
lighting_update_lights += src
|
||||
|
||||
vis_update = 1
|
||||
|
||||
/datum/light_source/proc/check()
|
||||
if(!source_atom || !light_range || !light_power)
|
||||
destroy()
|
||||
return 1
|
||||
|
||||
if(!top_atom)
|
||||
top_atom = source_atom
|
||||
. = 1
|
||||
|
||||
if(istype(top_atom, /turf))
|
||||
if(source_turf != top_atom)
|
||||
source_turf = top_atom
|
||||
. = 1
|
||||
else if(top_atom.loc != source_turf)
|
||||
source_turf = top_atom.loc
|
||||
. = 1
|
||||
|
||||
if(source_atom.light_power != light_power)
|
||||
light_power = source_atom.light_power
|
||||
. = 1
|
||||
|
||||
if(source_atom.light_range != light_range)
|
||||
light_range = source_atom.light_range
|
||||
. = 1
|
||||
|
||||
if(light_range && light_power && !applied)
|
||||
. = 1
|
||||
|
||||
if(source_atom.light_color != light_color)
|
||||
light_color = source_atom.light_color
|
||||
parse_light_color()
|
||||
. = 1
|
||||
|
||||
/datum/light_source/proc/parse_light_color()
|
||||
if(light_color)
|
||||
lum_r = color2R(light_color) / 255
|
||||
lum_g = color2G(light_color) / 255
|
||||
lum_b = color2B(light_color) / 255
|
||||
else
|
||||
lum_r = 1
|
||||
lum_g = 1
|
||||
lum_b = 1
|
||||
|
||||
#if LIGHTING_FALLOFF == 1 //circular
|
||||
#define LUM_DISTANCE(swapvar, O, T) swapvar = (O.x - T.x)**2 + (O.y - T.y)**2 + LIGHTING_HEIGHT
|
||||
#if LIGHTING_LAMBERTIAN == 1
|
||||
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(sqrt(swapvar) / max(1,light_range))) * (1 / sqrt(swapvar + 1)))
|
||||
#else
|
||||
#define LUM_ATTENUATION(swapvar) swapvar = 1 - CLAMP01(sqrt(swapvar) / max(1,light_range))
|
||||
#endif
|
||||
#elif LIGHTING_FALLOFF == 2 //square
|
||||
#define LUM_DISTANCE(swapvar, O, T) swapvar = abs(O.x - T.x) + abs(O.y - T.y) + LIGHTING_HEIGHT
|
||||
#if LIGHTING_LAMBERTIAN == 1
|
||||
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01((1 - CLAMP01(swapvar / max(1,light_range))) * (1 / sqrt(swapvar**2 + 1)))
|
||||
#else
|
||||
#define LUM_ATTENUATION(swapvar) swapvar = CLAMP01(swapvar / max(1,light_range))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define LUM_FALLOFF(swapvar, O, T) \
|
||||
LUM_DISTANCE(swapvar, O, T); \
|
||||
LUM_ATTENUATION(swapvar);
|
||||
|
||||
/datum/light_source/proc/apply_lum()
|
||||
applied = 1
|
||||
|
||||
// Cache the applied lum counts.
|
||||
applied_lum_r = lum_r
|
||||
applied_lum_g = lum_g
|
||||
applied_lum_b = lum_b
|
||||
|
||||
if(istype(source_turf))
|
||||
FOR_DVIEW(var/turf/T, light_range, source_turf, INVISIBILITY_LIGHTING)
|
||||
if(T.lighting_overlay)
|
||||
var/strength
|
||||
LUM_FALLOFF(strength, T, source_turf)
|
||||
strength *= light_power
|
||||
|
||||
if(!strength) //Don't add turfs that aren't affected to the affected turfs.
|
||||
continue
|
||||
|
||||
strength = round(strength, LIGHTING_ROUND_VALUE) //Screw sinking points.
|
||||
|
||||
effect_str += strength
|
||||
|
||||
T.lighting_overlay.update_lumcount(
|
||||
lum_r * strength,
|
||||
lum_g * strength,
|
||||
lum_b * strength
|
||||
)
|
||||
|
||||
else
|
||||
effect_str += 0
|
||||
|
||||
if(!T.affecting_lights)
|
||||
T.affecting_lights = list()
|
||||
|
||||
T.affecting_lights += src
|
||||
effect_turf += T
|
||||
END_FOR_DVIEW
|
||||
|
||||
/datum/light_source/proc/remove_lum()
|
||||
applied = 0
|
||||
var/i = 1
|
||||
for(var/turf/T in effect_turf)
|
||||
if(T.affecting_lights)
|
||||
T.affecting_lights -= src
|
||||
|
||||
if(T.lighting_overlay)
|
||||
var/str = effect_str[i]
|
||||
T.lighting_overlay.update_lumcount(-str * applied_lum_r, -str * applied_lum_g, -str * applied_lum_b)
|
||||
|
||||
i++
|
||||
|
||||
effect_str.Cut()
|
||||
effect_turf.Cut()
|
||||
|
||||
/datum/light_source/proc/forget_turf(turf/T)
|
||||
var/idx = effect_turf.Find(T)
|
||||
effect_turf.Cut(idx, idx + 1)
|
||||
effect_str.Cut(idx, idx + 1)
|
||||
|
||||
//Smartly updates the lighting, only removes lum from and adds lum to turfs that actually got changed.
|
||||
//This is for lights that need to reconsider due to nearby opacity changes.
|
||||
//Stupid dumb copy pasta because BYOND and speed.
|
||||
/datum/light_source/proc/smart_vis_update()
|
||||
var/list/view[0]
|
||||
FOR_DVIEW(var/turf/T, light_range, source_turf, INVISIBILITY_LIGHTING)
|
||||
view += T //Filter out turfs.
|
||||
END_FOR_DVIEW
|
||||
//This is the part where we calculate new turfs (if any)
|
||||
var/list/new_turfs = view - effect_turf //This will result with all the tiles that are added.
|
||||
for(var/turf/T in new_turfs)
|
||||
if(T.lighting_overlay)
|
||||
LUM_FALLOFF(., T, source_turf)
|
||||
. *= light_power
|
||||
|
||||
if(!.) //Don't add turfs that aren't affected to the affected turfs.
|
||||
continue
|
||||
|
||||
. = round(., LIGHTING_ROUND_VALUE)
|
||||
|
||||
effect_str += .
|
||||
|
||||
T.lighting_overlay.update_lumcount(
|
||||
lum_r * .,
|
||||
lum_g * .,
|
||||
lum_b * .
|
||||
)
|
||||
|
||||
else
|
||||
effect_str += 0
|
||||
|
||||
if(!T.affecting_lights)
|
||||
T.affecting_lights = list()
|
||||
|
||||
T.affecting_lights += src
|
||||
effect_turf += T
|
||||
|
||||
var/list/old_turfs = effect_turf - view
|
||||
for(var/turf/T in old_turfs)
|
||||
//Insert not-so-huge copy paste from remove_lum().
|
||||
var/idx = effect_turf.Find(T) //Get the index, luckily Find() is cheap in small lists like this. (with small I mean under a couple thousand len)
|
||||
if(T.affecting_lights)
|
||||
T.affecting_lights -= src
|
||||
|
||||
if(T.lighting_overlay)
|
||||
var/str = effect_str[idx]
|
||||
T.lighting_overlay.update_lumcount(-str * lum_r, -str * lum_g, -str * lum_b)
|
||||
|
||||
effect_turf.Cut(idx, idx + 1)
|
||||
effect_str.Cut(idx, idx + 1)
|
||||
|
||||
#undef LUM_FALLOFF
|
||||
#undef LUM_DISTANCE
|
||||
#undef LUM_ATTENUATION
|
||||
@@ -0,0 +1,9 @@
|
||||
/area
|
||||
luminosity = TRUE
|
||||
var/dynamic_lighting = TRUE
|
||||
|
||||
/area/New()
|
||||
. = ..()
|
||||
|
||||
if(dynamic_lighting)
|
||||
luminosity = FALSE
|
||||
@@ -1,19 +1,30 @@
|
||||
/atom
|
||||
var/light_power = 1 // intensity of the light
|
||||
var/light_range = 0 // range in tiles of the light
|
||||
var/light_color // RGB string representing the colour of the light
|
||||
var/light_color // Hexadecimal RGB string representing the colour of the light
|
||||
|
||||
var/datum/light_source/light
|
||||
var/list/light_sources
|
||||
|
||||
/atom/proc/set_light(l_range, l_power, l_color)
|
||||
if(l_power != null) light_power = l_power
|
||||
if(l_range != null) light_range = l_range
|
||||
if(l_color != null) light_color = l_color
|
||||
// Nonsensical value for l_color default, so we can detect if it gets set to null.
|
||||
#define NONSENSICAL_VALUE -99999
|
||||
/atom/proc/set_light(l_range, l_power, l_color = NONSENSICAL_VALUE)
|
||||
if(l_power != null)
|
||||
light_power = l_power
|
||||
|
||||
if(l_range != null)
|
||||
light_range = l_range
|
||||
|
||||
if(l_color != NONSENSICAL_VALUE)
|
||||
light_color = l_color
|
||||
|
||||
update_light()
|
||||
|
||||
#undef NONSENSICAL_VALUE
|
||||
|
||||
/atom/proc/update_light()
|
||||
set waitfor = FALSE
|
||||
|
||||
if(!light_power || !light_range)
|
||||
if(light)
|
||||
light.destroy()
|
||||
@@ -31,9 +42,14 @@
|
||||
|
||||
/atom/New()
|
||||
. = ..()
|
||||
|
||||
if(light_power && light_range)
|
||||
update_light()
|
||||
|
||||
if(opacity && isturf(loc))
|
||||
var/turf/T = loc
|
||||
T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guranteed to be on afterwards anyways.
|
||||
|
||||
/atom/Destroy()
|
||||
if(light)
|
||||
light.destroy()
|
||||
@@ -62,11 +78,22 @@
|
||||
new_loc.reconsider_lights()
|
||||
|
||||
/atom/proc/set_opacity(new_opacity)
|
||||
var/old_opacity = opacity
|
||||
if(new_opacity == opacity)
|
||||
return
|
||||
|
||||
opacity = new_opacity
|
||||
var/turf/T = loc
|
||||
if(old_opacity != new_opacity && istype(T))
|
||||
if(!isturf(T))
|
||||
return
|
||||
|
||||
if(new_opacity == TRUE)
|
||||
T.has_opaque_atom = TRUE
|
||||
T.reconsider_lights()
|
||||
else
|
||||
var/old_has_opaque_atom = T.has_opaque_atom
|
||||
T.recalc_atom_opacity()
|
||||
if(old_has_opaque_atom != T.has_opaque_atom)
|
||||
T.reconsider_lights()
|
||||
|
||||
/obj/item/equipped()
|
||||
. = ..()
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
/var/list/datum/lighting_corner/all_lighting_corners = list()
|
||||
/var/datum/lighting_corner/dummy/dummy_lighting_corner = new
|
||||
// Because we can control each corner of every lighting overlay.
|
||||
// And corners get shared between multiple turfs (unless you're on the corners of the map, then 1 corner doesn't).
|
||||
// For the record: these should never ever ever be deleted, even if the turf doesn't have dynamic lighting.
|
||||
|
||||
// This list is what the code that assigns corners listens to, the order in this list is the order in which corners are added to the /turf/corners list.
|
||||
/var/list/LIGHTING_CORNER_DIAGONAL = list(NORTHEAST, SOUTHEAST, SOUTHWEST, NORTHWEST)
|
||||
|
||||
/datum/lighting_corner
|
||||
var/list/turf/masters = list()
|
||||
var/list/datum/light_source/affecting = list() // Light sources affecting us.
|
||||
var/active = FALSE // TRUE if one of our masters has dynamic lighting.
|
||||
|
||||
var/x = 0
|
||||
var/y = 0
|
||||
var/z = 0
|
||||
|
||||
var/lum_r = 0
|
||||
var/lum_g = 0
|
||||
var/lum_b = 0
|
||||
|
||||
var/needs_update = FALSE
|
||||
|
||||
var/cache_r = LIGHTING_SOFT_THRESHOLD
|
||||
var/cache_g = LIGHTING_SOFT_THRESHOLD
|
||||
var/cache_b = LIGHTING_SOFT_THRESHOLD
|
||||
var/cache_mx = 0
|
||||
|
||||
var/update_gen = 0
|
||||
|
||||
/datum/lighting_corner/New(var/turf/new_turf, var/diagonal)
|
||||
. = ..()
|
||||
|
||||
all_lighting_corners += src
|
||||
|
||||
masters[new_turf] = turn(diagonal, 180)
|
||||
z = new_turf.z
|
||||
|
||||
var/vertical = diagonal & ~(diagonal - 1) // The horizontal directions (4 and 8) are bigger than the vertical ones (1 and 2), so we can reliably say the lsb is the horizontal direction.
|
||||
var/horizontal = diagonal & ~vertical // Now that we know the horizontal one we can get the vertical one.
|
||||
|
||||
x = new_turf.x + (horizontal == EAST ? 0.5 : -0.5)
|
||||
y = new_turf.y + (vertical == NORTH ? 0.5 : -0.5)
|
||||
|
||||
// My initial plan was to make this loop through a list of all the dirs (horizontal, vertical, diagonal).
|
||||
// Issue being that the only way I could think of doing it was very messy, slow and honestly overengineered.
|
||||
// So we'll have this hardcode instead.
|
||||
var/turf/T
|
||||
var/i
|
||||
|
||||
// Diagonal one is easy.
|
||||
T = get_step(new_turf, diagonal)
|
||||
if (T) // In case we're on the map's border.
|
||||
if (!T.corners)
|
||||
T.corners = list(null, null, null, null)
|
||||
|
||||
masters[T] = diagonal
|
||||
i = LIGHTING_CORNER_DIAGONAL.Find(turn(diagonal, 180))
|
||||
T.corners[i] = src
|
||||
|
||||
// Now the horizontal one.
|
||||
T = get_step(new_turf, horizontal)
|
||||
if (T) // Ditto.
|
||||
if (!T.corners)
|
||||
T.corners = list(null, null, null, null)
|
||||
|
||||
masters[T] = ((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH) // Get the dir based on coordinates.
|
||||
i = LIGHTING_CORNER_DIAGONAL.Find(turn(masters[T], 180))
|
||||
T.corners[i] = src
|
||||
|
||||
// And finally the vertical one.
|
||||
T = get_step(new_turf, vertical)
|
||||
if (T)
|
||||
if (!T.corners)
|
||||
T.corners = list(null, null, null, null)
|
||||
|
||||
masters[T] = ((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH) // Get the dir based on coordinates.
|
||||
i = LIGHTING_CORNER_DIAGONAL.Find(turn(masters[T], 180))
|
||||
T.corners[i] = src
|
||||
|
||||
update_active()
|
||||
|
||||
/datum/lighting_corner/proc/update_active()
|
||||
active = FALSE
|
||||
for (var/turf/T in masters)
|
||||
if (T.lighting_overlay)
|
||||
active = TRUE
|
||||
|
||||
// God that was a mess, now to do the rest of the corner code! Hooray!
|
||||
/datum/lighting_corner/proc/update_lumcount(var/delta_r, var/delta_g, var/delta_b)
|
||||
lum_r += delta_r
|
||||
lum_g += delta_g
|
||||
lum_b += delta_b
|
||||
|
||||
if (!needs_update)
|
||||
needs_update = TRUE
|
||||
lighting_update_corners += src
|
||||
|
||||
/datum/lighting_corner/proc/update_overlays()
|
||||
|
||||
// Cache these values a head of time so 4 individual lighting overlays don't all calculate them individually.
|
||||
var/mx = max(lum_r, lum_g, lum_b) // Scale it so 1 is the strongest lum, if it is above 1.
|
||||
. = 1 // factor
|
||||
if (mx > 1)
|
||||
. = 1 / mx
|
||||
|
||||
else if (mx < LIGHTING_SOFT_THRESHOLD)
|
||||
. = 0 // 0 means soft lighting.
|
||||
|
||||
cache_r = lum_r * . || LIGHTING_SOFT_THRESHOLD
|
||||
cache_g = lum_g * . || LIGHTING_SOFT_THRESHOLD
|
||||
cache_b = lum_b * . || LIGHTING_SOFT_THRESHOLD
|
||||
cache_mx = mx
|
||||
|
||||
for (var/TT in masters)
|
||||
var/turf/T = TT
|
||||
if (T.lighting_overlay)
|
||||
if (!T.lighting_overlay.needs_update)
|
||||
T.lighting_overlay.needs_update = TRUE
|
||||
lighting_update_overlays += T.lighting_overlay
|
||||
|
||||
|
||||
/datum/lighting_corner/dummy/New()
|
||||
return
|
||||
@@ -1,3 +1,4 @@
|
||||
var/list/all_lighting_overlays = list() // Global list of lighting overlays.
|
||||
/atom/movable/lighting_overlay
|
||||
name = ""
|
||||
mouse_opacity = 0
|
||||
@@ -6,90 +7,75 @@
|
||||
icon = LIGHTING_ICON
|
||||
layer = LIGHTING_LAYER
|
||||
invisibility = INVISIBILITY_LIGHTING
|
||||
color = "#000000"
|
||||
color = LIGHTING_BASE_MATRIX
|
||||
icon_state = "light1"
|
||||
auto_init = 0 // doesn't need special init
|
||||
blend_mode = BLEND_MULTIPLY
|
||||
|
||||
var/lum_r
|
||||
var/lum_g
|
||||
var/lum_b
|
||||
var/lum_r = 0
|
||||
var/lum_g = 0
|
||||
var/lum_b = 0
|
||||
|
||||
var/needs_update
|
||||
var/needs_update = FALSE
|
||||
|
||||
/atom/movable/lighting_overlay/New()
|
||||
/atom/movable/lighting_overlay/New(var/atom/loc, var/no_update = FALSE)
|
||||
. = ..()
|
||||
verbs.Cut()
|
||||
global.all_lighting_overlays += src
|
||||
|
||||
var/turf/T = loc //If this runtimes atleast we'll know what's creating overlays outside of turfs.
|
||||
T.lighting_overlay = src
|
||||
T.luminosity = 0
|
||||
|
||||
/atom/movable/lighting_overlay/proc/get_clamped_lum(var/minlum = 0, var/maxlum = 1)
|
||||
var/lum = max(lum_r, lum_g, lum_b)
|
||||
if(lum <= minlum)
|
||||
return 0
|
||||
else if(lum >= maxlum)
|
||||
return 1
|
||||
else
|
||||
return (lum - minlum) / (maxlum - minlum)
|
||||
|
||||
/atom/movable/lighting_overlay/proc/update_lumcount(delta_r, delta_g, delta_b)
|
||||
if(!delta_r && !delta_g && !delta_b) //Nothing is being changed all together.
|
||||
if(no_update)
|
||||
return
|
||||
|
||||
var/should_update = 0
|
||||
|
||||
if(!needs_update) //If this isn't true, we're already updating anyways.
|
||||
if(max(lum_r, lum_g, lum_b) < 1) //Any change that could happen WILL change appearance.
|
||||
should_update = 1
|
||||
|
||||
else if(max(lum_r + delta_r, lum_g + delta_g, lum_b + delta_b) < 1) //The change would bring us under 1 max lum, again, guaranteed to change appearance.
|
||||
should_update = 1
|
||||
|
||||
else //We need to make sure that the colour ratios won't change in this code block.
|
||||
var/mx1 = max(lum_r, lum_g, lum_b)
|
||||
var/mx2 = max(lum_r + delta_r, lum_g + delta_g, lum_b + delta_b)
|
||||
|
||||
if(lum_r / mx1 != (lum_r + delta_r) / mx2 || lum_g / mx1 != (lum_g + delta_g) / mx2 || lum_b / mx1 != (lum_b + delta_b) / mx2) //Stuff would change.
|
||||
should_update = 1
|
||||
|
||||
lum_r = max(lum_r + delta_r, 0) //Lum shouldn't drop below 1
|
||||
lum_g = max(lum_g + delta_g, 0)
|
||||
lum_b = max(lum_b + delta_b, 0)
|
||||
|
||||
if(!needs_update && should_update)
|
||||
needs_update = 1
|
||||
lighting_update_overlays += src
|
||||
update_overlay()
|
||||
|
||||
/atom/movable/lighting_overlay/proc/update_overlay()
|
||||
set waitfor = FALSE
|
||||
var/turf/T = loc
|
||||
|
||||
if(istype(T)) //Incase we're not on a turf, pool ourselves, something happened.
|
||||
if(lum_r == lum_g && lum_r == lum_b) //greyscale
|
||||
blend_mode = BLEND_OVERLAY
|
||||
if(lum_r <= 0)
|
||||
T.luminosity = 0
|
||||
color = "#000000"
|
||||
alpha = 255
|
||||
else
|
||||
T.luminosity = 1
|
||||
color = "#000000"
|
||||
alpha = (1 - min(lum_r, 1)) * 255
|
||||
if(!istype(T))
|
||||
if(loc)
|
||||
log_debug("A lighting overlay realised its loc was NOT a turf (actual loc: [loc][loc ? ", " + loc.type : "null"]) in update_overlay() and got qdel'ed!")
|
||||
else
|
||||
alpha = 255
|
||||
var/mx = max(lum_r, lum_g, lum_b)
|
||||
. = 1 // factor
|
||||
if(mx > 1)
|
||||
. = 1/mx
|
||||
blend_mode = BLEND_MULTIPLY
|
||||
color = rgb(lum_r * 255 * ., lum_g * 255 * ., lum_b * 255 * .)
|
||||
if(color != "#000000")
|
||||
T.luminosity = 1
|
||||
else //No light, set the turf's luminosity to 0 to remove it from view()
|
||||
T.luminosity = 0
|
||||
else
|
||||
//warning("A lighting overlay realised its loc was NOT a turf (actual loc: [loc][loc ? ", " + loc.type : "null"]) in update_overlay() and got qdel'ed!") //fucking bullshit bugs means this spams when shuttles move, feel free to fix
|
||||
log_debug("A lighting overlay realised its loc was NOT a turf (actual loc: [loc][loc ? ", " + loc.type : "null"]) in update_overlay() and got qdel'ed!")
|
||||
log_debug("A lighting overlay realised it was in nullspace in update_overlay() and got pooled!")
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
// To the future coder who sees this and thinks
|
||||
// "Why didn't he just use a loop?"
|
||||
// Well my man, it's because the loop performed like shit.
|
||||
// And there's no way to improve it because
|
||||
// without a loop you can make the list all at once which is the fastest you're gonna get.
|
||||
// Oh it's also shorter line wise.
|
||||
// Including with these comments.
|
||||
|
||||
// See LIGHTING_CORNER_DIAGONAL in lighting_corner.dm for why these values are what they are.
|
||||
// No I seriously cannot think of a more efficient method, fuck off Comic.
|
||||
var/datum/lighting_corner/cr = T.corners[3] || dummy_lighting_corner
|
||||
var/datum/lighting_corner/cg = T.corners[2] || dummy_lighting_corner
|
||||
var/datum/lighting_corner/cb = T.corners[4] || dummy_lighting_corner
|
||||
var/datum/lighting_corner/ca = T.corners[1] || dummy_lighting_corner
|
||||
|
||||
var/max = max(cr.cache_mx, cg.cache_mx, cb.cache_mx, ca.cache_mx)
|
||||
|
||||
var/list/new_matrix = list(
|
||||
cr.cache_r, cr.cache_g, cr.cache_b, 0,
|
||||
cg.cache_r, cg.cache_g, cg.cache_b, 0,
|
||||
cb.cache_r, cb.cache_g, cb.cache_b, 0,
|
||||
ca.cache_r, ca.cache_g, ca.cache_b, 0,
|
||||
0, 0, 0, 1
|
||||
)
|
||||
var/lum = max > LIGHTING_SOFT_THRESHOLD
|
||||
|
||||
if(lum)
|
||||
luminosity = 1
|
||||
animate(src, color = new_matrix, time = 5)
|
||||
else
|
||||
animate(src, color = new_matrix, time = 5)
|
||||
animate(luminosity = 0, time = 0)
|
||||
|
||||
|
||||
|
||||
/atom/movable/lighting_overlay/singularity_act()
|
||||
return
|
||||
@@ -98,10 +84,13 @@
|
||||
return
|
||||
|
||||
/atom/movable/lighting_overlay/Destroy()
|
||||
lighting_update_overlays -= src
|
||||
global.all_lighting_overlays -= src
|
||||
global.lighting_update_overlays -= src
|
||||
global.lighting_update_overlays_old -= src
|
||||
|
||||
var/turf/T = loc
|
||||
if(istype(T))
|
||||
T.lighting_overlay = null
|
||||
T.luminosity = 1
|
||||
|
||||
return ..()
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/datum/controller/process/lighting
|
||||
var/last_light_count = 0
|
||||
var/last_overlay_count = 0
|
||||
|
||||
/datum/controller/process/lighting/doWork()
|
||||
var/list/lighting_update_lights_old = lighting_update_lights //We use a different list so any additions to the update lists during a delay from SCHECK don't cause things to be cut from the list without being updated.
|
||||
last_light_count = lighting_update_lights.len
|
||||
lighting_update_lights = null //Nulling it first because of http://www.byond.com/forum/?post=1854520
|
||||
lighting_update_lights = list()
|
||||
|
||||
for(var/datum/light_source/L in lighting_update_lights_old)
|
||||
if(L.destroyed || L.check() || L.force_update)
|
||||
L.remove_lum()
|
||||
if(!L.destroyed)
|
||||
L.apply_lum()
|
||||
|
||||
else if(L.vis_update) //We smartly update only tiles that became (in) visible to use.
|
||||
L.smart_vis_update()
|
||||
|
||||
L.vis_update = 0
|
||||
L.force_update = 0
|
||||
L.needs_update = 0
|
||||
|
||||
SCHECK
|
||||
|
||||
var/list/lighting_update_overlays_old = lighting_update_overlays //Same as above.
|
||||
last_overlay_count = lighting_update_overlays.len
|
||||
lighting_update_overlays = null //Same as above
|
||||
lighting_update_overlays = list()
|
||||
|
||||
for(var/atom/movable/lighting_overlay/O in lighting_update_overlays_old)
|
||||
O.update_overlay()
|
||||
O.needs_update = 0
|
||||
|
||||
SCHECK
|
||||
@@ -0,0 +1,16 @@
|
||||
/proc/create_all_lighting_overlays()
|
||||
for(var/zlevel = 1 to world.maxz)
|
||||
create_lighting_overlays_zlevel(zlevel)
|
||||
|
||||
/proc/create_lighting_overlays_zlevel(var/zlevel)
|
||||
ASSERT(zlevel)
|
||||
|
||||
for(var/turf/T in block(locate(1, 1, zlevel), locate(world.maxx, world.maxy, zlevel)))
|
||||
if(!T.dynamic_lighting)
|
||||
continue
|
||||
|
||||
var/area/A = T.loc
|
||||
if(!A.dynamic_lighting)
|
||||
continue
|
||||
|
||||
new /atom/movable/lighting_overlay(T, TRUE)
|
||||
@@ -0,0 +1,283 @@
|
||||
// This is where the fun begins.
|
||||
// These are the main datums that emit light.
|
||||
|
||||
/datum/light_source
|
||||
var/atom/top_atom // The atom we're emitting light from(for example a mob if we're from a flashlight that's being held).
|
||||
var/atom/source_atom // The atom that we belong to.
|
||||
|
||||
var/turf/source_turf // The turf under the above.
|
||||
var/light_power // Intensity of the emitter light.
|
||||
var/light_range // The range of the emitted light.
|
||||
var/light_color // The colour of the light, string, decomposed by parse_light_color()
|
||||
|
||||
// Variables for keeping track of the colour.
|
||||
var/lum_r
|
||||
var/lum_g
|
||||
var/lum_b
|
||||
|
||||
// The lumcount values used to apply the light.
|
||||
var/tmp/applied_lum_r
|
||||
var/tmp/applied_lum_g
|
||||
var/tmp/applied_lum_b
|
||||
|
||||
var/list/datum/lighting_corner/effect_str // List used to store how much we're affecting corners.
|
||||
var/list/turf/affecting_turfs
|
||||
|
||||
var/applied = FALSE // Whether we have applied our light yet or not.
|
||||
|
||||
var/vis_update // Whether we should smartly recalculate visibility. and then only update tiles that became(in)visible to us.
|
||||
var/needs_update // Whether we are queued for an update.
|
||||
var/destroyed // Whether we are destroyed and need to stop emitting light.
|
||||
var/force_update
|
||||
|
||||
/datum/light_source/New(var/atom/owner, var/atom/top)
|
||||
source_atom = owner // Set our new owner.
|
||||
if(!source_atom.light_sources)
|
||||
source_atom.light_sources = list()
|
||||
|
||||
source_atom.light_sources += src // Add us to the lights of our owner.
|
||||
top_atom = top
|
||||
if(top_atom != source_atom)
|
||||
if(!top.light_sources)
|
||||
top.light_sources = list()
|
||||
|
||||
top_atom.light_sources += src
|
||||
|
||||
source_turf = top_atom
|
||||
light_power = source_atom.light_power
|
||||
light_range = source_atom.light_range
|
||||
light_color = source_atom.light_color
|
||||
|
||||
parse_light_color()
|
||||
|
||||
effect_str = list()
|
||||
affecting_turfs = list()
|
||||
|
||||
update()
|
||||
|
||||
return ..()
|
||||
|
||||
// Kill ourselves.
|
||||
/datum/light_source/proc/destroy()
|
||||
destroyed = TRUE
|
||||
force_update()
|
||||
if(source_atom)
|
||||
source_atom.light_sources -= src
|
||||
|
||||
if(top_atom)
|
||||
top_atom.light_sources -= src
|
||||
|
||||
// Call it dirty, I don't care.
|
||||
// This is here so there's no performance loss on non-instant updates from the fact that the engine can also do instant updates.
|
||||
// If you're wondering what's with the "BYOND" argument: BYOND won't let me have a() macro that has no arguments :|.
|
||||
#define effect_update(BYOND) \
|
||||
if(!needs_update) \
|
||||
{ \
|
||||
lighting_update_lights += src; \
|
||||
needs_update = TRUE; \
|
||||
}
|
||||
|
||||
// This proc will cause the light source to update the top atom, and add itself to the update queue.
|
||||
/datum/light_source/proc/update(var/atom/new_top_atom)
|
||||
// This top atom is different.
|
||||
if(new_top_atom && new_top_atom != top_atom)
|
||||
if(top_atom != source_atom) // Remove ourselves from the light sources of that top atom.
|
||||
top_atom.light_sources -= src
|
||||
|
||||
top_atom = new_top_atom
|
||||
|
||||
if(top_atom != source_atom)
|
||||
if(!top_atom.light_sources)
|
||||
top_atom.light_sources = list()
|
||||
|
||||
top_atom.light_sources += src // Add ourselves to the light sources of our new top atom.
|
||||
|
||||
effect_update(null)
|
||||
|
||||
// Will force an update without checking if it's actually needed.
|
||||
/datum/light_source/proc/force_update()
|
||||
force_update = 1
|
||||
|
||||
effect_update(null)
|
||||
|
||||
// Will cause the light source to recalculate turfs that were removed or added to visibility only.
|
||||
/datum/light_source/proc/vis_update()
|
||||
vis_update = 1
|
||||
|
||||
effect_update(null)
|
||||
|
||||
// Will check if we actually need to update, and update any variables that may need to be updated.
|
||||
/datum/light_source/proc/check()
|
||||
if(!source_atom || !light_range || !light_power)
|
||||
destroy()
|
||||
return 1
|
||||
|
||||
if(!top_atom)
|
||||
top_atom = source_atom
|
||||
. = 1
|
||||
|
||||
if(isturf(top_atom))
|
||||
if(source_turf != top_atom)
|
||||
source_turf = top_atom
|
||||
. = 1
|
||||
else if(top_atom.loc != source_turf)
|
||||
source_turf = top_atom.loc
|
||||
. = 1
|
||||
|
||||
if(source_atom.light_power != light_power)
|
||||
light_power = source_atom.light_power
|
||||
. = 1
|
||||
|
||||
if(source_atom.light_range != light_range)
|
||||
light_range = source_atom.light_range
|
||||
. = 1
|
||||
|
||||
if(light_range && light_power && !applied)
|
||||
. = 1
|
||||
|
||||
if(source_atom.light_color != light_color)
|
||||
light_color = source_atom.light_color
|
||||
parse_light_color()
|
||||
. = 1
|
||||
|
||||
// Decompile the hexadecimal colour into lumcounts of each perspective.
|
||||
/datum/light_source/proc/parse_light_color()
|
||||
if(light_color)
|
||||
lum_r = GetRedPart (light_color) / 255
|
||||
lum_g = GetGreenPart(light_color) / 255
|
||||
lum_b = GetBluePart (light_color) / 255
|
||||
else
|
||||
lum_r = 1
|
||||
lum_g = 1
|
||||
lum_b = 1
|
||||
|
||||
// Macro that applies light to a new corner.
|
||||
// It is a macro in the interest of speed, yet not having to copy paste it.
|
||||
// If you're wondering what's with the backslashes, the backslashes cause BYOND to not automatically end the line.
|
||||
// As such this all gets counted as a single line.
|
||||
// The braces and semicolons are there to be able to do this on a single line.
|
||||
|
||||
#define APPLY_CORNER(C) \
|
||||
. = LUM_FALLOFF(C, source_turf); \
|
||||
\
|
||||
. *= light_power; \
|
||||
\
|
||||
effect_str[C] = .; \
|
||||
\
|
||||
C.update_lumcount \
|
||||
( \
|
||||
. * applied_lum_r, \
|
||||
. * applied_lum_g, \
|
||||
. * applied_lum_b \
|
||||
);
|
||||
|
||||
// I don't need to explain what this does, do I?
|
||||
#define REMOVE_CORNER(C) \
|
||||
. = -effect_str[C]; \
|
||||
C.update_lumcount \
|
||||
( \
|
||||
. * applied_lum_r, \
|
||||
. * applied_lum_g, \
|
||||
. * applied_lum_b \
|
||||
);
|
||||
|
||||
// This is the define used to calculate falloff.
|
||||
#define LUM_FALLOFF(C, T)(1 - CLAMP01(sqrt((C.x - T.x) ** 2 +(C.y - T.y) ** 2 + LIGHTING_HEIGHT) / max(1, light_range)))
|
||||
|
||||
/datum/light_source/proc/apply_lum()
|
||||
var/static/update_gen = 1
|
||||
applied = 1
|
||||
|
||||
// Keep track of the last applied lum values so that the lighting can be reversed
|
||||
applied_lum_r = lum_r
|
||||
applied_lum_g = lum_g
|
||||
applied_lum_b = lum_b
|
||||
|
||||
FOR_DVIEW(var/turf/T, light_range, source_turf, INVISIBILITY_LIGHTING)
|
||||
if(!T.lighting_corners_initialised)
|
||||
T.generate_missing_corners()
|
||||
|
||||
for(var/datum/lighting_corner/C in T.get_corners())
|
||||
if(C.update_gen == update_gen)
|
||||
continue
|
||||
|
||||
C.update_gen = update_gen
|
||||
C.affecting += src
|
||||
|
||||
if(!C.active)
|
||||
effect_str[C] = 0
|
||||
continue
|
||||
|
||||
APPLY_CORNER(C)
|
||||
|
||||
if(!T.affecting_lights)
|
||||
T.affecting_lights = list()
|
||||
|
||||
T.affecting_lights += src
|
||||
affecting_turfs += T
|
||||
|
||||
update_gen++
|
||||
|
||||
/datum/light_source/proc/remove_lum()
|
||||
applied = FALSE
|
||||
|
||||
for(var/turf/T in affecting_turfs)
|
||||
if(!T.affecting_lights)
|
||||
T.affecting_lights = list()
|
||||
else
|
||||
T.affecting_lights -= src
|
||||
|
||||
affecting_turfs.Cut()
|
||||
|
||||
for(var/datum/lighting_corner/C in effect_str)
|
||||
REMOVE_CORNER(C)
|
||||
|
||||
C.affecting -= src
|
||||
|
||||
effect_str.Cut()
|
||||
|
||||
/datum/light_source/proc/recalc_corner(var/datum/lighting_corner/C)
|
||||
if(effect_str.Find(C)) // Already have one.
|
||||
REMOVE_CORNER(C)
|
||||
|
||||
APPLY_CORNER(C)
|
||||
|
||||
/datum/light_source/proc/smart_vis_update()
|
||||
var/list/datum/lighting_corner/corners = list()
|
||||
var/list/turf/turfs = list()
|
||||
FOR_DVIEW(var/turf/T, light_range, source_turf, 0)
|
||||
if(!T.lighting_corners_initialised)
|
||||
T.generate_missing_corners()
|
||||
corners |= T.get_corners()
|
||||
turfs += T
|
||||
|
||||
var/list/L = turfs - affecting_turfs // New turfs, add us to the affecting lights of them.
|
||||
affecting_turfs += L
|
||||
for(var/turf/T in L)
|
||||
if(!T.affecting_lights)
|
||||
T.affecting_lights = list(src)
|
||||
else
|
||||
T.affecting_lights += src
|
||||
|
||||
L = affecting_turfs - turfs // Now-gone turfs, remove us from the affecting lights.
|
||||
affecting_turfs -= L
|
||||
for(var/turf/T in L)
|
||||
T.affecting_lights -= src
|
||||
|
||||
for(var/datum/lighting_corner/C in corners - effect_str) // New corners
|
||||
C.affecting += src
|
||||
if(!C.active)
|
||||
effect_str[C] = 0
|
||||
continue
|
||||
|
||||
APPLY_CORNER(C)
|
||||
|
||||
for(var/datum/lighting_corner/C in effect_str - corners) // Old, now gone, corners.
|
||||
REMOVE_CORNER(C)
|
||||
C.affecting -= src
|
||||
effect_str -= C
|
||||
|
||||
#undef effect_update
|
||||
#undef LUM_FALLOFF
|
||||
#undef REMOVE_CORNER
|
||||
#undef APPLY_CORNER
|
||||
@@ -1,25 +0,0 @@
|
||||
/var/list/lighting_update_lights = list()
|
||||
/var/list/lighting_update_overlays = list()
|
||||
|
||||
/area/var/lighting_use_dynamic = 1
|
||||
|
||||
// duplicates lots of code, but this proc needs to be as fast as possible.
|
||||
/proc/create_lighting_overlays(zlevel = 0)
|
||||
var/area/A
|
||||
if(zlevel == 0) // populate all zlevels
|
||||
for(var/turf/T in world)
|
||||
if(T.dynamic_lighting)
|
||||
A = T.loc
|
||||
if(A.lighting_use_dynamic)
|
||||
var/atom/movable/lighting_overlay/O = new(T)
|
||||
T.lighting_overlay = O
|
||||
|
||||
else
|
||||
for(var/x = 1; x <= world.maxx; x++)
|
||||
for(var/y = 1; y <= world.maxy; y++)
|
||||
var/turf/T = locate(x, y, zlevel)
|
||||
if(T.dynamic_lighting)
|
||||
A = T.loc
|
||||
if(A.lighting_use_dynamic)
|
||||
var/atom/movable/lighting_overlay/O = new(T)
|
||||
T.lighting_overlay = O
|
||||
@@ -1,26 +1,102 @@
|
||||
/turf
|
||||
var/list/affecting_lights
|
||||
var/atom/movable/lighting_overlay/lighting_overlay
|
||||
var/dynamic_lighting = TRUE
|
||||
luminosity = 1
|
||||
|
||||
var/tmp/lighting_corners_initialised = FALSE
|
||||
|
||||
var/tmp/list/datum/light_source/affecting_lights // List of light sources affecting this turf.
|
||||
var/tmp/atom/movable/lighting_overlay/lighting_overlay // Our lighting overlay.
|
||||
var/tmp/list/datum/lighting_corner/corners
|
||||
var/tmp/has_opaque_atom = FALSE // Not to be confused with opacity, this will be TRUE if there's any opaque atom on the tile.
|
||||
|
||||
/turf/New()
|
||||
. = ..()
|
||||
|
||||
if(opacity)
|
||||
has_opaque_atom = TRUE
|
||||
|
||||
// Causes any affecting light sources to be queued for a visibility update, for example a door got opened.
|
||||
/turf/proc/reconsider_lights()
|
||||
for(var/datum/light_source/L in affecting_lights)
|
||||
L.vis_update()
|
||||
|
||||
/turf/proc/lighting_clear_overlays()
|
||||
/turf/proc/lighting_clear_overlay()
|
||||
if(lighting_overlay)
|
||||
qdel(lighting_overlay)
|
||||
|
||||
/turf/proc/lighting_build_overlays()
|
||||
for(var/datum/lighting_corner/C in corners)
|
||||
C.update_active()
|
||||
|
||||
// Builds a lighting overlay for us, but only if our area is dynamic.
|
||||
/turf/proc/lighting_build_overlay()
|
||||
if(lighting_overlay)
|
||||
return
|
||||
|
||||
var/area/A = loc
|
||||
if(A.lighting_use_dynamic)
|
||||
var/atom/movable/lighting_overlay/O = new(src)
|
||||
lighting_overlay = O
|
||||
// forcibly refresh lighting on this tile
|
||||
// must make light forget tile or it wil remain
|
||||
// convinced that it is already lighting it
|
||||
for(var/datum/light_source/L in affecting_lights)
|
||||
L.forget_turf(src)
|
||||
L.vis_update()
|
||||
if(A.dynamic_lighting)
|
||||
if(!lighting_corners_initialised)
|
||||
generate_missing_corners()
|
||||
|
||||
new /atom/movable/lighting_overlay(src)
|
||||
|
||||
for(var/datum/lighting_corner/C in corners)
|
||||
if(!C.active) // We would activate the corner, calculate the lighting for it.
|
||||
for(var/L in C.affecting)
|
||||
var/datum/light_source/S = L
|
||||
S.recalc_corner(C)
|
||||
|
||||
C.active = TRUE
|
||||
|
||||
// Used to get a scaled lumcount.
|
||||
/turf/proc/get_lumcount(var/minlum = 0, var/maxlum = 1)
|
||||
if(!lighting_overlay)
|
||||
return 1
|
||||
|
||||
var/totallums = 0
|
||||
for(var/datum/lighting_corner/L in corners)
|
||||
totallums += max(L.lum_r, L.lum_g, L.lum_b)
|
||||
|
||||
totallums /= 4 // 4 corners, max channel selected, return the average
|
||||
|
||||
totallums =(totallums - minlum) /(maxlum - minlum)
|
||||
|
||||
return CLAMP01(totallums)
|
||||
|
||||
// Can't think of a good name, this proc will recalculate the has_opaque_atom variable.
|
||||
/turf/proc/recalc_atom_opacity()
|
||||
has_opaque_atom = FALSE
|
||||
for(var/atom/A in src.contents + src) // Loop through every movable atom on our tile PLUS ourselves (we matter too...)
|
||||
if(A.opacity)
|
||||
has_opaque_atom = TRUE
|
||||
|
||||
// If an opaque movable atom moves around we need to potentially update visibility.
|
||||
/turf/Entered(var/atom/movable/Obj, var/atom/OldLoc)
|
||||
. = ..()
|
||||
|
||||
if(Obj && Obj.opacity)
|
||||
has_opaque_atom = TRUE // Make sure to do this before reconsider_lights(), incase we're on instant updates. Guaranteed to be on in this case.
|
||||
reconsider_lights()
|
||||
|
||||
/turf/Exited(var/atom/movable/Obj, var/atom/newloc)
|
||||
. = ..()
|
||||
|
||||
if(Obj && Obj.opacity)
|
||||
recalc_atom_opacity() // Make sure to do this before reconsider_lights(), incase we're on instant updates.
|
||||
reconsider_lights()
|
||||
|
||||
/turf/proc/get_corners()
|
||||
if(has_opaque_atom)
|
||||
return null // Since this proc gets used in a for loop, null won't be looped though.
|
||||
|
||||
return corners
|
||||
|
||||
/turf/proc/generate_missing_corners()
|
||||
lighting_corners_initialised = TRUE
|
||||
if(!corners)
|
||||
corners = list(null, null, null, null)
|
||||
|
||||
for(var/i = 1 to 4)
|
||||
if(corners[i]) // Already have a corner on this direction.
|
||||
continue
|
||||
|
||||
corners[i] = new /datum/lighting_corner(src, LIGHTING_CORNER_DIAGONAL[i])
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#undef LIGHTING_INTERVAL
|
||||
|
||||
#undef LIGHTING_FALLOFF
|
||||
#undef LIGHTING_LAMBERTIAN
|
||||
#undef LIGHTING_HEIGHT
|
||||
|
||||
#undef LIGHTING_RESOLUTION
|
||||
#undef LIGHTING_LAYER
|
||||
#undef LIGHTING_ICON
|
||||
#undef LIGHTING_ICON
|
||||
|
||||
#undef LIGHTING_BASE_MATRIX
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
if(57 to 58)
|
||||
new /obj/item/toy/syndicateballoon(src)
|
||||
if(59 to 60)
|
||||
new /obj/item/weapon/gun/energy/kinetic_accelerator/hyper(src)
|
||||
new /obj/item/borg/upgrade/modkit/aoe/mobs(src)
|
||||
new /obj/item/clothing/suit/space(src)
|
||||
new /obj/item/clothing/head/helmet/space(src)
|
||||
if(61 to 62)
|
||||
|
||||
@@ -313,7 +313,7 @@
|
||||
anchored = 1.0
|
||||
var/obj/item/weapon/card/id/inserted_id
|
||||
var/list/prize_list = list(
|
||||
new /datum/data/mining_equipment("Stimpack", /obj/item/weapon/reagent_containers/hypospray/autoinjector/stimpack, 50),
|
||||
new /datum/data/mining_equipment("Stimpack", /obj/item/weapon/reagent_containers/hypospray/autoinjector/stimpack, 50),
|
||||
new /datum/data/mining_equipment("Teporone MediPen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/teporone, 50),
|
||||
new /datum/data/mining_equipment("MediPen Bundle", /obj/item/weapon/storage/box/autoinjector/utility, 200),
|
||||
new /datum/data/mining_equipment("Whiskey", /obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey, 100),
|
||||
@@ -324,10 +324,10 @@
|
||||
new /datum/data/mining_equipment("Advanced Scanner", /obj/item/device/t_scanner/adv_mining_scanner, 400),
|
||||
new /datum/data/mining_equipment("Hivelord Stabilizer", /obj/item/weapon/hivelordstabilizer, 400),
|
||||
new /datum/data/mining_equipment("Mining Drone", /obj/item/weapon/mining_drone_cube, 500),
|
||||
new /datum/data/mining_equipment("Drone Melee Upgrade", /obj/item/device/mine_bot_ugprade, 400),
|
||||
new /datum/data/mining_equipment("Drone Health Upgrade",/obj/item/device/mine_bot_ugprade/health, 400),
|
||||
new /datum/data/mining_equipment("Drone Ranged Upgrade",/obj/item/device/mine_bot_ugprade/cooldown, 600),
|
||||
new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/weapon/twohanded/required/mining_hammer, 750),
|
||||
new /datum/data/mining_equipment("Drone Melee Upgrade", /obj/item/device/mine_bot_upgrade, 400),
|
||||
new /datum/data/mining_equipment("Drone Health Upgrade",/obj/item/device/mine_bot_upgrade/health, 400),
|
||||
new /datum/data/mining_equipment("Drone Ranged Upgrade",/obj/item/device/mine_bot_upgrade/cooldown, 600),
|
||||
new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/weapon/twohanded/required/mining_hammer, 750),
|
||||
new /datum/data/mining_equipment("Drone AI Upgrade", /obj/item/slimepotion/sentience/mining, 1000),
|
||||
new /datum/data/mining_equipment("GAR mesons", /obj/item/clothing/glasses/meson/gar, 500),
|
||||
new /datum/data/mining_equipment("Brute First-Aid Kit", /obj/item/weapon/storage/firstaid/brute, 600),
|
||||
@@ -342,7 +342,14 @@
|
||||
new /datum/data/mining_equipment("Space Cash", /obj/item/weapon/spacecash/c1000, 2000),
|
||||
new /datum/data/mining_equipment("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000),
|
||||
new /datum/data/mining_equipment("Super Resonator", /obj/item/weapon/resonator/upgraded, 2500),
|
||||
new /datum/data/mining_equipment("Super Accelerator", /obj/item/weapon/gun/energy/kinetic_accelerator/super, 3000),
|
||||
new /datum/data/mining_equipment("KA White Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer, 100),
|
||||
new /datum/data/mining_equipment("KA Adjustable Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer/adjustable, 150),
|
||||
new /datum/data/mining_equipment("KA Super Chassis", /obj/item/borg/upgrade/modkit/chassis_mod, 250),
|
||||
new /datum/data/mining_equipment("KA Hyper Chassis", /obj/item/borg/upgrade/modkit/chassis_mod/orange, 300),
|
||||
new /datum/data/mining_equipment("KA Range Increase", /obj/item/borg/upgrade/modkit/range, 1000),
|
||||
new /datum/data/mining_equipment("KA Damage Increase", /obj/item/borg/upgrade/modkit/damage, 1000),
|
||||
new /datum/data/mining_equipment("KA Cooldown Decrease",/obj/item/borg/upgrade/modkit/cooldown, 1000),
|
||||
new /datum/data/mining_equipment("KA AoE Damage", /obj/item/borg/upgrade/modkit/aoe/mobs, 2000),
|
||||
new /datum/data/mining_equipment("Point Transfer Card", /obj/item/weapon/card/mining_point_card, 500),
|
||||
)
|
||||
|
||||
@@ -938,18 +945,18 @@
|
||||
|
||||
//Melee
|
||||
|
||||
/obj/item/device/mine_bot_ugprade
|
||||
/obj/item/device/mine_bot_upgrade
|
||||
name = "minebot melee upgrade"
|
||||
desc = "A minebot upgrade."
|
||||
icon_state = "door_electronics"
|
||||
icon = 'icons/obj/doors/door_assembly.dmi'
|
||||
|
||||
/obj/item/device/mine_bot_ugprade/afterattack(mob/living/simple_animal/hostile/mining_drone/M, mob/user, proximity)
|
||||
/obj/item/device/mine_bot_upgrade/afterattack(mob/living/simple_animal/hostile/mining_drone/M, mob/user, proximity)
|
||||
if(!istype(M) || !proximity)
|
||||
return
|
||||
upgrade_bot(M, user)
|
||||
|
||||
/obj/item/device/mine_bot_ugprade/proc/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user)
|
||||
/obj/item/device/mine_bot_upgrade/proc/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user)
|
||||
if(M.melee_damage_upper != initial(M.melee_damage_upper))
|
||||
to_chat(user, "[M] already has a combat upgrade installed!")
|
||||
return
|
||||
@@ -960,10 +967,10 @@
|
||||
|
||||
//Health
|
||||
|
||||
/obj/item/device/mine_bot_ugprade/health
|
||||
/obj/item/device/mine_bot_upgrade/health
|
||||
name = "minebot chassis upgrade"
|
||||
|
||||
/obj/item/device/mine_bot_ugprade/health/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user)
|
||||
/obj/item/device/mine_bot_upgrade/health/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user)
|
||||
if(M.maxHealth != initial(M.maxHealth))
|
||||
to_chat(user, "[M] already has a reinforced chassis!")
|
||||
return
|
||||
@@ -974,10 +981,10 @@
|
||||
|
||||
//Cooldown
|
||||
|
||||
/obj/item/device/mine_bot_ugprade/cooldown
|
||||
/obj/item/device/mine_bot_upgrade/cooldown
|
||||
name = "minebot cooldown upgrade"
|
||||
|
||||
/obj/item/device/mine_bot_ugprade/cooldown/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user)
|
||||
/obj/item/device/mine_bot_upgrade/cooldown/upgrade_bot(mob/living/simple_animal/hostile/mining_drone/M, mob/user)
|
||||
if(M.ranged_cooldown_time != initial(M.ranged_cooldown_time))
|
||||
to_chat(user, "[M] already has a decreased weapon cooldown!")
|
||||
return
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
/obj/structure/closet/crate/necropolis/dragon
|
||||
name = "dragon chest"
|
||||
|
||||
/obj/structure/closet/crate/necropolis/dragon/New()
|
||||
..()
|
||||
var/loot = rand(1,4)
|
||||
switch(loot)
|
||||
if(1)
|
||||
new /obj/item/weapon/melee/ghost_sword(src)
|
||||
if(2)
|
||||
new /obj/item/weapon/lava_staff(src)
|
||||
if(3)
|
||||
new /obj/item/weapon/spellbook/oneuse/sacredflame(src)
|
||||
new /obj/item/weapon/gun/magic/wand/fireball(src)
|
||||
if(4)
|
||||
new /obj/item/weapon/dragons_blood(src)
|
||||
|
||||
// Spectral Blade
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword
|
||||
name = "spectral blade"
|
||||
desc = "A rusted and dulled blade. It doesn't look like it'd do much damage. It glows weakly."
|
||||
icon_state = "spectral"
|
||||
item_state = "spectral"
|
||||
flags = CONDUCT
|
||||
sharp = 1
|
||||
edge = 1
|
||||
w_class = 4
|
||||
force = 1
|
||||
throwforce = 1
|
||||
hitsound = 'sound/effects/ghost2.ogg'
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "rended")
|
||||
var/summon_cooldown = 0
|
||||
var/list/mob/dead/observer/spirits
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/New()
|
||||
..()
|
||||
spirits = list()
|
||||
processing_objects.Add(src)
|
||||
poi_list |= src
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/Destroy()
|
||||
for(var/mob/dead/observer/G in spirits)
|
||||
G.invisibility = initial(G.invisibility)
|
||||
spirits.Cut()
|
||||
processing_objects.Remove(src)
|
||||
poi_list -= src
|
||||
. = ..()
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/attack_self(mob/user)
|
||||
if(summon_cooldown > world.time)
|
||||
to_chat(user, "You just recently called out for aid. You don't want to annoy the spirits.")
|
||||
return
|
||||
to_chat(user, "You call out for aid, attempting to summon spirits to your side.")
|
||||
|
||||
notify_ghosts("[user] is raising their [src], calling for your help!", enter_link="<a href=?src=[UID()];follow=1>(Click to help)</a>", source = user, action = NOTIFY_FOLLOW)
|
||||
|
||||
summon_cooldown = world.time + 600
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/Topic(href, href_list)
|
||||
if(href_list["follow"])
|
||||
var/mob/dead/observer/ghost = usr
|
||||
if(istype(ghost))
|
||||
ghost.ManualFollow(src)
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/process()
|
||||
ghost_check()
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/proc/ghost_check()
|
||||
var/ghost_counter = 0
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/contents = T.GetAllContents()
|
||||
var/mob/dead/observer/current_spirits = list()
|
||||
|
||||
for(var/mob/dead/observer/O in player_list)
|
||||
if(is_type_in_list(O.following, contents))
|
||||
ghost_counter++
|
||||
O.invisibility = 0
|
||||
current_spirits |= O
|
||||
|
||||
for(var/mob/dead/observer/G in spirits - current_spirits)
|
||||
G.invisibility = initial(G.invisibility)
|
||||
|
||||
spirits = current_spirits
|
||||
|
||||
return ghost_counter
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/attack(mob/living/target, mob/living/carbon/human/user)
|
||||
force = 0
|
||||
var/ghost_counter = ghost_check()
|
||||
|
||||
force = Clamp((ghost_counter * 4), 0, 75)
|
||||
user.visible_message("<span class='danger'>[user] strikes with the force of [ghost_counter] vengeful spirits!</span>")
|
||||
..()
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type)
|
||||
var/ghost_counter = ghost_check()
|
||||
final_block_chance += Clamp((ghost_counter * 5), 0, 75)
|
||||
owner.visible_message("<span class='danger'>[owner] is protected by a ring of [ghost_counter] ghosts!</span>")
|
||||
return ..()
|
||||
|
||||
// Blood
|
||||
|
||||
/obj/item/weapon/dragons_blood
|
||||
name = "bottle of dragons blood"
|
||||
desc = "You're not actually going to drink this, are you?"
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "vial"
|
||||
|
||||
/obj/item/weapon/dragons_blood/attack_self(mob/living/carbon/human/user)
|
||||
if(!istype(user))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/random = rand(1,3)
|
||||
|
||||
switch(random)
|
||||
if(1)
|
||||
to_chat(user, "<span class='danger'>Your flesh begins to melt! Miraculously, you seem fine otherwise.</span>")
|
||||
H.set_species("Skeleton")
|
||||
if(2)
|
||||
to_chat(user, "<span class='danger'>Power courses through you! You can now shift your form at will.")
|
||||
if(user.mind)
|
||||
var/obj/effect/proc_holder/spell/targeted/shapeshift/dragon/D = new
|
||||
user.mind.AddSpell(D)
|
||||
if(3)
|
||||
to_chat(user, "<span class='danger'>You feel like you could walk straight through lava now.</span>")
|
||||
H.weather_immunities |= "lava"
|
||||
|
||||
playsound(user.loc,'sound/items/drink.ogg', rand(10,50), 1)
|
||||
qdel(src)
|
||||
|
||||
/datum/disease/transformation/dragon
|
||||
name = "dragon transformation"
|
||||
cure_text = "nothing"
|
||||
cures = list("adminordrazine")
|
||||
agent = "dragon's blood"
|
||||
desc = "What do dragons have to do with Space Station 13?"
|
||||
stage_prob = 20
|
||||
severity = BIOHAZARD
|
||||
visibility_flags = 0
|
||||
stage1 = list("Your bones ache.")
|
||||
stage2 = list("Your skin feels scaley.")
|
||||
stage3 = list("<span class='danger'>You have an overwhelming urge to terrorize some peasants.</span>", "<span class='danger'>Your teeth feel sharper.</span>")
|
||||
stage4 = list("<span class='danger'>Your blood burns.</span>")
|
||||
stage5 = list("<span class='danger'>You're a fucking dragon. However, any previous allegiances you held still apply. It'd be incredibly rude to eat your still human friends for no reason.</span>")
|
||||
new_form = /mob/living/simple_animal/hostile/megafauna/dragon/lesser
|
||||
|
||||
//Lava Staff
|
||||
|
||||
/obj/item/weapon/lava_staff
|
||||
name = "staff of lava"
|
||||
desc = "The ability to fill the emergency shuttle with lava. What more could you want out of life?"
|
||||
icon_state = "staffofstorms"
|
||||
item_state = "staffofstorms"
|
||||
icon = 'icons/obj/guns/magic.dmi'
|
||||
slot_flags = SLOT_BACK
|
||||
item_state = "staffofstorms"
|
||||
w_class = 4
|
||||
force = 25
|
||||
damtype = BURN
|
||||
hitsound = 'sound/weapons/sear.ogg'
|
||||
burn_state = LAVA_PROOF | FIRE_PROOF
|
||||
unacidable = 1
|
||||
var/turf_type = /turf/unsimulated/floor/lava // /turf/simulated/floor/plating/lava/smooth once Lavaland turfs are added
|
||||
var/transform_string = "lava"
|
||||
var/reset_turf_type = /turf/simulated/floor/plating/airless/asteroid // /turf/simulated/floor/plating/asteroid/basalt once Lavaland turfs are added
|
||||
var/reset_string = "basalt"
|
||||
var/create_cooldown = 100
|
||||
var/create_delay = 30
|
||||
var/reset_cooldown = 50
|
||||
var/timer = 0
|
||||
var/banned_turfs
|
||||
|
||||
/obj/item/weapon/lava_staff/New()
|
||||
. = ..()
|
||||
banned_turfs = typecacheof(list(/turf/space/transit, /turf/unsimulated))
|
||||
|
||||
/obj/item/weapon/lava_staff/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
..()
|
||||
if(timer > world.time)
|
||||
return
|
||||
|
||||
if(is_type_in_typecache(target, banned_turfs))
|
||||
return
|
||||
|
||||
if(target in view(user.client.view, get_turf(user)))
|
||||
|
||||
var/turf/simulated/T = get_turf(target)
|
||||
if(!istype(T))
|
||||
return
|
||||
if(!istype(T, turf_type))
|
||||
var/obj/effect/overlay/temp/lavastaff/L = new /obj/effect/overlay/temp/lavastaff(T)
|
||||
L.alpha = 0
|
||||
animate(L, alpha = 255, time = create_delay)
|
||||
user.visible_message("<span class='danger'>[user] points [src] at [T]!</span>")
|
||||
timer = world.time + create_delay + 1
|
||||
if(do_after(user, create_delay, target = T))
|
||||
user.visible_message("<span class='danger'>[user] turns \the [T] into [transform_string]!</span>")
|
||||
message_admins("[key_name_admin(user)] fired the lava staff at [get_area(target)] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>).")
|
||||
log_game("[key_name(user)] fired the lava staff at [get_area(target)] ([T.x], [T.y], [T.z]).")
|
||||
T.ChangeTurf(turf_type)
|
||||
timer = world.time + create_cooldown
|
||||
qdel(L)
|
||||
else
|
||||
timer = world.time
|
||||
qdel(L)
|
||||
return
|
||||
else
|
||||
user.visible_message("<span class='danger'>[user] turns \the [T] into [reset_string]!</span>")
|
||||
T.ChangeTurf(reset_turf_type)
|
||||
timer = world.time + reset_cooldown
|
||||
playsound(T,'sound/magic/Fireball.ogg', 200, 1)
|
||||
|
||||
/obj/effect/overlay/temp/lavastaff
|
||||
icon_state = "lavastaff_warn"
|
||||
duration = 50
|
||||
@@ -0,0 +1,81 @@
|
||||
/obj/structure/closet/crate/necropolis/bubblegum
|
||||
name = "bubblegum chest"
|
||||
|
||||
/obj/structure/closet/crate/necropolis/bubblegum/New()
|
||||
..()
|
||||
var/loot = rand(1,3)
|
||||
switch(loot)
|
||||
if(1)
|
||||
new /obj/item/mayhem(src)
|
||||
if(2)
|
||||
new /obj/item/blood_contract(src)
|
||||
if(3)
|
||||
new /obj/item/weapon/gun/magic/staff/spellblade(src)
|
||||
|
||||
// Mayhem
|
||||
|
||||
/obj/item/mayhem
|
||||
name = "mayhem in a bottle"
|
||||
desc = "A magically infused bottle of blood, the scent of which will drive anyone nearby into a murderous frenzy."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "vial"
|
||||
|
||||
/obj/item/mayhem/attack_self(mob/user)
|
||||
for(var/mob/living/carbon/human/H in range(7,user))
|
||||
spawn()
|
||||
var/obj/effect/mine/pickup/bloodbath/B = new(H)
|
||||
B.mineEffect(H)
|
||||
to_chat(user, "<span class='notice'>You shatter the bottle!</span>")
|
||||
playsound(user.loc, 'sound/effects/Glassbr1.ogg', 100, 1)
|
||||
qdel(src)
|
||||
|
||||
// Blood Contract
|
||||
|
||||
/obj/item/blood_contract
|
||||
name = "blood contract"
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "scroll2"
|
||||
color = "#FF0000"
|
||||
desc = "Mark your target for death."
|
||||
var/used = FALSE
|
||||
|
||||
/obj/item/blood_contract/attack_self(mob/user)
|
||||
if(used)
|
||||
return
|
||||
|
||||
used = TRUE
|
||||
var/choice = input(user,"Who do you want dead?","Choose Your Victim") as null|anything in player_list
|
||||
|
||||
if(!choice)
|
||||
used = FALSE
|
||||
return
|
||||
else if(!isliving(choice))
|
||||
to_chat(user, "[choice] is already dead!")
|
||||
used = FALSE
|
||||
return
|
||||
else if(choice == user)
|
||||
to_chat(user, "You feel like writing your own name into a cursed death warrant would be unwise.")
|
||||
used = FALSE
|
||||
return
|
||||
else
|
||||
var/mob/living/L = choice
|
||||
|
||||
message_admins("[key_name_admin(L)] has been marked for death by [key_name_admin(user)].")
|
||||
log_admin("[key_name(L)] has been marked for death by [key_name(user)].")
|
||||
|
||||
var/datum/objective/survive/survive = new
|
||||
survive.owner = L.mind
|
||||
L.mind.objectives += survive
|
||||
to_chat(L, "<span class='userdanger'>You've been marked for death! Don't let the demons get you!</span>")
|
||||
L.color = "#FF0000"
|
||||
spawn()
|
||||
var/obj/effect/mine/pickup/bloodbath/B = new(L)
|
||||
B.mineEffect(L)
|
||||
|
||||
for(var/mob/living/carbon/human/H in player_list)
|
||||
if(H == L)
|
||||
continue
|
||||
to_chat(H, "<span class='userdanger'>You have an overwhelming desire to kill [L]. They have been marked red! Go kill them!</span>")
|
||||
H.put_in_hands(new /obj/item/weapon/kitchen/knife/butcher(H))
|
||||
|
||||
qdel(src)
|
||||
+2
@@ -10,6 +10,7 @@
|
||||
luminosity = 8
|
||||
max_n_of_items = INFINITY
|
||||
unacidable = 1
|
||||
burn_state = LAVA_PROOF | FIRE_PROOF
|
||||
pixel_y = -4
|
||||
use_power = 0
|
||||
var/memory_saved = FALSE
|
||||
@@ -98,6 +99,7 @@
|
||||
luminosity = 8
|
||||
use_power = 0
|
||||
density = 1
|
||||
burn_state = LAVA_PROOF | FIRE_PROOF
|
||||
unacidable = 1
|
||||
var/activation_method = "touch"
|
||||
var/activation_damage_type = null
|
||||
@@ -0,0 +1,188 @@
|
||||
/obj/item/weapon/hierophant_staff
|
||||
name = "Hierophant's staff"
|
||||
desc = "A large club with intense magic power infused into it."
|
||||
icon_state = "hierophant_staff"
|
||||
item_state = "hierophant_staff"
|
||||
icon = 'icons/obj/guns/magic.dmi'
|
||||
slot_flags = SLOT_BACK
|
||||
w_class = 4
|
||||
force = 20
|
||||
hitsound = "swing_hit"
|
||||
//hitsound = 'sound/weapons/sonic_jackhammer.ogg'
|
||||
actions_types = list(/datum/action/item_action/vortex_recall, /datum/action/item_action/toggle_unfriendly_fire)
|
||||
var/cooldown_time = 20 //how long the cooldown between non-melee ranged attacks is
|
||||
var/chaser_cooldown = 101 //how long the cooldown between firing chasers at mobs is
|
||||
var/chaser_timer = 0 //what our current chaser cooldown is
|
||||
var/timer = 0 //what our current cooldown is
|
||||
var/blast_range = 3 //how long the cardinal blast's walls are
|
||||
var/obj/effect/hierophant/rune //the associated rune we teleport to
|
||||
var/teleporting = FALSE //if we ARE teleporting
|
||||
var/friendly_fire_check = FALSE //if the blasts we make will consider our faction against the faction of hit targets
|
||||
|
||||
/obj/item/weapon/hierophant_staff/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
..()
|
||||
var/turf/T = get_turf(target)
|
||||
if(!T || timer > world.time)
|
||||
return
|
||||
timer = world.time + CLICK_CD_MELEE //by default, melee attacks only cause melee blasts, and have an accordingly short cooldown
|
||||
if(proximity_flag)
|
||||
spawn(0)
|
||||
aoe_burst(T, user)
|
||||
add_logs(user, target, "fired 3x3 blast at", src)
|
||||
else
|
||||
if(ismineralturf(target) && get_dist(user, target) < 6) //target is minerals, we can hit it(even if we can't see it)
|
||||
spawn(0)
|
||||
cardinal_blasts(T, user)
|
||||
timer = world.time + cooldown_time
|
||||
else if(target in view(5, get_turf(user))) //if the target is in view, hit it
|
||||
timer = world.time + cooldown_time
|
||||
if(isliving(target) && chaser_timer <= world.time) //living and chasers off cooldown? fire one!
|
||||
chaser_timer = world.time + chaser_cooldown
|
||||
new /obj/effect/overlay/temp/hierophant/chaser(get_turf(user), user, target, 1.5, friendly_fire_check)
|
||||
add_logs(user, target, "fired a chaser at", src)
|
||||
else
|
||||
spawn(0)
|
||||
cardinal_blasts(T, user) //otherwise, just do cardinal blast
|
||||
add_logs(user, target, "fired cardinal blast at", src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>That target is out of range!</span>") //too far away
|
||||
|
||||
/obj/item/weapon/hierophant_staff/ui_action_click(mob/user, actiontype)
|
||||
if(actiontype == /datum/action/item_action/toggle_unfriendly_fire) //toggle friendly fire...
|
||||
friendly_fire_check = !friendly_fire_check
|
||||
to_chat(user, "<span class='warning'>You toggle friendly fire [friendly_fire_check ? "off":"on"]!</span>")
|
||||
return
|
||||
if(user.get_active_hand() != src && user.get_inactive_hand() != src) //you need to hold the staff to teleport
|
||||
to_chat(user, "<span class='warning'>You need to hold the staff in your hands to [rune ? "teleport with it" : "create a rune"]!</span>")
|
||||
return
|
||||
if(!rune)
|
||||
if(isturf(user.loc))
|
||||
user.visible_message("<span class='hierophant_warning'>[user] holds [src] carefully in front of them, moving it in a strange pattern...</span>", \
|
||||
"<span class='notice'>You start creating a hierophant rune to teleport to...</span>")
|
||||
timer = world.time + 51
|
||||
if(do_after(user, 50, target = user))
|
||||
var/turf/T = get_turf(user)
|
||||
playsound(T,'sound/magic/Blind.ogg', 200, 1, -4)
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph/teleport(T, user)
|
||||
var/obj/effect/hierophant/H = new/obj/effect/hierophant(T)
|
||||
rune = H
|
||||
user.update_action_buttons_icon()
|
||||
user.visible_message("<span class='hierophant_warning'>[user] creates a strange rune beneath them!</span>", \
|
||||
"<span class='hierophant'>You create a hierophant rune, which you can teleport yourself and any allies to at any time!</span>\n\
|
||||
<span class='notice'>You can remove the rune to place a new one by striking it with the staff.</span>")
|
||||
else
|
||||
timer = world.time
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to be on solid ground to produce a rune!</span>")
|
||||
return
|
||||
if(get_dist(user, rune) <= 2) //rune too close abort
|
||||
to_chat(user, "<span class='warning'>You are too close to the rune to teleport to it!</span>")
|
||||
return
|
||||
if(is_blocked_turf(get_turf(rune)))
|
||||
to_chat(user, "<span class='warning'>The rune is blocked by something, preventing teleportation!</span>")
|
||||
return
|
||||
teleporting = TRUE //start channel
|
||||
user.update_action_buttons_icon()
|
||||
user.visible_message("<span class='hierophant_warning'>[user] starts to glow faintly...</span>")
|
||||
timer = world.time + 50
|
||||
if(do_after(user, 40, target = user) && rune)
|
||||
var/turf/T = get_turf(rune)
|
||||
var/turf/source = get_turf(user)
|
||||
if(is_blocked_turf(T))
|
||||
teleporting = FALSE
|
||||
to_chat(user, "<span class='warning'>The rune is blocked by something, preventing teleportation!</span>")
|
||||
user.update_action_buttons_icon()
|
||||
return
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph(T, user)
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph(source, user)
|
||||
playsound(T,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(T,'sound/magic/Wand_Teleport.ogg', 200, 1)
|
||||
playsound(source,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(source,'sound/machines/AirlockOpen.ogg', 200, 1)
|
||||
if(!do_after(user, 3, target = user) || !rune) //no walking away shitlord
|
||||
teleporting = FALSE
|
||||
if(user)
|
||||
user.update_action_buttons_icon()
|
||||
return
|
||||
if(is_blocked_turf(T))
|
||||
teleporting = FALSE
|
||||
to_chat(user, "<span class='warning'>The rune is blocked by something, preventing teleportation!</span>")
|
||||
user.update_action_buttons_icon()
|
||||
return
|
||||
add_logs(user, rune, "teleported self from ([source.x],[source.y],[source.z]) to")
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph/teleport(T, user)
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph/teleport(source, user)
|
||||
for(var/t in RANGE_TURFS(1, T))
|
||||
var/obj/effect/overlay/temp/hierophant/blast/B = new /obj/effect/overlay/temp/hierophant/blast(t, user, TRUE) //blasts produced will not hurt allies
|
||||
B.damage = 30
|
||||
for(var/t in RANGE_TURFS(1, source))
|
||||
var/obj/effect/overlay/temp/hierophant/blast/B = new /obj/effect/overlay/temp/hierophant/blast(t, user, TRUE) //but absolutely will hurt enemies
|
||||
B.damage = 30
|
||||
for(var/mob/living/L in range(1, source))
|
||||
spawn(0)
|
||||
teleport_mob(source, L, T, user) //regardless, take all mobs near us along
|
||||
sleep(6) //at this point the blasts detonate
|
||||
else
|
||||
timer = world.time
|
||||
teleporting = FALSE
|
||||
if(user)
|
||||
user.update_action_buttons_icon()
|
||||
|
||||
/obj/item/weapon/hierophant_staff/proc/teleport_mob(turf/source, mob/M, turf/target, mob/user)
|
||||
var/turf/turf_to_teleport_to = get_step(target, get_dir(source, M)) //get position relative to caster
|
||||
if(!turf_to_teleport_to || is_blocked_turf(turf_to_teleport_to))
|
||||
return
|
||||
animate(M, alpha = 0, time = 2, easing = EASE_OUT) //fade out
|
||||
sleep(1)
|
||||
if(!M)
|
||||
return
|
||||
M.visible_message("<span class='hierophant_warning'>[M] fades out!</span>")
|
||||
sleep(2)
|
||||
if(!M)
|
||||
return
|
||||
M.forceMove(turf_to_teleport_to)
|
||||
sleep(1)
|
||||
if(!M)
|
||||
return
|
||||
animate(M, alpha = 255, time = 2, easing = EASE_IN) //fade IN
|
||||
sleep(1)
|
||||
if(!M)
|
||||
return
|
||||
M.visible_message("<span class='hierophant_warning'>[M] fades in!</span>")
|
||||
if(user != M)
|
||||
add_logs(user, M, "teleported", null, "from ([source.x],[source.y],[source.z])")
|
||||
|
||||
/obj/item/weapon/hierophant_staff/proc/cardinal_blasts(turf/T, mob/living/user) //fire cardinal cross blasts with a delay
|
||||
if(!T)
|
||||
return
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph/cardinal(T, user)
|
||||
playsound(T,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
|
||||
sleep(2)
|
||||
new /obj/effect/overlay/temp/hierophant/blast(T, user, friendly_fire_check)
|
||||
for(var/d in cardinal)
|
||||
spawn(0)
|
||||
blast_wall(T, d, user)
|
||||
|
||||
/obj/item/weapon/hierophant_staff/proc/blast_wall(turf/T, dir, mob/living/user) //make a wall of blasts blast_range tiles long
|
||||
if(!T)
|
||||
return
|
||||
var/range = blast_range
|
||||
var/turf/previousturf = T
|
||||
var/turf/J = get_step(previousturf, dir)
|
||||
for(var/i in 1 to range)
|
||||
if(!J)
|
||||
return
|
||||
new /obj/effect/overlay/temp/hierophant/blast(J, user, friendly_fire_check)
|
||||
previousturf = J
|
||||
J = get_step(previousturf, dir)
|
||||
|
||||
/obj/item/weapon/hierophant_staff/proc/aoe_burst(turf/T, mob/living/user) //make a 3x3 blast around a target
|
||||
if(!T)
|
||||
return
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph(T, user)
|
||||
playsound(T,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
|
||||
sleep(2)
|
||||
for(var/t in RANGE_TURFS(1, T))
|
||||
new /obj/effect/overlay/temp/hierophant/blast(t, user, friendly_fire_check)
|
||||
@@ -0,0 +1,52 @@
|
||||
/obj/item/weapon/staff/storm
|
||||
name = "staff of storms"
|
||||
desc = "An ancient staff retrieved from the remains of Legion. The wind stirs as you move it."
|
||||
icon_state = "staffofstorms"
|
||||
item_state = "staffofstorms"
|
||||
icon = 'icons/obj/guns/magic.dmi'
|
||||
slot_flags = SLOT_BACK
|
||||
item_state = "staffofstorms"
|
||||
w_class = 4
|
||||
force = 25
|
||||
damtype = BURN
|
||||
hitsound = 'sound/weapons/sear.ogg'
|
||||
var/storm_type = /datum/weather/ash_storm
|
||||
var/storm_cooldown = 0
|
||||
|
||||
/obj/item/weapon/staff/storm/attack_self(mob/user)
|
||||
if(storm_cooldown > world.time)
|
||||
to_chat(user, "<span class='warning'>The staff is still recharging!</span>")
|
||||
return
|
||||
|
||||
var/area/user_area = get_area(user)
|
||||
var/datum/weather/A
|
||||
var/z_level_name = space_manager.levels_by_name[user.z]
|
||||
for(var/V in weather_master.existing_weather)
|
||||
var/datum/weather/W = V
|
||||
if(W.target_z == z_level_name && W.area_type == user_area.type)
|
||||
A = W
|
||||
break
|
||||
if(A)
|
||||
|
||||
if(A.stage != END_STAGE)
|
||||
if(A.stage == WIND_DOWN_STAGE)
|
||||
to_chat(user, "<span class='warning'>The storm is already ending! It would be a waste to use the staff now.</span>")
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] holds [src] skywards as an orange beam travels into the sky!</span>", \
|
||||
"<span class='notice'>You hold [src] skyward, dispelling the storm!</span>")
|
||||
playsound(user, 'sound/magic/Staff_Change.ogg', 200, 0)
|
||||
A.wind_down()
|
||||
return
|
||||
else
|
||||
A = new storm_type
|
||||
A.name = "staff storm"
|
||||
A.area_type = user_area.type
|
||||
A.target_z = z_level_name
|
||||
A.telegraph_duration = 100
|
||||
A.end_duration = 100
|
||||
|
||||
user.visible_message("<span class='warning'>[user] holds [src] skywards as red lightning crackles into the sky!</span>", \
|
||||
"<span class='notice'>You hold [src] skyward, calling down a terrible storm!</span>")
|
||||
playsound(user, 'sound/magic/Staff_Change.ogg', 200, 0)
|
||||
A.telegraph()
|
||||
storm_cooldown = world.time + 200
|
||||
@@ -0,0 +1,394 @@
|
||||
//Shared Bag
|
||||
|
||||
//Internal
|
||||
/obj/item/weapon/storage/backpack/shared
|
||||
name = "paradox bag"
|
||||
desc = "Somehow, it's in two places at once."
|
||||
max_combined_w_class = 60
|
||||
max_w_class = 3
|
||||
|
||||
//External
|
||||
/obj/item/device/shared_storage
|
||||
name = "paradox bag"
|
||||
desc = "Somehow, it's in two places at once."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "cultpack"
|
||||
slot_flags = SLOT_BACK
|
||||
var/obj/item/weapon/storage/backpack/shared/bag
|
||||
|
||||
/obj/item/device/shared_storage/red
|
||||
name = "paradox bag"
|
||||
desc = "Somehow, it's in two places at once."
|
||||
|
||||
/obj/item/device/shared_storage/red/New()
|
||||
..()
|
||||
if(!bag)
|
||||
var/obj/item/weapon/storage/backpack/shared/S = new(src)
|
||||
var/obj/item/device/shared_storage/blue = new(loc)
|
||||
|
||||
bag = S
|
||||
blue.bag = S
|
||||
|
||||
/obj/item/device/shared_storage/attackby(obj/item/W, mob/user, params)
|
||||
if(bag)
|
||||
bag.loc = user
|
||||
bag.attackby(W, user, params)
|
||||
|
||||
/obj/item/device/shared_storage/attack_self(mob/living/carbon/user)
|
||||
if(!iscarbon(user))
|
||||
return
|
||||
if(src == user.l_hand || src == user.r_hand)
|
||||
if(bag)
|
||||
bag.loc = user
|
||||
bag.attack_hand(user)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/device/shared_storage/attack_hand(mob/living/carbon/user)
|
||||
if(!iscarbon(user))
|
||||
return
|
||||
if(loc == user && user.back && user.back == src)
|
||||
if(bag)
|
||||
bag.loc = user
|
||||
bag.attack_hand(user)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/device/shared_storage/MouseDrop(atom/over_object)
|
||||
if(iscarbon(usr))
|
||||
var/mob/M = usr
|
||||
|
||||
if(!over_object)
|
||||
return
|
||||
|
||||
if(istype(M.loc, /obj/mecha))
|
||||
return
|
||||
|
||||
if(!M.restrained() && !M.stat)
|
||||
playsound(loc, "rustle", 50, 1, -5)
|
||||
|
||||
if(istype(over_object, /obj/screen/inventory/hand))
|
||||
if(!M.unEquip(src))
|
||||
return
|
||||
M.put_in_active_hand(src)
|
||||
else if(bag)
|
||||
bag.loc = usr
|
||||
bag.attack_hand(usr)
|
||||
|
||||
add_fingerprint(M)
|
||||
|
||||
//Potion of Flight: as we do not have the "Angel" species this currently does not work.
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/bottle/potion
|
||||
icon = 'icons/obj/lavaland/artefacts.dmi'
|
||||
icon_state = "potionflask"
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/bottle/potion/flight
|
||||
name = "strange elixir"
|
||||
desc = "A flask with an almost-holy aura emitting from it. The label on the bottle says: 'erqo'hyy tvi'rf lbh jv'atf'."
|
||||
list_reagents = list("flightpotion" = 5)
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/bottle/potion/update_icon()
|
||||
if(reagents.total_volume)
|
||||
icon_state = "potionflask"
|
||||
else
|
||||
icon_state = "potionflask_empty"
|
||||
|
||||
/datum/reagent/flightpotion
|
||||
name = "Flight Potion"
|
||||
id = "flightpotion"
|
||||
description = "Strange mutagenic compound of unknown origins."
|
||||
reagent_state = LIQUID
|
||||
color = "#FFEBEB"
|
||||
|
||||
/datum/reagent/flightpotion/reaction_mob(mob/living/M, method = TOUCH, reac_volume, show_message = 1)
|
||||
to_chat(M, "<span class='warning'>This item is currently non-functional.</span>")
|
||||
/*if(ishuman(M) && M.stat != DEAD)
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.species.name != "Human" || reac_volume < 5) // implying xenohumans are holy
|
||||
if(method == INGEST && show_message)
|
||||
to_chat(H, "<span class='notice'><i>You feel nothing but a terrible aftertaste.</i></span>")
|
||||
return ..()
|
||||
|
||||
to_chat(H, "<span class='userdanger'>A terrible pain travels down your back as wings burst out!</span>")
|
||||
H.set_species("Angel")
|
||||
playsound(H.loc, 'sound/items/poster_ripped.ogg', 50, 1, -1)
|
||||
H.adjustBruteLoss(20)
|
||||
H.emote("scream")
|
||||
..()*/
|
||||
|
||||
//Boat
|
||||
|
||||
/obj/vehicle/lavaboat
|
||||
name = "lava boat"
|
||||
desc = "A boat used for traversing lava."
|
||||
icon_state = "goliath_boat"
|
||||
icon = 'icons/obj/lavaland/dragonboat.dmi'
|
||||
keytype = /obj/item/weapon/oar
|
||||
burn_state = LAVA_PROOF | FIRE_PROOF
|
||||
|
||||
/obj/vehicle/lavaboat/relaymove(mob/user, direction)
|
||||
var/turf/next = get_step(src, direction)
|
||||
var/turf/current = get_turf(src)
|
||||
|
||||
if(istype(next, /turf/unsimulated/floor/lava) || istype(current, /turf/unsimulated/floor/lava)) //We can move from land to lava, or lava to land, but not from land to land
|
||||
..()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Boats don't go on land!</span>")
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/oar
|
||||
name = "oar"
|
||||
icon = 'icons/obj/vehicles.dmi'
|
||||
icon_state = "oar"
|
||||
item_state = "rods"
|
||||
desc = "Not to be confused with the kind Research hassles you for."
|
||||
force = 12
|
||||
w_class = 3
|
||||
burn_state = LAVA_PROOF | FIRE_PROOF
|
||||
|
||||
/datum/crafting_recipe/oar
|
||||
name = "goliath bone oar"
|
||||
result = /obj/item/weapon/oar
|
||||
reqs = list(/obj/item/stack/sheet/bone = 2)
|
||||
time = 15
|
||||
category = CAT_PRIMAL
|
||||
|
||||
/datum/crafting_recipe/boat
|
||||
name = "goliath hide boat"
|
||||
result = /obj/vehicle/lavaboat
|
||||
reqs = list(/obj/item/stack/sheet/animalhide/goliath_hide = 3)
|
||||
time = 50
|
||||
category = CAT_PRIMAL
|
||||
|
||||
//Dragon Boat
|
||||
|
||||
/obj/item/ship_in_a_bottle
|
||||
name = "ship in a bottle"
|
||||
desc = "A tiny ship inside a bottle."
|
||||
icon = 'icons/obj/lavaland/artefacts.dmi'
|
||||
icon_state = "ship_bottle"
|
||||
|
||||
/obj/item/ship_in_a_bottle/attack_self(mob/user)
|
||||
to_chat(user, "You're not sure how they get the ships in these things, but you're pretty sure you know how to get it out.")
|
||||
playsound(user.loc, 'sound/effects/Glassbr1.ogg', 100, 1)
|
||||
new /obj/vehicle/lavaboat/dragon(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/vehicle/lavaboat/dragon
|
||||
name = "mysterious boat"
|
||||
desc = "This boat moves where you will it, without the need for an oar."
|
||||
keytype = null
|
||||
icon_state = "dragon_boat"
|
||||
generic_pixel_y = 2
|
||||
generic_pixel_x = 1
|
||||
vehicle_move_delay = 1
|
||||
|
||||
// Wisp Lantern
|
||||
/obj/item/device/wisp_lantern
|
||||
name = "spooky lantern"
|
||||
desc = "This lantern gives off no light, but is home to a friendly wisp."
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
icon_state = "lantern-blue"
|
||||
var/obj/effect/wisp/wisp
|
||||
|
||||
/obj/item/device/wisp_lantern/attack_self(mob/user)
|
||||
if(!wisp)
|
||||
to_chat(user, "<span class='warning'>The wisp has gone missing!</span>")
|
||||
return
|
||||
if(wisp.loc == src)
|
||||
to_chat(user, "<span class='notice'>You release the wisp. It begins to bob around your head.</span>")
|
||||
user.sight |= SEE_MOBS
|
||||
icon_state = "lantern"
|
||||
wisp.orbit(user, 20, forceMove = TRUE)
|
||||
feedback_add_details("wisp_lantern","F") // freed
|
||||
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You return the wisp to the lantern.</span>")
|
||||
|
||||
if(wisp.orbiting)
|
||||
var/atom/A = wisp.orbiting
|
||||
if(isliving(A))
|
||||
var/mob/living/M = A
|
||||
M.sight &= ~SEE_MOBS
|
||||
to_chat(M, "<span class='notice'>Your vision returns to normal.</span>")
|
||||
|
||||
wisp.stop_orbit()
|
||||
wisp.loc = src
|
||||
icon_state = "lantern-blue"
|
||||
feedback_add_details("wisp_lantern","R") // returned
|
||||
|
||||
/obj/item/device/wisp_lantern/New()
|
||||
..()
|
||||
wisp = new(src)
|
||||
|
||||
/obj/item/device/wisp_lantern/Destroy()
|
||||
if(wisp)
|
||||
if(wisp.loc == src)
|
||||
qdel(wisp)
|
||||
else
|
||||
wisp.visible_message("<span class='notice'>[wisp] has a sad feeling for a moment, then it passes.</span>")
|
||||
return ..()
|
||||
|
||||
/obj/effect/wisp
|
||||
name = "friendly wisp"
|
||||
desc = "Happy to light your way."
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
icon_state = "orb"
|
||||
layer = ABOVE_ALL_MOB_LAYER
|
||||
light_power = 1
|
||||
light_range = 7
|
||||
|
||||
//Red/Blue Cubes
|
||||
|
||||
/obj/item/device/warp_cube
|
||||
name = "blue cube"
|
||||
desc = "A mysterious blue cube."
|
||||
icon = 'icons/obj/lavaland/artefacts.dmi'
|
||||
icon_state = "blue_cube"
|
||||
var/obj/item/device/warp_cube/linked
|
||||
|
||||
/obj/item/device/warp_cube/Destroy()
|
||||
if(linked)
|
||||
linked.linked = null
|
||||
linked = null
|
||||
return ..()
|
||||
|
||||
/obj/item/device/warp_cube/attack_self(mob/user)
|
||||
if(!linked)
|
||||
to_chat(user, "[src] fizzles uselessly.")
|
||||
return
|
||||
|
||||
var/datum/effect/system/harmless_smoke_spread/smoke = new /datum/effect/system/harmless_smoke_spread()
|
||||
smoke.set_up(1, 0, user.loc)
|
||||
smoke.start()
|
||||
|
||||
user.forceMove(get_turf(linked))
|
||||
feedback_add_details("warp_cube","[src.type]")
|
||||
|
||||
var/datum/effect/system/harmless_smoke_spread/smoke2 = new /datum/effect/system/harmless_smoke_spread()
|
||||
smoke2.set_up(1, 0, user.loc)
|
||||
smoke2.start()
|
||||
|
||||
/obj/item/device/warp_cube/red
|
||||
name = "red cube"
|
||||
desc = "A mysterious red cube."
|
||||
icon_state = "red_cube"
|
||||
|
||||
/obj/item/device/warp_cube/red/New()
|
||||
..()
|
||||
if(!linked)
|
||||
var/obj/item/device/warp_cube/blue = new(src.loc)
|
||||
linked = blue
|
||||
blue.linked = src
|
||||
|
||||
//Meat Hook
|
||||
|
||||
/obj/item/weapon/gun/magic/hook
|
||||
name = "meat hook"
|
||||
desc = "Mid or feed."
|
||||
ammo_type = /obj/item/ammo_casing/magic/hook
|
||||
icon_state = "hook"
|
||||
item_state = "chain"
|
||||
fire_sound = 'sound/weapons/batonextend.ogg'
|
||||
max_charges = 1
|
||||
flags = NOBLUDGEON
|
||||
force = 18
|
||||
|
||||
/obj/item/ammo_casing/magic/hook
|
||||
name = "hook"
|
||||
desc = "a hook."
|
||||
projectile_type = /obj/item/projectile/hook
|
||||
caliber = "hook"
|
||||
icon_state = "hook"
|
||||
|
||||
/obj/item/projectile/hook
|
||||
name = "hook"
|
||||
icon_state = "hook"
|
||||
icon = 'icons/obj/lavaland/artefacts.dmi'
|
||||
pass_flags = PASSTABLE
|
||||
damage = 25
|
||||
armour_penetration = 100
|
||||
damage_type = BRUTE
|
||||
hitsound = 'sound/effects/splat.ogg'
|
||||
weaken = 3
|
||||
var/chain
|
||||
|
||||
/obj/item/projectile/hook/fire(setAngle)
|
||||
if(firer)
|
||||
chain = firer.Beam(src, icon_state = "chain", time = INFINITY, maxdistance = INFINITY)
|
||||
..()
|
||||
//TODO: root the firer until the chain returns
|
||||
|
||||
/obj/item/projectile/hook/on_hit(atom/target)
|
||||
. = ..()
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(!L.anchored)
|
||||
L.visible_message("<span class='danger'>[L] is snagged by [firer]'s hook!</span>")
|
||||
L.forceMove(get_turf(firer))
|
||||
|
||||
/obj/item/projectile/hook/Destroy()
|
||||
qdel(chain)
|
||||
return ..()
|
||||
|
||||
//Immortality Talisman
|
||||
|
||||
/obj/item/device/immortality_talisman
|
||||
name = "Immortality Talisman"
|
||||
desc = "A dread talisman that can render you completely invulnerable."
|
||||
icon = 'icons/obj/lavaland/artefacts.dmi'
|
||||
icon_state = "talisman"
|
||||
actions_types = list(/datum/action/item_action/immortality)
|
||||
var/cooldown = 0
|
||||
|
||||
/datum/action/item_action/immortality
|
||||
name = "Immortality"
|
||||
|
||||
/obj/item/device/immortality_talisman/Destroy(force)
|
||||
if(force)
|
||||
. = ..()
|
||||
else
|
||||
return QDEL_HINT_LETMELIVE
|
||||
|
||||
/obj/item/device/immortality_talisman/attack_self(mob/user)
|
||||
if(cooldown < world.time)
|
||||
feedback_add_details("immortality_talisman","U") // usage
|
||||
cooldown = world.time + 600
|
||||
user.visible_message("<span class='danger'>[user] vanishes from reality, leaving a a hole in their place!</span>")
|
||||
var/obj/effect/immortality_talisman/Z = new(get_turf(src.loc))
|
||||
Z.name = "hole in reality"
|
||||
Z.desc = "It's shaped an awful lot like [user.name]."
|
||||
Z.setDir(user.dir)
|
||||
user.forceMove(Z)
|
||||
user.notransform = 1
|
||||
user.status_flags |= GODMODE
|
||||
spawn(100)
|
||||
user.status_flags &= ~GODMODE
|
||||
user.notransform = 0
|
||||
user.forceMove(get_turf(Z))
|
||||
user.visible_message("<span class='danger'>[user] pops back into reality!</span>")
|
||||
Z.can_destroy = TRUE
|
||||
qdel(Z)
|
||||
else
|
||||
to_chat(user, "<span class'warning'>[src] is still recharging.</span>")
|
||||
|
||||
/obj/effect/immortality_talisman
|
||||
icon_state = "blank"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
var/can_destroy = FALSE
|
||||
|
||||
/obj/effect/immortality_talisman/attackby()
|
||||
return
|
||||
|
||||
/obj/effect/immortality_talisman/ex_act()
|
||||
return
|
||||
|
||||
/obj/effect/immortality_talisman/singularity_pull()
|
||||
return 0
|
||||
|
||||
/obj/effect/immortality_talisman/Destroy(force)
|
||||
if(!can_destroy && !force)
|
||||
return QDEL_HINT_LETMELIVE
|
||||
else
|
||||
. = ..()
|
||||
@@ -6,19 +6,21 @@
|
||||
icon_state = "necrocrate"
|
||||
icon_opened = "necrocrateopen"
|
||||
icon_closed = "necrocrate"
|
||||
burn_state = LAVA_PROOF | FIRE_PROOF
|
||||
unacidable = 1
|
||||
|
||||
/obj/structure/closet/crate/necropolis/tendril
|
||||
desc = "It's watching you suspiciously."
|
||||
|
||||
/obj/structure/closet/crate/necropolis/tendril/New()
|
||||
..()
|
||||
// uncomment me once these items are being implemented
|
||||
/*var/loot = rand(1,25)
|
||||
var/loot = rand(1,24)
|
||||
switch(loot)
|
||||
if(1)
|
||||
new /obj/item/device/shared_storage/red(src)
|
||||
if(2)
|
||||
new /obj/item/clothing/suit/space/hardsuit/cult(src)
|
||||
new /obj/item/clothing/head/helmet/space/cult(src)
|
||||
new /obj/item/clothing/suit/space/cult(src)
|
||||
if(3)
|
||||
new /obj/item/device/soulstone/anybody(src)
|
||||
if(4)
|
||||
@@ -26,593 +28,45 @@
|
||||
if(5)
|
||||
new /obj/item/clothing/glasses/godeye(src)
|
||||
if(6)
|
||||
new /obj/item/weapon/reagent_containers/glass/bottle/potion/flight(src)
|
||||
if(7)
|
||||
new /obj/item/weapon/pickaxe/diamond(src)
|
||||
if(8)
|
||||
if(7)
|
||||
new /obj/item/clothing/head/culthood(src)
|
||||
new /obj/item/clothing/suit/cultrobes(src)
|
||||
new /obj/item/clothing/suit/hooded/cultrobes(src)
|
||||
new /obj/item/weapon/bedsheet/cult(src)
|
||||
if(8)
|
||||
new /obj/item/organ/internal/brain/xeno(src)
|
||||
if(9)
|
||||
new /obj/item/organ/brain/alien(src)
|
||||
new /obj/item/organ/internal/heart/cursed(src)
|
||||
if(10)
|
||||
new /obj/item/organ/heart/cursed(src)
|
||||
if(11)
|
||||
new /obj/item/ship_in_a_bottle(src)
|
||||
if(11)
|
||||
new /obj/item/clothing/head/helmet/space/rig/ert/paranormal/berserker(src)
|
||||
new /obj/item/clothing/suit/space/rig/ert/paranormal/berserker(src)
|
||||
if(12)
|
||||
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker(src)
|
||||
if(13)
|
||||
new /obj/item/weapon/sord(src)
|
||||
if(14)
|
||||
if(13)
|
||||
new /obj/item/weapon/nullrod/scythe/talking(src)
|
||||
if(15)
|
||||
if(14)
|
||||
new /obj/item/weapon/nullrod/armblade(src)
|
||||
if(16)
|
||||
if(15)
|
||||
new /obj/item/weapon/guardiancreator(src)
|
||||
if(17)
|
||||
if(16)
|
||||
new /obj/item/borg/upgrade/modkit/aoe/turfs/andmobs(src)
|
||||
if(18)
|
||||
if(17)
|
||||
new /obj/item/device/warp_cube/red(src)
|
||||
if(19)
|
||||
if(18)
|
||||
new /obj/item/device/wisp_lantern(src)
|
||||
if(20)
|
||||
if(19)
|
||||
new /obj/item/device/immortality_talisman(src)
|
||||
if(21)
|
||||
if(20)
|
||||
new /obj/item/weapon/gun/magic/hook(src)
|
||||
if(22)
|
||||
if(21)
|
||||
new /obj/item/voodoo(src)
|
||||
if(23)
|
||||
if(22)
|
||||
new /obj/item/weapon/grenade/clusterbuster/inferno(src)
|
||||
if(24)
|
||||
if(23)
|
||||
new /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater/hell(src)
|
||||
new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor(src)
|
||||
if(25)
|
||||
new /obj/item/weapon/spellbook/oneuse/summonitem(src)*/
|
||||
|
||||
///Bosses
|
||||
|
||||
//Dragon
|
||||
|
||||
/obj/structure/closet/crate/necropolis/dragon
|
||||
name = "dragon chest"
|
||||
|
||||
/obj/structure/closet/crate/necropolis/dragon/New()
|
||||
..()
|
||||
var/loot = rand(1,4)
|
||||
switch(loot)
|
||||
if(1)
|
||||
new /obj/item/weapon/melee/ghost_sword(src)
|
||||
if(2)
|
||||
new /obj/item/weapon/lava_staff(src)
|
||||
if(3)
|
||||
new /obj/item/weapon/spellbook/oneuse/sacredflame(src)
|
||||
new /obj/item/weapon/gun/magic/wand/fireball(src)
|
||||
if(4)
|
||||
new /obj/item/weapon/dragons_blood(src)
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword
|
||||
name = "spectral blade"
|
||||
desc = "A rusted and dulled blade. It doesn't look like it'd do much damage. It glows weakly."
|
||||
icon_state = "spectral"
|
||||
item_state = "spectral"
|
||||
flags = CONDUCT
|
||||
sharp = 1
|
||||
edge = 1
|
||||
w_class = 4
|
||||
force = 1
|
||||
throwforce = 1
|
||||
hitsound = 'sound/effects/ghost2.ogg'
|
||||
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "rended")
|
||||
var/summon_cooldown = 0
|
||||
var/list/mob/dead/observer/spirits
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/New()
|
||||
..()
|
||||
spirits = list()
|
||||
processing_objects.Add(src)
|
||||
poi_list |= src
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/Destroy()
|
||||
for(var/mob/dead/observer/G in spirits)
|
||||
G.invisibility = initial(G.invisibility)
|
||||
spirits.Cut()
|
||||
processing_objects.Remove(src)
|
||||
poi_list -= src
|
||||
. = ..()
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/attack_self(mob/user)
|
||||
if(summon_cooldown > world.time)
|
||||
to_chat(user, "You just recently called out for aid. You don't want to annoy the spirits.")
|
||||
return
|
||||
to_chat(user, "You call out for aid, attempting to summon spirits to your side.")
|
||||
|
||||
notify_ghosts("[user] is raising their [src], calling for your help!", enter_link="<a href=?src=[UID()];follow=1>(Click to help)</a>", source = user, action = NOTIFY_FOLLOW)
|
||||
|
||||
summon_cooldown = world.time + 600
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/Topic(href, href_list)
|
||||
if(href_list["follow"])
|
||||
var/mob/dead/observer/ghost = usr
|
||||
if(istype(ghost))
|
||||
ghost.ManualFollow(src)
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/process()
|
||||
ghost_check()
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/proc/ghost_check()
|
||||
var/ghost_counter = 0
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/contents = T.GetAllContents()
|
||||
var/mob/dead/observer/current_spirits = list()
|
||||
|
||||
for(var/mob/dead/observer/O in player_list)
|
||||
if(is_type_in_list(O.following, contents))
|
||||
ghost_counter++
|
||||
O.invisibility = 0
|
||||
current_spirits |= O
|
||||
|
||||
for(var/mob/dead/observer/G in spirits - current_spirits)
|
||||
G.invisibility = initial(G.invisibility)
|
||||
|
||||
spirits = current_spirits
|
||||
|
||||
return ghost_counter
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/attack(mob/living/target, mob/living/carbon/human/user)
|
||||
force = 0
|
||||
var/ghost_counter = ghost_check()
|
||||
|
||||
force = Clamp((ghost_counter * 4), 0, 75)
|
||||
user.visible_message("<span class='danger'>[user] strikes with the force of [ghost_counter] vengeful spirits!</span>")
|
||||
..()
|
||||
|
||||
/obj/item/weapon/melee/ghost_sword/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance, damage, attack_type)
|
||||
var/ghost_counter = ghost_check()
|
||||
final_block_chance += Clamp((ghost_counter * 5), 0, 75)
|
||||
owner.visible_message("<span class='danger'>[owner] is protected by a ring of [ghost_counter] ghosts!</span>")
|
||||
return ..()
|
||||
|
||||
// Blood
|
||||
|
||||
/obj/item/weapon/dragons_blood
|
||||
name = "bottle of dragons blood"
|
||||
desc = "You're not actually going to drink this, are you?"
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "vial"
|
||||
|
||||
/obj/item/weapon/dragons_blood/attack_self(mob/living/carbon/human/user)
|
||||
if(!istype(user))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/random = rand(1,3)
|
||||
|
||||
switch(random)
|
||||
if(1)
|
||||
to_chat(user, "<span class='danger'>Your flesh begins to melt! Miraculously, you seem fine otherwise.</span>")
|
||||
H.set_species("Skeleton")
|
||||
if(2)
|
||||
to_chat(user, "<span class='danger'>Power courses through you! You can now shift your form at will.")
|
||||
if(user.mind)
|
||||
var/obj/effect/proc_holder/spell/targeted/shapeshift/dragon/D = new
|
||||
user.mind.AddSpell(D)
|
||||
if(3)
|
||||
to_chat(user, "<span class='danger'>You feel like you could walk straight through lava now.</span>")
|
||||
H.weather_immunities |= "lava"
|
||||
|
||||
playsound(user.loc,'sound/items/drink.ogg', rand(10,50), 1)
|
||||
qdel(src)
|
||||
|
||||
/datum/disease/transformation/dragon
|
||||
name = "dragon transformation"
|
||||
cure_text = "nothing"
|
||||
cures = list("adminordrazine")
|
||||
agent = "dragon's blood"
|
||||
desc = "What do dragons have to do with Space Station 13?"
|
||||
stage_prob = 20
|
||||
severity = BIOHAZARD
|
||||
visibility_flags = 0
|
||||
stage1 = list("Your bones ache.")
|
||||
stage2 = list("Your skin feels scaley.")
|
||||
stage3 = list("<span class='danger'>You have an overwhelming urge to terrorize some peasants.</span>", "<span class='danger'>Your teeth feel sharper.</span>")
|
||||
stage4 = list("<span class='danger'>Your blood burns.</span>")
|
||||
stage5 = list("<span class='danger'>You're a fucking dragon. However, any previous allegiances you held still apply. It'd be incredibly rude to eat your still human friends for no reason.</span>")
|
||||
new_form = /mob/living/simple_animal/hostile/megafauna/dragon/lesser
|
||||
|
||||
//Lava Staff
|
||||
|
||||
/obj/item/weapon/lava_staff
|
||||
name = "staff of lava"
|
||||
desc = "The ability to fill the emergency shuttle with lava. What more could you want out of life?"
|
||||
icon_state = "staffofstorms"
|
||||
item_state = "staffofstorms"
|
||||
icon = 'icons/obj/guns/magic.dmi'
|
||||
slot_flags = SLOT_BACK
|
||||
item_state = "staffofstorms"
|
||||
w_class = 4
|
||||
force = 25
|
||||
damtype = BURN
|
||||
hitsound = 'sound/weapons/sear.ogg'
|
||||
var/turf_type = /turf/unsimulated/floor/lava // /turf/simulated/floor/plating/lava/smooth once Lavaland turfs are added
|
||||
var/transform_string = "lava"
|
||||
var/reset_turf_type = /turf/simulated/floor/plating/airless/asteroid // /turf/simulated/floor/plating/asteroid/basalt once Lavaland turfs are added
|
||||
var/reset_string = "basalt"
|
||||
var/create_cooldown = 100
|
||||
var/create_delay = 30
|
||||
var/reset_cooldown = 50
|
||||
var/timer = 0
|
||||
var/banned_turfs
|
||||
|
||||
/obj/item/weapon/lava_staff/New()
|
||||
. = ..()
|
||||
banned_turfs = typecacheof(list(/turf/space/transit, /turf/unsimulated))
|
||||
|
||||
/obj/item/weapon/lava_staff/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
..()
|
||||
if(timer > world.time)
|
||||
return
|
||||
|
||||
if(is_type_in_typecache(target, banned_turfs))
|
||||
return
|
||||
|
||||
if(target in view(user.client.view, get_turf(user)))
|
||||
|
||||
var/turf/simulated/T = get_turf(target)
|
||||
if(!istype(T))
|
||||
return
|
||||
if(!istype(T, turf_type))
|
||||
var/obj/effect/overlay/temp/lavastaff/L = new /obj/effect/overlay/temp/lavastaff(T)
|
||||
L.alpha = 0
|
||||
animate(L, alpha = 255, time = create_delay)
|
||||
user.visible_message("<span class='danger'>[user] points [src] at [T]!</span>")
|
||||
timer = world.time + create_delay + 1
|
||||
if(do_after(user, create_delay, target = T))
|
||||
user.visible_message("<span class='danger'>[user] turns \the [T] into [transform_string]!</span>")
|
||||
message_admins("[key_name_admin(user)] fired the lava staff at [get_area(target)] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>).")
|
||||
log_game("[key_name(user)] fired the lava staff at [get_area(target)] ([T.x], [T.y], [T.z]).")
|
||||
T.ChangeTurf(turf_type)
|
||||
timer = world.time + create_cooldown
|
||||
qdel(L)
|
||||
else
|
||||
timer = world.time
|
||||
qdel(L)
|
||||
return
|
||||
else
|
||||
user.visible_message("<span class='danger'>[user] turns \the [T] into [reset_string]!</span>")
|
||||
T.ChangeTurf(reset_turf_type)
|
||||
timer = world.time + reset_cooldown
|
||||
playsound(T,'sound/magic/Fireball.ogg', 200, 1)
|
||||
|
||||
/obj/effect/overlay/temp/lavastaff
|
||||
icon_state = "lavastaff_warn"
|
||||
duration = 50
|
||||
|
||||
// Bubblegum
|
||||
|
||||
/obj/structure/closet/crate/necropolis/bubblegum
|
||||
name = "bubblegum chest"
|
||||
|
||||
/obj/structure/closet/crate/necropolis/bubblegum/New()
|
||||
..()
|
||||
var/loot = rand(1,3)
|
||||
switch(loot)
|
||||
if(1)
|
||||
new /obj/item/mayhem(src)
|
||||
if(2)
|
||||
new /obj/item/blood_contract(src)
|
||||
if(3)
|
||||
new /obj/item/weapon/gun/magic/staff/spellblade(src)
|
||||
|
||||
// Mayhem
|
||||
|
||||
/obj/item/mayhem
|
||||
name = "mayhem in a bottle"
|
||||
desc = "A magically infused bottle of blood, the scent of which will drive anyone nearby into a murderous frenzy."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "vial"
|
||||
|
||||
/obj/item/mayhem/attack_self(mob/user)
|
||||
for(var/mob/living/carbon/human/H in range(7,user))
|
||||
spawn()
|
||||
var/obj/effect/mine/pickup/bloodbath/B = new(H)
|
||||
B.mineEffect(H)
|
||||
to_chat(user, "<span class='notice'>You shatter the bottle!</span>")
|
||||
playsound(user.loc, 'sound/effects/Glassbr1.ogg', 100, 1)
|
||||
qdel(src)
|
||||
|
||||
// Blood Contract
|
||||
|
||||
/obj/item/blood_contract
|
||||
name = "blood contract"
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "scroll2"
|
||||
color = "#FF0000"
|
||||
desc = "Mark your target for death."
|
||||
var/used = FALSE
|
||||
|
||||
/obj/item/blood_contract/attack_self(mob/user)
|
||||
if(used)
|
||||
return
|
||||
|
||||
used = TRUE
|
||||
var/choice = input(user,"Who do you want dead?","Choose Your Victim") as null|anything in player_list
|
||||
|
||||
if(!choice)
|
||||
used = FALSE
|
||||
return
|
||||
else if(!isliving(choice))
|
||||
to_chat(user, "[choice] is already dead!")
|
||||
used = FALSE
|
||||
return
|
||||
else
|
||||
var/mob/living/L = choice
|
||||
|
||||
message_admins("[key_name_admin(L)] has been marked for death by [key_name_admin(user)].")
|
||||
log_admin("[key_name(L)] has been marked for death by [key_name(user)].")
|
||||
|
||||
var/datum/objective/survive/survive = new
|
||||
survive.owner = L.mind
|
||||
L.mind.objectives += survive
|
||||
to_chat(L, "<span class='userdanger'>You've been marked for death! Don't let the demons get you!</span>")
|
||||
L.color = "#FF0000"
|
||||
spawn()
|
||||
var/obj/effect/mine/pickup/bloodbath/B = new(L)
|
||||
B.mineEffect(L)
|
||||
|
||||
for(var/mob/living/carbon/human/H in player_list)
|
||||
if(H == L)
|
||||
continue
|
||||
to_chat(H, "<span class='userdanger'>You have an overwhelming desire to kill [L]. They have been marked red! Go kill them!</span>")
|
||||
H.put_in_hands(new /obj/item/weapon/kitchen/knife/butcher(H))
|
||||
|
||||
qdel(src)
|
||||
|
||||
// Legion
|
||||
|
||||
// Staff of Storms
|
||||
|
||||
/obj/item/weapon/staff/storm
|
||||
name = "staff of storms"
|
||||
desc = "An ancient staff retrieved from the remains of Legion. The wind stirs as you move it."
|
||||
icon_state = "staffofstorms"
|
||||
item_state = "staffofstorms"
|
||||
icon = 'icons/obj/guns/magic.dmi'
|
||||
slot_flags = SLOT_BACK
|
||||
item_state = "staffofstorms"
|
||||
w_class = 4
|
||||
force = 25
|
||||
damtype = BURN
|
||||
hitsound = 'sound/weapons/sear.ogg'
|
||||
var/storm_type = /datum/weather/ash_storm
|
||||
var/storm_cooldown = 0
|
||||
|
||||
/obj/item/weapon/staff/storm/attack_self(mob/user)
|
||||
if(storm_cooldown > world.time)
|
||||
to_chat(user, "<span class='warning'>The staff is still recharging!</span>")
|
||||
return
|
||||
|
||||
var/area/user_area = get_area(user)
|
||||
var/datum/weather/A
|
||||
var/z_level_name = space_manager.levels_by_name[user.z]
|
||||
for(var/V in weather_master.existing_weather)
|
||||
var/datum/weather/W = V
|
||||
if(W.target_z == z_level_name && W.area_type == user_area.type)
|
||||
A = W
|
||||
break
|
||||
if(A)
|
||||
|
||||
if(A.stage != END_STAGE)
|
||||
if(A.stage == WIND_DOWN_STAGE)
|
||||
to_chat(user, "<span class='warning'>The storm is already ending! It would be a waste to use the staff now.</span>")
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] holds [src] skywards as an orange beam travels into the sky!</span>", \
|
||||
"<span class='notice'>You hold [src] skyward, dispelling the storm!</span>")
|
||||
playsound(user, 'sound/magic/Staff_Change.ogg', 200, 0)
|
||||
A.wind_down()
|
||||
return
|
||||
else
|
||||
A = new storm_type
|
||||
A.name = "staff storm"
|
||||
A.area_type = user_area.type
|
||||
A.target_z = z_level_name
|
||||
A.telegraph_duration = 100
|
||||
A.end_duration = 100
|
||||
|
||||
user.visible_message("<span class='warning'>[user] holds [src] skywards as red lightning crackles into the sky!</span>", \
|
||||
"<span class='notice'>You hold [src] skyward, calling down a terrible storm!</span>")
|
||||
playsound(user, 'sound/magic/Staff_Change.ogg', 200, 0)
|
||||
A.telegraph()
|
||||
storm_cooldown = world.time + 200
|
||||
|
||||
// Hierophant
|
||||
|
||||
//Hierophant
|
||||
|
||||
/obj/item/weapon/hierophant_staff
|
||||
name = "Hierophant's staff"
|
||||
desc = "A large club with intense magic power infused into it."
|
||||
icon_state = "hierophant_staff"
|
||||
item_state = "hierophant_staff"
|
||||
icon = 'icons/obj/guns/magic.dmi'
|
||||
slot_flags = SLOT_BACK
|
||||
w_class = 4
|
||||
force = 20
|
||||
hitsound = "swing_hit"
|
||||
//hitsound = 'sound/weapons/sonic_jackhammer.ogg'
|
||||
actions_types = list(/datum/action/item_action/vortex_recall, /datum/action/item_action/toggle_unfriendly_fire)
|
||||
var/cooldown_time = 20 //how long the cooldown between non-melee ranged attacks is
|
||||
var/chaser_cooldown = 101 //how long the cooldown between firing chasers at mobs is
|
||||
var/chaser_timer = 0 //what our current chaser cooldown is
|
||||
var/timer = 0 //what our current cooldown is
|
||||
var/blast_range = 3 //how long the cardinal blast's walls are
|
||||
var/obj/effect/hierophant/rune //the associated rune we teleport to
|
||||
var/teleporting = FALSE //if we ARE teleporting
|
||||
var/friendly_fire_check = FALSE //if the blasts we make will consider our faction against the faction of hit targets
|
||||
|
||||
/obj/item/weapon/hierophant_staff/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
||||
..()
|
||||
var/turf/T = get_turf(target)
|
||||
if(!T || timer > world.time)
|
||||
return
|
||||
timer = world.time + CLICK_CD_MELEE //by default, melee attacks only cause melee blasts, and have an accordingly short cooldown
|
||||
if(proximity_flag)
|
||||
spawn(0)
|
||||
aoe_burst(T, user)
|
||||
add_logs(user, target, "fired 3x3 blast at", src)
|
||||
else
|
||||
if(ismineralturf(target) && get_dist(user, target) < 6) //target is minerals, we can hit it(even if we can't see it)
|
||||
spawn(0)
|
||||
cardinal_blasts(T, user)
|
||||
timer = world.time + cooldown_time
|
||||
else if(target in view(5, get_turf(user))) //if the target is in view, hit it
|
||||
timer = world.time + cooldown_time
|
||||
if(isliving(target) && chaser_timer <= world.time) //living and chasers off cooldown? fire one!
|
||||
chaser_timer = world.time + chaser_cooldown
|
||||
new /obj/effect/overlay/temp/hierophant/chaser(get_turf(user), user, target, 1.5, friendly_fire_check)
|
||||
add_logs(user, target, "fired a chaser at", src)
|
||||
else
|
||||
spawn(0)
|
||||
cardinal_blasts(T, user) //otherwise, just do cardinal blast
|
||||
add_logs(user, target, "fired cardinal blast at", src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>That target is out of range!</span>") //too far away
|
||||
|
||||
/obj/item/weapon/hierophant_staff/ui_action_click(mob/user, actiontype)
|
||||
if(actiontype == /datum/action/item_action/toggle_unfriendly_fire) //toggle friendly fire...
|
||||
friendly_fire_check = !friendly_fire_check
|
||||
to_chat(user, "<span class='warning'>You toggle friendly fire [friendly_fire_check ? "off":"on"]!</span>")
|
||||
return
|
||||
if(user.get_active_hand() != src && user.get_inactive_hand() != src) //you need to hold the staff to teleport
|
||||
to_chat(user, "<span class='warning'>You need to hold the staff in your hands to [rune ? "teleport with it" : "create a rune"]!</span>")
|
||||
return
|
||||
if(!rune)
|
||||
if(isturf(user.loc))
|
||||
user.visible_message("<span class='hierophant_warning'>[user] holds [src] carefully in front of them, moving it in a strange pattern...</span>", \
|
||||
"<span class='notice'>You start creating a hierophant rune to teleport to...</span>")
|
||||
timer = world.time + 51
|
||||
if(do_after(user, 50, target = user))
|
||||
var/turf/T = get_turf(user)
|
||||
playsound(T,'sound/magic/Blind.ogg', 200, 1, -4)
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph/teleport(T, user)
|
||||
var/obj/effect/hierophant/H = new/obj/effect/hierophant(T)
|
||||
rune = H
|
||||
user.update_action_buttons_icon()
|
||||
user.visible_message("<span class='hierophant_warning'>[user] creates a strange rune beneath them!</span>", \
|
||||
"<span class='hierophant'>You create a hierophant rune, which you can teleport yourself and any allies to at any time!</span>\n\
|
||||
<span class='notice'>You can remove the rune to place a new one by striking it with the staff.</span>")
|
||||
else
|
||||
timer = world.time
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to be on solid ground to produce a rune!</span>")
|
||||
return
|
||||
if(get_dist(user, rune) <= 2) //rune too close abort
|
||||
to_chat(user, "<span class='warning'>You are too close to the rune to teleport to it!</span>")
|
||||
return
|
||||
if(is_blocked_turf(get_turf(rune)))
|
||||
to_chat(user, "<span class='warning'>The rune is blocked by something, preventing teleportation!</span>")
|
||||
return
|
||||
teleporting = TRUE //start channel
|
||||
user.update_action_buttons_icon()
|
||||
user.visible_message("<span class='hierophant_warning'>[user] starts to glow faintly...</span>")
|
||||
timer = world.time + 50
|
||||
if(do_after(user, 40, target = user) && rune)
|
||||
var/turf/T = get_turf(rune)
|
||||
var/turf/source = get_turf(user)
|
||||
if(is_blocked_turf(T))
|
||||
teleporting = FALSE
|
||||
to_chat(user, "<span class='warning'>The rune is blocked by something, preventing teleportation!</span>")
|
||||
user.update_action_buttons_icon()
|
||||
return
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph(T, user)
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph(source, user)
|
||||
playsound(T,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(T,'sound/magic/Wand_Teleport.ogg', 200, 1)
|
||||
playsound(source,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(source,'sound/machines/AirlockOpen.ogg', 200, 1)
|
||||
if(!do_after(user, 3, target = user) || !rune) //no walking away shitlord
|
||||
teleporting = FALSE
|
||||
if(user)
|
||||
user.update_action_buttons_icon()
|
||||
return
|
||||
if(is_blocked_turf(T))
|
||||
teleporting = FALSE
|
||||
to_chat(user, "<span class='warning'>The rune is blocked by something, preventing teleportation!</span>")
|
||||
user.update_action_buttons_icon()
|
||||
return
|
||||
add_logs(user, rune, "teleported self from ([source.x],[source.y],[source.z]) to")
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph/teleport(T, user)
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph/teleport(source, user)
|
||||
for(var/t in RANGE_TURFS(1, T))
|
||||
var/obj/effect/overlay/temp/hierophant/blast/B = new /obj/effect/overlay/temp/hierophant/blast(t, user, TRUE) //blasts produced will not hurt allies
|
||||
B.damage = 30
|
||||
for(var/t in RANGE_TURFS(1, source))
|
||||
var/obj/effect/overlay/temp/hierophant/blast/B = new /obj/effect/overlay/temp/hierophant/blast(t, user, TRUE) //but absolutely will hurt enemies
|
||||
B.damage = 30
|
||||
for(var/mob/living/L in range(1, source))
|
||||
spawn(0)
|
||||
teleport_mob(source, L, T, user) //regardless, take all mobs near us along
|
||||
sleep(6) //at this point the blasts detonate
|
||||
else
|
||||
timer = world.time
|
||||
teleporting = FALSE
|
||||
if(user)
|
||||
user.update_action_buttons_icon()
|
||||
|
||||
/obj/item/weapon/hierophant_staff/proc/teleport_mob(turf/source, mob/M, turf/target, mob/user)
|
||||
var/turf/turf_to_teleport_to = get_step(target, get_dir(source, M)) //get position relative to caster
|
||||
if(!turf_to_teleport_to || is_blocked_turf(turf_to_teleport_to))
|
||||
return
|
||||
animate(M, alpha = 0, time = 2, easing = EASE_OUT) //fade out
|
||||
sleep(1)
|
||||
if(!M)
|
||||
return
|
||||
M.visible_message("<span class='hierophant_warning'>[M] fades out!</span>")
|
||||
sleep(2)
|
||||
if(!M)
|
||||
return
|
||||
M.forceMove(turf_to_teleport_to)
|
||||
sleep(1)
|
||||
if(!M)
|
||||
return
|
||||
animate(M, alpha = 255, time = 2, easing = EASE_IN) //fade IN
|
||||
sleep(1)
|
||||
if(!M)
|
||||
return
|
||||
M.visible_message("<span class='hierophant_warning'>[M] fades in!</span>")
|
||||
if(user != M)
|
||||
add_logs(user, M, "teleported", null, "from ([source.x],[source.y],[source.z])")
|
||||
|
||||
/obj/item/weapon/hierophant_staff/proc/cardinal_blasts(turf/T, mob/living/user) //fire cardinal cross blasts with a delay
|
||||
if(!T)
|
||||
return
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph/cardinal(T, user)
|
||||
playsound(T,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
|
||||
sleep(2)
|
||||
new /obj/effect/overlay/temp/hierophant/blast(T, user, friendly_fire_check)
|
||||
for(var/d in cardinal)
|
||||
spawn(0)
|
||||
blast_wall(T, d, user)
|
||||
|
||||
/obj/item/weapon/hierophant_staff/proc/blast_wall(turf/T, dir, mob/living/user) //make a wall of blasts blast_range tiles long
|
||||
if(!T)
|
||||
return
|
||||
var/range = blast_range
|
||||
var/turf/previousturf = T
|
||||
var/turf/J = get_step(previousturf, dir)
|
||||
for(var/i in 1 to range)
|
||||
if(!J)
|
||||
return
|
||||
new /obj/effect/overlay/temp/hierophant/blast(J, user, friendly_fire_check)
|
||||
previousturf = J
|
||||
J = get_step(previousturf, dir)
|
||||
|
||||
/obj/item/weapon/hierophant_staff/proc/aoe_burst(turf/T, mob/living/user) //make a 3x3 blast around a target
|
||||
if(!T)
|
||||
return
|
||||
new /obj/effect/overlay/temp/hierophant/telegraph(T, user)
|
||||
playsound(T,'sound/magic/blink.ogg', 200, 1)
|
||||
//playsound(T,'sound/effects/bin_close.ogg', 200, 1)
|
||||
sleep(2)
|
||||
for(var/t in RANGE_TURFS(1, T))
|
||||
new /obj/effect/overlay/temp/hierophant/blast(t, user, friendly_fire_check)
|
||||
new /obj/item/clothing/head/helmet/space/rig/ert/paranormal/inquisitor(src)
|
||||
new /obj/item/clothing/suit/space/rig/ert/paranormal/inquisitor(src)
|
||||
if(24)
|
||||
new /obj/item/weapon/spellbook/oneuse/summonitem(src)
|
||||
@@ -200,7 +200,6 @@
|
||||
/obj/structure/closet/crate/miningcar
|
||||
desc = "A mining car. This one doesn't work on rails, but has to be dragged."
|
||||
name = "mining car (not for rails)"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "miningcar"
|
||||
density = 1
|
||||
icon_opened = "miningcaropen"
|
||||
|
||||
@@ -14,10 +14,6 @@
|
||||
/mob/camera/experience_pressure_difference()
|
||||
return
|
||||
|
||||
/mob/camera/Destroy()
|
||||
..()
|
||||
return QDEL_HINT_HARDDEL_NOW
|
||||
|
||||
/mob/camera/Login()
|
||||
..()
|
||||
update_interface()
|
||||
|
||||
@@ -309,7 +309,7 @@
|
||||
Stun(2)
|
||||
|
||||
var/obj/item/organ/internal/eyes/E = get_int_organ(/obj/item/organ/internal/eyes)
|
||||
if(!E)
|
||||
if(!E || (E && E.weld_proof))
|
||||
return
|
||||
|
||||
switch(damage)
|
||||
|
||||
@@ -721,8 +721,6 @@
|
||||
if(istype(id))
|
||||
return id
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_sight()
|
||||
if(!client)
|
||||
return
|
||||
@@ -1533,12 +1531,6 @@
|
||||
if(species.default_language)
|
||||
add_language(species.default_language)
|
||||
|
||||
see_in_dark = species.darksight
|
||||
if(see_in_dark > 2)
|
||||
see_invisible = SEE_INVISIBLE_LEVEL_ONE
|
||||
else
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
|
||||
hunger_drain = species.hunger_drain
|
||||
digestion_ratio = species.digestion_ratio
|
||||
|
||||
@@ -1608,8 +1600,17 @@
|
||||
dna.real_name = real_name
|
||||
|
||||
species.handle_post_spawn(src)
|
||||
|
||||
see_in_dark = species.get_resultant_darksight(src)
|
||||
if(see_in_dark > 2)
|
||||
see_invisible = SEE_INVISIBLE_LEVEL_ONE
|
||||
else
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
|
||||
species.handle_dna(src) //Give them whatever special dna business they got.
|
||||
|
||||
update_client_colour(0)
|
||||
|
||||
spawn(0)
|
||||
overlays.Cut()
|
||||
update_mutantrace(1)
|
||||
@@ -1632,7 +1633,6 @@
|
||||
return null
|
||||
return species.default_language ? all_languages[species.default_language] : null
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/bloody_doodle()
|
||||
set category = "IC"
|
||||
set name = "Write in blood"
|
||||
|
||||
@@ -119,6 +119,7 @@
|
||||
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view)
|
||||
update_sight()
|
||||
update_inv_glasses()
|
||||
update_client_colour()
|
||||
else if(I == head)
|
||||
head = null
|
||||
if(I.flags & BLOCKHAIR || I.flags & BLOCKHEADHAIR)
|
||||
@@ -271,6 +272,7 @@
|
||||
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view)
|
||||
update_sight()
|
||||
update_inv_glasses(redraw_mob)
|
||||
update_client_colour()
|
||||
if(slot_gloves)
|
||||
gloves = W
|
||||
update_inv_gloves(redraw_mob)
|
||||
|
||||
@@ -7,8 +7,16 @@
|
||||
language = "Abductor Mindlink"
|
||||
default_language = "Abductor Mindlink"
|
||||
unarmed_type = /datum/unarmed_attack/punch
|
||||
darksight = 3
|
||||
eyes = "blank_eyes"
|
||||
has_organ = list(
|
||||
"heart" = /obj/item/organ/internal/heart,
|
||||
"lungs" = /obj/item/organ/internal/lungs,
|
||||
"liver" = /obj/item/organ/internal/liver,
|
||||
"kidneys" = /obj/item/organ/internal/kidneys,
|
||||
"brain" = /obj/item/organ/internal/brain,
|
||||
"appendix" = /obj/item/organ/internal/appendix,
|
||||
"eyes" = /obj/item/organ/internal/eyes/abductor //3 darksight.
|
||||
)
|
||||
|
||||
flags = HAS_LIPS | NO_BLOOD | NO_BREATHE
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
punchdamagelow = 0
|
||||
punchdamagehigh = 1
|
||||
//primitive = /mob/living/carbon/monkey/wryn
|
||||
darksight = 3
|
||||
slowdown = 1
|
||||
warning_low_pressure = -300
|
||||
hazard_low_pressure = 1
|
||||
@@ -32,7 +31,7 @@
|
||||
has_organ = list(
|
||||
"heart" = /obj/item/organ/internal/heart,
|
||||
"brain" = /obj/item/organ/internal/brain,
|
||||
"eyes" = /obj/item/organ/internal/eyes,
|
||||
"eyes" = /obj/item/organ/internal/eyes/wryn, //3 darksight.
|
||||
"appendix" = /obj/item/organ/internal/appendix,
|
||||
"antennae" = /obj/item/organ/internal/wryn/hivenode
|
||||
)
|
||||
@@ -89,7 +88,7 @@
|
||||
name_plural = "Nucleations"
|
||||
icobase = 'icons/mob/human_races/r_nucleation.dmi'
|
||||
unarmed_type = /datum/unarmed_attack/punch
|
||||
blurb = "A sub-race of unforunates who have been exposed to too much supermatter radiation. As a result, \
|
||||
blurb = "A sub-race of unfortunates who have been exposed to too much supermatter radiation. As a result, \
|
||||
supermatter crystal clusters have begun to grow across their bodies. Research to find a cure for this ailment \
|
||||
has been slow, and so this is a common fate for veteran engineers. The supermatter crystals produce oxygen, \
|
||||
negating the need for the individual to breathe. Their massive change in biology, however, renders most medicines \
|
||||
@@ -109,8 +108,8 @@
|
||||
reagent_tag = PROCESS_ORG
|
||||
has_organ = list(
|
||||
"heart" = /obj/item/organ/internal/heart,
|
||||
"crystalized brain" = /obj/item/organ/internal/brain/crystal,
|
||||
"eyes" = /obj/item/organ/internal/eyes/luminescent_crystal,
|
||||
"crystallized brain" = /obj/item/organ/internal/brain/crystal,
|
||||
"eyes" = /obj/item/organ/internal/eyes/luminescent_crystal, //Standard darksight of 2.
|
||||
"strange crystal" = /obj/item/organ/internal/nucleation/strange_crystal,
|
||||
"resonant crystal" = /obj/item/organ/internal/nucleation/resonant_crystal
|
||||
)
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
|
||||
has_organ = list(
|
||||
"brain" = /obj/item/organ/internal/brain/golem
|
||||
)
|
||||
) //Has standard darksight of 2.
|
||||
|
||||
suicide_messages = list(
|
||||
"is crumbling into dust!",
|
||||
"is smashing their body apart!")
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
tail = "chimptail"
|
||||
bodyflags = FEET_PADDED | HAS_TAIL
|
||||
reagent_tag = PROCESS_ORG
|
||||
//Has standard darksight of 2.
|
||||
|
||||
//unarmed_types = list(/datum/unarmed_attack/bite, /datum/unarmed_attack/claws)
|
||||
//inherent_verbs = list(/mob/living/proc/ventcrawl)
|
||||
@@ -54,7 +55,7 @@
|
||||
|
||||
/datum/species/monkey/handle_dna(var/mob/living/carbon/human/H)
|
||||
H.dna.SetSEState(MONKEYBLOCK,1)
|
||||
genemutcheck(H, MONKEYBLOCK)
|
||||
genemutcheck(H,MONKEYBLOCK,null,MUTCHK_FORCED)
|
||||
|
||||
/datum/species/monkey/handle_can_equip(obj/item/I, slot, disable_warning = 0, mob/living/carbon/human/user)
|
||||
switch(slot)
|
||||
@@ -105,6 +106,15 @@
|
||||
base_color = "#000000"
|
||||
tail = "farwatail"
|
||||
reagent_tag = PROCESS_ORG
|
||||
has_organ = list(
|
||||
"heart" = /obj/item/organ/internal/heart,
|
||||
"lungs" = /obj/item/organ/internal/lungs,
|
||||
"liver" = /obj/item/organ/internal/liver/tajaran,
|
||||
"kidneys" = /obj/item/organ/internal/kidneys,
|
||||
"brain" = /obj/item/organ/internal/brain,
|
||||
"appendix" = /obj/item/organ/internal/appendix,
|
||||
"eyes" = /obj/item/organ/internal/eyes/tajaran/farwa //Tajara monkey-forms are uniquely colourblind and have excellent darksight, which is why they need a subtype of their greater-form's organ..
|
||||
)
|
||||
|
||||
|
||||
/datum/species/monkey/vulpkanin
|
||||
@@ -120,6 +130,15 @@
|
||||
base_color = "#000000"
|
||||
tail = "wolpintail"
|
||||
reagent_tag = PROCESS_ORG
|
||||
has_organ = list(
|
||||
"heart" = /obj/item/organ/internal/heart,
|
||||
"lungs" = /obj/item/organ/internal/lungs,
|
||||
"liver" = /obj/item/organ/internal/liver/vulpkanin,
|
||||
"kidneys" = /obj/item/organ/internal/kidneys,
|
||||
"brain" = /obj/item/organ/internal/brain,
|
||||
"appendix" = /obj/item/organ/internal/appendix,
|
||||
"eyes" = /obj/item/organ/internal/eyes/vulpkanin/wolpin //Vulpkanin monkey-forms are uniquely colourblind and have excellent darksight, which is why they need a subtype of their greater-form's organ..
|
||||
)
|
||||
|
||||
|
||||
/datum/species/monkey/skrell
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
heat_level_2 = 400 // Heat damage level 2 above this point.
|
||||
heat_level_3 = 500 // Heat damage level 3 above this point.
|
||||
|
||||
//Has default darksight of 2.
|
||||
|
||||
suicide_messages = list(
|
||||
"is twisting their own neck!",
|
||||
"is letting some O2 in!",
|
||||
|
||||
@@ -7,15 +7,14 @@
|
||||
|
||||
default_language = "Galactic Common"
|
||||
unarmed_type = /datum/unarmed_attack/claws
|
||||
|
||||
darksight = 8
|
||||
|
||||
|
||||
ignored_by = list(/mob/living/simple_animal/hostile/faithless)
|
||||
|
||||
blood_color = "#CCCCCC"
|
||||
flesh_color = "#AAAAAA"
|
||||
has_organ = list(
|
||||
"brain" = /obj/item/organ/internal/brain
|
||||
"brain" = /obj/item/organ/internal/brain,
|
||||
"eyes" = /obj/item/organ/internal/eyes/shadow //8 darksight.
|
||||
)
|
||||
|
||||
flags = NO_BLOOD | NO_BREATHE | RADIMMUNE
|
||||
@@ -23,7 +22,7 @@
|
||||
oxy_mod = 0
|
||||
|
||||
virus_immune = 1
|
||||
|
||||
|
||||
dietflags = DIET_OMNI //the mutation process allowed you to now digest all foods regardless of initial race
|
||||
reagent_tag = PROCESS_ORG
|
||||
suicide_messages = list(
|
||||
@@ -31,10 +30,10 @@
|
||||
"is jamming their claws into their eye sockets!",
|
||||
"is twisting their own neck!",
|
||||
"is staring into the closest light source!")
|
||||
|
||||
|
||||
var/grant_vision_toggle = 1
|
||||
var/datum/action/innate/shadow/darkvision/vision_toggle
|
||||
|
||||
|
||||
/datum/action/innate/shadow/darkvision //Darkvision toggle so shadowpeople can actually see where darkness is
|
||||
name = "Toggle Darkvision"
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
@@ -49,13 +48,13 @@
|
||||
else
|
||||
H.vision_type = null
|
||||
to_chat(H, "<span class='notice'>You adjust your vision to recognize the shadows.</span>")
|
||||
|
||||
|
||||
/datum/species/shadow/grant_abilities(var/mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
if(grant_vision_toggle)
|
||||
vision_toggle = new
|
||||
vision_toggle.Grant(H)
|
||||
|
||||
|
||||
/datum/species/shadow/remove_abilities(var/mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
if(grant_vision_toggle && vision_toggle)
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
"is twisting their skull off!")
|
||||
has_organ = list(
|
||||
"brain" = /obj/item/organ/internal/brain/golem,
|
||||
)
|
||||
) //Has default darksight of 2.
|
||||
|
||||
/datum/species/skeleton/handle_reagents(var/mob/living/carbon/human/H, var/datum/reagent/R)
|
||||
// Crazylemon is still silly
|
||||
|
||||
@@ -49,8 +49,7 @@
|
||||
var/siemens_coeff = 1 //base electrocution coefficient
|
||||
|
||||
var/invis_sight = SEE_INVISIBLE_LIVING
|
||||
var/darksight = 2
|
||||
|
||||
|
||||
var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure.
|
||||
var/warning_high_pressure = WARNING_HIGH_PRESSURE // High pressure warning.
|
||||
var/warning_low_pressure = WARNING_LOW_PRESSURE // Low pressure warning.
|
||||
@@ -85,7 +84,7 @@
|
||||
|
||||
var/ventcrawler = 0 //Determines if the mob can go through the vents.
|
||||
var/has_fine_manipulation = 1 // Can use small items.
|
||||
|
||||
|
||||
var/mob/living/list/ignored_by = list() // list of mobs that will ignore this species
|
||||
|
||||
var/list/allowed_consumed_mobs = list() //If a species can consume mobs, put the type of mobs it can consume here.
|
||||
@@ -588,12 +587,23 @@ It'll return null if the organ doesn't correspond, so include null checks when u
|
||||
return null
|
||||
return has_organ[organ_slot]
|
||||
|
||||
/datum/species/proc/get_resultant_darksight(mob/living/carbon/human/H) //Returns default value of 2 if the mob doesn't have eyes, otherwise it grabs the eyes darksight.
|
||||
var/resultant_darksight = 2
|
||||
var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes)
|
||||
if(eyes)
|
||||
resultant_darksight = eyes.get_dark_view()
|
||||
return resultant_darksight
|
||||
|
||||
/datum/species/proc/update_sight(mob/living/carbon/human/H)
|
||||
H.sight = initial(H.sight)
|
||||
H.see_in_dark = darksight
|
||||
H.see_in_dark = get_resultant_darksight(H)
|
||||
H.see_invisible = invis_sight
|
||||
|
||||
if(H.see_in_dark > 2) //Preliminary see_invisible handling as per set_species() in code\modules\mob\living\carbon\human\human.dm.
|
||||
H.see_invisible = SEE_INVISIBLE_LEVEL_ONE
|
||||
else
|
||||
H.see_invisible = SEE_INVISIBLE_LIVING
|
||||
|
||||
if(H.client.eye != H)
|
||||
var/atom/A = H.client.eye
|
||||
if(A.update_remote_sight(H)) //returns 1 if we override all other sight updates.
|
||||
@@ -644,7 +654,7 @@ It'll return null if the organ doesn't correspond, so include null checks when u
|
||||
if(rig.visor && rig.visor.vision && rig.visor.active && rig.visor.vision.glasses)
|
||||
var/obj/item/clothing/glasses/G = rig.visor.vision.glasses
|
||||
if(istype(G))
|
||||
H.see_in_dark = (G.darkness_view ? G.darkness_view : darksight) // Otherwise we keep our darkness view with togglable nightvision.
|
||||
H.see_in_dark = (G.darkness_view ? G.darkness_view : get_resultant_darksight(H)) // Otherwise we keep our darkness view with togglable nightvision.
|
||||
if(G.vision_flags) // MESONS
|
||||
H.sight |= G.vision_flags
|
||||
|
||||
@@ -654,7 +664,7 @@ It'll return null if the organ doesn't correspond, so include null checks when u
|
||||
H.see_in_dark = max(lesser_darkview_bonus, H.see_in_dark)
|
||||
|
||||
if(H.vision_type)
|
||||
H.see_in_dark = max(H.see_in_dark, H.vision_type.see_in_dark, darksight)
|
||||
H.see_in_dark = max(H.see_in_dark, H.vision_type.see_in_dark, get_resultant_darksight(H))
|
||||
H.see_invisible = H.vision_type.see_invisible
|
||||
if(H.vision_type.light_sensitive)
|
||||
H.weakeyes = 1
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
worlds tumultous at best."
|
||||
|
||||
reagent_tag = PROCESS_ORG
|
||||
//Has standard darksight of 2.
|
||||
|
||||
/datum/species/unathi
|
||||
name = "Unathi"
|
||||
@@ -30,7 +31,6 @@
|
||||
tail = "sogtail"
|
||||
unarmed_type = /datum/unarmed_attack/claws
|
||||
primitive_form = "Stok"
|
||||
darksight = 3
|
||||
|
||||
blurb = "A heavily reptillian species, Unathi (or 'Sinta as they call themselves) hail from the \
|
||||
Uuosa-Eso system, which roughly translates to 'burning mother'.<br/><br/>Coming from a harsh, radioactive \
|
||||
@@ -66,7 +66,7 @@
|
||||
"kidneys" = /obj/item/organ/internal/kidneys,
|
||||
"brain" = /obj/item/organ/internal/brain,
|
||||
"appendix" = /obj/item/organ/internal/appendix,
|
||||
"eyes" = /obj/item/organ/internal/eyes,
|
||||
"eyes" = /obj/item/organ/internal/eyes/unathi //3 darksight.
|
||||
)
|
||||
|
||||
allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/lizard, /mob/living/simple_animal/chick, /mob/living/simple_animal/chicken,
|
||||
@@ -91,7 +91,6 @@
|
||||
language = "Siik'tajr"
|
||||
tail = "tajtail"
|
||||
unarmed_type = /datum/unarmed_attack/claws
|
||||
darksight = 8
|
||||
|
||||
blurb = "The Tajaran race is a species of feline-like bipeds hailing from the planet of Ahdomai in the \
|
||||
S'randarr system. They have been brought up into the space age by the Humans and Skrell, and have been \
|
||||
@@ -126,7 +125,8 @@
|
||||
"kidneys" = /obj/item/organ/internal/kidneys,
|
||||
"brain" = /obj/item/organ/internal/brain,
|
||||
"appendix" = /obj/item/organ/internal/appendix,
|
||||
"eyes" = /obj/item/organ/internal/eyes,
|
||||
"eyes" = /obj/item/organ/internal/eyes/tajaran /*Most Tajara see in full colour as a result of genetic augmentation, although it cost them their darksight (darksight = 2)
|
||||
unless they choose otherwise by selecting the colourblind disability in character creation (darksight = 8 but colourblind).*/
|
||||
)
|
||||
|
||||
allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/chick, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot,
|
||||
@@ -152,7 +152,6 @@
|
||||
primitive_form = "Wolpin"
|
||||
tail = "vulptail"
|
||||
unarmed_type = /datum/unarmed_attack/claws
|
||||
darksight = 8
|
||||
|
||||
blurb = "Vulpkanin are a species of sharp-witted canine-pideds residing on the planet Altam just barely within the \
|
||||
dual-star Vazzend system. Their politically de-centralized society and independent natures have led them to become a species and \
|
||||
@@ -176,7 +175,8 @@
|
||||
"kidneys" = /obj/item/organ/internal/kidneys,
|
||||
"brain" = /obj/item/organ/internal/brain,
|
||||
"appendix" = /obj/item/organ/internal/appendix,
|
||||
"eyes" = /obj/item/organ/internal/eyes,
|
||||
"eyes" = /obj/item/organ/internal/eyes/vulpkanin /*Most Vulpkanin see in full colour as a result of genetic augmentation, although it cost them their darksight (darksight = 2)
|
||||
unless they choose otherwise by selecting the colourblind disability in character creation (darksight = 8 but colourblind).*/
|
||||
)
|
||||
|
||||
allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/lizard, /mob/living/simple_animal/chick, /mob/living/simple_animal/chicken,
|
||||
@@ -226,7 +226,7 @@
|
||||
"kidneys" = /obj/item/organ/internal/kidneys,
|
||||
"brain" = /obj/item/organ/internal/brain,
|
||||
"appendix" = /obj/item/organ/internal/appendix,
|
||||
"eyes" = /obj/item/organ/internal/eyes,
|
||||
"eyes" = /obj/item/organ/internal/eyes //Default darksight of 2.
|
||||
)
|
||||
|
||||
suicide_messages = list(
|
||||
@@ -315,7 +315,7 @@
|
||||
"kidneys" = /obj/item/organ/internal/kidneys,
|
||||
"brain" = /obj/item/organ/internal/brain,
|
||||
"appendix" = /obj/item/organ/internal/appendix,
|
||||
"eyes" = /obj/item/organ/internal/eyes,
|
||||
"eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2.
|
||||
"stack" = /obj/item/organ/internal/stack/vox //Not the same as the cortical stack implant Vox Raiders spawn with. The cortical stack implant is used
|
||||
) //for determining the success of the heist game-mode's 'leave nobody behind' objective, while this is just an organ.
|
||||
|
||||
@@ -439,7 +439,7 @@
|
||||
"liver" = /obj/item/organ/internal/liver,
|
||||
"kidneys" = /obj/item/organ/internal/kidneys,
|
||||
"brain" = /obj/item/organ/internal/brain,
|
||||
"eyes" = /obj/item/organ/internal/eyes,
|
||||
"eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2.
|
||||
"stack" = /obj/item/organ/internal/stack/vox //Not the same as the cortical stack implant Vox Raiders spawn with. The cortical stack implant is used
|
||||
) //for determining the success of the heist game-mode's 'leave nobody behind' objective, while this is just an organ.
|
||||
|
||||
@@ -478,7 +478,7 @@
|
||||
"kidneys" = /obj/item/organ/internal/kidneys,
|
||||
"brain" = /obj/item/organ/internal/brain,
|
||||
"appendix" = /obj/item/organ/internal/appendix,
|
||||
"eyes" = /obj/item/organ/internal/eyes,
|
||||
"eyes" = /obj/item/organ/internal/eyes //Default darksight of 2.
|
||||
)
|
||||
|
||||
allowed_consumed_mobs = list(/mob/living/simple_animal/diona)
|
||||
@@ -517,6 +517,7 @@
|
||||
exotic_blood = "water"
|
||||
//ventcrawler = 1 //ventcrawling commented out
|
||||
butt_sprite = "slime"
|
||||
//Has default darksight of 2.
|
||||
|
||||
has_organ = list(
|
||||
"brain" = /obj/item/organ/internal/brain/slime
|
||||
@@ -685,7 +686,6 @@
|
||||
default_language = "Galactic Common"
|
||||
language = "Psionic Communication"
|
||||
unarmed_type = /datum/unarmed_attack/punch
|
||||
darksight = 5 // BOOSTED from 2
|
||||
eyes = "grey_eyes_s"
|
||||
butt_sprite = "grey"
|
||||
|
||||
@@ -696,7 +696,7 @@
|
||||
"kidneys" = /obj/item/organ/internal/kidneys,
|
||||
"brain" = /obj/item/organ/internal/brain/grey,
|
||||
"appendix" = /obj/item/organ/internal/appendix,
|
||||
"eyes" = /obj/item/organ/internal/eyes,
|
||||
"eyes" = /obj/item/organ/internal/eyes/grey //5 darksight.
|
||||
)
|
||||
|
||||
brute_mod = 1.25 //greys are fragile
|
||||
@@ -714,11 +714,9 @@
|
||||
/datum/species/grey/handle_dna(var/mob/living/carbon/C, var/remove)
|
||||
if(!remove)
|
||||
C.dna.SetSEState(REMOTETALKBLOCK,1,1)
|
||||
C.mutations |= REMOTE_TALK
|
||||
genemutcheck(C,REMOTETALKBLOCK,null,MUTCHK_FORCED)
|
||||
else
|
||||
C.dna.SetSEState(REMOTETALKBLOCK,0,1)
|
||||
C.mutations -= REMOTE_TALK
|
||||
genemutcheck(C,REMOTETALKBLOCK,null,MUTCHK_FORCED)
|
||||
..()
|
||||
|
||||
@@ -771,13 +769,13 @@
|
||||
has_organ = list(
|
||||
"nutrient channel" = /obj/item/organ/internal/liver/diona,
|
||||
"neural strata" = /obj/item/organ/internal/heart/diona,
|
||||
"receptor node" = /obj/item/organ/internal/diona_receptor,
|
||||
"receptor node" = /obj/item/organ/internal/eyes/diona, //Default darksight of 2.
|
||||
"gas bladder" = /obj/item/organ/internal/brain/diona,
|
||||
"polyp segment" = /obj/item/organ/internal/kidneys/diona,
|
||||
"anchoring ligament" = /obj/item/organ/internal/appendix/diona
|
||||
)
|
||||
|
||||
vision_organ = /obj/item/organ/internal/diona_receptor
|
||||
vision_organ = /obj/item/organ/internal/eyes/diona
|
||||
has_limbs = list(
|
||||
"chest" = list("path" = /obj/item/organ/external/chest/diona),
|
||||
"groin" = list("path" = /obj/item/organ/external/groin/diona),
|
||||
@@ -883,10 +881,10 @@
|
||||
has_organ = list(
|
||||
"brain" = /obj/item/organ/internal/brain/mmi_holder/posibrain,
|
||||
"cell" = /obj/item/organ/internal/cell,
|
||||
"optics" = /obj/item/organ/internal/optical_sensor
|
||||
"optics" = /obj/item/organ/internal/eyes/optical_sensor //Default darksight of 2.
|
||||
)
|
||||
|
||||
vision_organ = /obj/item/organ/internal/optical_sensor
|
||||
vision_organ = /obj/item/organ/internal/eyes/optical_sensor
|
||||
has_limbs = list(
|
||||
"chest" = list("path" = /obj/item/organ/external/chest/ipc),
|
||||
"groin" = list("path" = /obj/item/organ/external/groin/ipc),
|
||||
@@ -932,7 +930,6 @@
|
||||
language = "Orluum"
|
||||
unarmed_type = /datum/unarmed_attack/punch
|
||||
eyes = "drask_eyes_s"
|
||||
darksight = 5
|
||||
|
||||
speech_sounds = list('sound/voice/DraskTalk.ogg')
|
||||
speech_chance = 20
|
||||
@@ -982,7 +979,7 @@
|
||||
"heart" = /obj/item/organ/internal/heart/drask,
|
||||
"lungs" = /obj/item/organ/internal/lungs/drask,
|
||||
"metabolic strainer" = /obj/item/organ/internal/liver/drask,
|
||||
"eyes" = /obj/item/organ/internal/eyes/drask,
|
||||
"eyes" = /obj/item/organ/internal/eyes/drask, //5 darksight.
|
||||
"brain" = /obj/item/organ/internal/brain/drask
|
||||
)
|
||||
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
/mob/living/Destroy()
|
||||
if(ranged_ability)
|
||||
ranged_ability.remove_ranged_ability(src)
|
||||
..()
|
||||
return QDEL_HINT_HARDDEL_NOW
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/ghostize(can_reenter_corpse = 1)
|
||||
var/prev_client = client
|
||||
if(..())
|
||||
@@ -48,14 +47,14 @@
|
||||
set category = "Object"
|
||||
|
||||
if(AM.Adjacent(src))
|
||||
src.start_pulling(AM)
|
||||
start_pulling(AM)
|
||||
return
|
||||
|
||||
//same as above
|
||||
/mob/living/pointed(atom/A as mob|obj|turf in view())
|
||||
if(incapacitated())
|
||||
return 0
|
||||
if(src.status_flags & FAKEDEATH)
|
||||
if(status_flags & FAKEDEATH)
|
||||
return 0
|
||||
if(!..())
|
||||
return 0
|
||||
@@ -78,7 +77,7 @@
|
||||
to_chat(src, "<span class='notice'>You have given up life and succumbed to death.</span>")
|
||||
|
||||
/mob/living/proc/InCritical()
|
||||
return (src.health < 0 && src.health > -95.0 && stat == UNCONSCIOUS)
|
||||
return (health < 0 && health > -95.0 && stat == UNCONSCIOUS)
|
||||
|
||||
/mob/living/ex_act(severity)
|
||||
..()
|
||||
@@ -114,7 +113,7 @@
|
||||
if(actual < desired)
|
||||
temperature = desired
|
||||
// if(istype(src, /mob/living/carbon/human))
|
||||
// to_chat(world, "[src] ~ [src.bodytemperature] ~ [temperature]")
|
||||
// to_chat(world, "[src] ~ [bodytemperature] ~ [temperature]")
|
||||
return temperature
|
||||
|
||||
|
||||
@@ -228,29 +227,31 @@
|
||||
|
||||
else
|
||||
|
||||
L += src.contents
|
||||
for(var/obj/item/weapon/storage/S in src.contents) //Check for storage items
|
||||
L += contents
|
||||
for(var/obj/item/weapon/storage/S in contents) //Check for storage items
|
||||
L += get_contents(S)
|
||||
for(var/obj/item/clothing/suit/storage/S in src.contents)//Check for labcoats and jackets
|
||||
for(var/obj/item/clothing/suit/storage/S in contents)//Check for labcoats and jackets
|
||||
L += get_contents(S)
|
||||
for(var/obj/item/clothing/accessory/storage/S in src.contents)//Check for holsters
|
||||
for(var/obj/item/clothing/accessory/storage/S in contents)//Check for holsters
|
||||
L += get_contents(S)
|
||||
for(var/obj/item/weapon/gift/G in src.contents) //Check for gift-wrapped items
|
||||
for(var/obj/item/weapon/implant/storage/I in contents) //Check for storage implants.
|
||||
L += I.get_contents()
|
||||
for(var/obj/item/weapon/gift/G in contents) //Check for gift-wrapped items
|
||||
L += G.gift
|
||||
if(istype(G.gift, /obj/item/weapon/storage))
|
||||
L += get_contents(G.gift)
|
||||
|
||||
for(var/obj/item/smallDelivery/D in src.contents) //Check for package wrapped items
|
||||
for(var/obj/item/smallDelivery/D in contents) //Check for package wrapped items
|
||||
L += D.wrapped
|
||||
if(istype(D.wrapped, /obj/item/weapon/storage)) //this should never happen
|
||||
L += get_contents(D.wrapped)
|
||||
for(var/obj/item/weapon/folder/F in src.contents)
|
||||
for(var/obj/item/weapon/folder/F in contents)
|
||||
L += F.contents //Folders can't store any storage items.
|
||||
|
||||
return L
|
||||
|
||||
/mob/living/proc/check_contents_for(A)
|
||||
var/list/L = src.get_contents()
|
||||
var/list/L = get_contents()
|
||||
|
||||
for(var/obj/B in L)
|
||||
if(B.type == A)
|
||||
@@ -273,27 +274,27 @@
|
||||
/mob/living/proc/heal_organ_damage(var/brute, var/burn)
|
||||
adjustBruteLoss(-brute)
|
||||
adjustFireLoss(-burn)
|
||||
src.updatehealth()
|
||||
updatehealth()
|
||||
|
||||
// damage ONE external organ, organ gets randomly selected from damaged ones.
|
||||
/mob/living/proc/take_organ_damage(var/brute, var/burn)
|
||||
if(status_flags & GODMODE) return 0 //godmode
|
||||
adjustBruteLoss(brute)
|
||||
adjustFireLoss(burn)
|
||||
src.updatehealth()
|
||||
updatehealth()
|
||||
|
||||
// heal MANY external organs, in random order
|
||||
/mob/living/proc/heal_overall_damage(var/brute, var/burn)
|
||||
adjustBruteLoss(-brute)
|
||||
adjustFireLoss(-burn)
|
||||
src.updatehealth()
|
||||
updatehealth()
|
||||
|
||||
// damage MANY external organs, in random order
|
||||
/mob/living/proc/take_overall_damage(var/brute, var/burn, var/used_weapon = null)
|
||||
if(status_flags & GODMODE) return 0 //godmode
|
||||
adjustBruteLoss(brute)
|
||||
adjustFireLoss(burn)
|
||||
src.updatehealth()
|
||||
updatehealth()
|
||||
|
||||
/mob/living/proc/has_organic_damage()
|
||||
return (maxHealth - health)
|
||||
@@ -367,7 +368,7 @@
|
||||
if(buckled) //Unbuckle the mob and clear the alerts.
|
||||
buckled.buckled_mob = null
|
||||
buckled = null
|
||||
anchored = initial(src.anchored)
|
||||
anchored = initial(anchored)
|
||||
update_canmove()
|
||||
clear_alert("buckled")
|
||||
post_buckle_mob(src)
|
||||
@@ -655,7 +656,7 @@
|
||||
// The src mob is trying to place an item on someone
|
||||
// Override if a certain mob should be behave differently when placing items (can't, for example)
|
||||
/mob/living/stripPanelEquip(obj/item/what, mob/who, where, var/silent = 0)
|
||||
what = src.get_active_hand()
|
||||
what = get_active_hand()
|
||||
if(what && (what.flags & NODROP))
|
||||
to_chat(src, "<span class='warning'>You can't put \the [what.name] on [who], it's stuck to your hand!</span>")
|
||||
return
|
||||
|
||||
@@ -52,5 +52,7 @@
|
||||
var/list/surgeries = list() //a list of surgery datums. generally empty, they're added when the player wants them.
|
||||
|
||||
var/gene_stability = DEFAULT_GENE_STABILITY
|
||||
|
||||
|
||||
var/obj/effect/proc_holder/ranged_ability //Any ranged ability the mob has, as a click override
|
||||
|
||||
var/list/say_log = list() //a log of what we've said, plain text, no spans or junk, essentially just each individual "message"
|
||||
|
||||
@@ -149,7 +149,7 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
if(speaking && (speaking.flags & HIVEMIND))
|
||||
speaking.broadcast(src,trim(message))
|
||||
return 1
|
||||
|
||||
|
||||
if(message_mode == "cords")
|
||||
if(iscarbon(src))
|
||||
var/mob/living/carbon/C = src
|
||||
@@ -282,6 +282,9 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
if(O) //It's possible that it could be deleted in the meantime.
|
||||
O.hear_talk(src, message, verb, speaking)
|
||||
|
||||
//Log of what we've said, plain message, no spans or junk
|
||||
say_log += message
|
||||
|
||||
log_say("[name]/[key] : [message]")
|
||||
return 1
|
||||
|
||||
|
||||
@@ -47,17 +47,17 @@
|
||||
real_name = name
|
||||
|
||||
add_language("Rootspeak")
|
||||
src.verbs += /mob/living/simple_animal/diona/proc/merge
|
||||
verbs += /mob/living/simple_animal/diona/proc/merge
|
||||
|
||||
/mob/living/simple_animal/diona/attack_hand(mob/living/carbon/human/M as mob)
|
||||
/mob/living/simple_animal/diona/attack_hand(mob/living/carbon/human/M)
|
||||
//Let people pick the little buggers up.
|
||||
if(M.a_intent == I_HELP)
|
||||
if(M.species && M.species.name == "Diona")
|
||||
to_chat(M, "You feel your being twine with that of [src] as it merges with your biomass.")
|
||||
to_chat(src, "You feel your being twine with that of [M] as you merge with its biomass.")
|
||||
src.verbs += /mob/living/simple_animal/diona/proc/split
|
||||
src.verbs -= /mob/living/simple_animal/diona/proc/merge
|
||||
src.forceMove(M)
|
||||
verbs += /mob/living/simple_animal/diona/proc/split
|
||||
verbs -= /mob/living/simple_animal/diona/proc/merge
|
||||
forceMove(M)
|
||||
else
|
||||
get_scooped(M)
|
||||
|
||||
@@ -68,32 +68,34 @@
|
||||
set name = "Merge with gestalt"
|
||||
set desc = "Merge with another diona."
|
||||
|
||||
if(istype(src.loc,/mob/living/carbon))
|
||||
src.verbs -= /mob/living/simple_animal/diona/proc/merge
|
||||
if(iscarbon(loc))
|
||||
verbs -= /mob/living/simple_animal/diona/proc/merge
|
||||
return
|
||||
|
||||
var/list/choices = list()
|
||||
for(var/mob/living/carbon/C in view(1,src))
|
||||
|
||||
if(!(src.Adjacent(C)) || !(C.client)) continue
|
||||
if(!(Adjacent(C)) || !(C.client))
|
||||
continue
|
||||
|
||||
if(istype(C,/mob/living/carbon/human))
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/D = C
|
||||
if(D.species && D.species.name == "Diona")
|
||||
choices += C
|
||||
|
||||
var/mob/living/M = input(src,"Who do you wish to merge with?") in null|choices
|
||||
|
||||
if(!M || !src || !(src.Adjacent(M))) return
|
||||
if(!M || !src || !(Adjacent(M)))
|
||||
return
|
||||
|
||||
if(istype(M,/mob/living/carbon/human))
|
||||
if(ishuman(M))
|
||||
to_chat(M, "You feel your being twine with that of [src] as it merges with your biomass.")
|
||||
M.status_flags |= PASSEMOTES
|
||||
|
||||
to_chat(src, "You feel your being twine with that of [M] as you merge with its biomass.")
|
||||
src.loc = M
|
||||
src.verbs += /mob/living/simple_animal/diona/proc/split
|
||||
src.verbs -= /mob/living/simple_animal/diona/proc/merge
|
||||
forceMove(M)
|
||||
verbs += /mob/living/simple_animal/diona/proc/split
|
||||
verbs -= /mob/living/simple_animal/diona/proc/merge
|
||||
else
|
||||
return
|
||||
|
||||
@@ -102,61 +104,25 @@
|
||||
set name = "Split from gestalt"
|
||||
set desc = "Split away from your gestalt as a lone nymph."
|
||||
|
||||
if(!(istype(src.loc,/mob/living/carbon)))
|
||||
src.verbs -= /mob/living/simple_animal/diona/proc/split
|
||||
if(!(iscarbon(loc)))
|
||||
verbs -= /mob/living/simple_animal/diona/proc/split
|
||||
return
|
||||
|
||||
to_chat(src.loc, "You feel a pang of loss as [src] splits away from your biomass.")
|
||||
to_chat(src, "You wiggle out of the depths of [src.loc]'s biomass and plop to the ground.")
|
||||
to_chat(loc, "You feel a pang of loss as [src] splits away from your biomass.")
|
||||
to_chat(src, "You wiggle out of the depths of [loc]'s biomass and plop to the ground.")
|
||||
|
||||
var/mob/living/M = src.loc
|
||||
var/mob/living/M = loc
|
||||
|
||||
src.loc = get_turf(src)
|
||||
src.verbs -= /mob/living/simple_animal/diona/proc/split
|
||||
src.verbs += /mob/living/simple_animal/diona/proc/merge
|
||||
forceMove(get_turf(src))
|
||||
verbs -= /mob/living/simple_animal/diona/proc/split
|
||||
verbs += /mob/living/simple_animal/diona/proc/merge
|
||||
|
||||
if(istype(M))
|
||||
for(var/atom/A in M.contents)
|
||||
if(istype(A,/mob/living/simple_animal/borer) || istype(A,/obj/item/weapon/holder))
|
||||
if(istype(A, /mob/living/simple_animal/borer) || istype(A, /obj/item/weapon/holder))
|
||||
return
|
||||
M.status_flags &= ~PASSEMOTES
|
||||
|
||||
/mob/living/simple_animal/diona/verb/fertilize_plant()
|
||||
set category = "Diona"
|
||||
set name = "Fertilize plant"
|
||||
set desc = "Turn your food into nutrients for plants."
|
||||
|
||||
var/list/trays = list()
|
||||
for(var/obj/machinery/hydroponics/tray in range(1))
|
||||
if(tray.nutrilevel < 10)
|
||||
trays += tray
|
||||
|
||||
var/obj/machinery/hydroponics/target = input("Select a tray:") as null|anything in trays
|
||||
|
||||
if(!src || !target || target.nutrilevel == 10) return //Sanity check.
|
||||
|
||||
src.nutrition -= ((10-target.nutrilevel)*5)
|
||||
target.adjustNutri(10)
|
||||
src.visible_message("<span class='danger'>[src] secretes a trickle of green liquid from its tail, refilling [target]'s nutrient tray.","\red You secrete a trickle of green liquid from your tail, refilling [target]'s nutrient tray.</span>")
|
||||
|
||||
/mob/living/simple_animal/diona/verb/eat_weeds()
|
||||
set category = "Diona"
|
||||
set name = "Eat Weeds"
|
||||
set desc = "Clean the weeds out of soil or a hydroponics tray."
|
||||
|
||||
var/list/trays = list()
|
||||
for(var/obj/machinery/hydroponics/tray in range(1))
|
||||
if(tray.weedlevel > 0)
|
||||
trays += tray
|
||||
|
||||
var/obj/machinery/hydroponics/target = input("Select a tray:") as null|anything in trays
|
||||
|
||||
if(!src || !target || target.weedlevel == 0) return //Sanity check.
|
||||
|
||||
src.nutrition += target.weedlevel * 15
|
||||
target.adjustWeeds(-10)
|
||||
src.visible_message("<span class='danger'>[src] begins rooting through [target], ripping out weeds and eating them noisily.</span>","<span class='danger'>You begin rooting through [target], ripping out weeds and eating them noisily.</span>")
|
||||
|
||||
/mob/living/simple_animal/diona/verb/evolve()
|
||||
set category = "Diona"
|
||||
set name = "Evolve"
|
||||
@@ -170,15 +136,15 @@
|
||||
to_chat(src, "<span class='warning'>You need to binge on weeds in order to have the energy to grow...</span>")
|
||||
return
|
||||
|
||||
src.split()
|
||||
src.visible_message("<span class='danger'>[src] begins to shift and quiver, and erupts in a shower of shed bark as it splits into a tangle of nearly a dozen new dionaea.</span>","<span class='danger'>You begin to shift and quiver, feeling your awareness splinter. All at once, we consume our stored nutrients to surge with growth, splitting into a tangle of at least a dozen new dionaea. We have attained our gestalt form.</span>")
|
||||
split()
|
||||
visible_message("<span class='danger'>[src] begins to shift and quiver, and erupts in a shower of shed bark as it splits into a tangle of nearly a dozen new dionaea.</span>","<span class='danger'>You begin to shift and quiver, feeling your awareness splinter. All at once, we consume our stored nutrients to surge with growth, splitting into a tangle of at least a dozen new dionaea. We have attained our gestalt form.</span>")
|
||||
|
||||
var/mob/living/carbon/human/diona/adult = new(get_turf(src.loc))
|
||||
var/mob/living/carbon/human/diona/adult = new(get_turf(loc))
|
||||
adult.set_species("Diona")
|
||||
|
||||
if(istype(loc,/obj/item/weapon/holder/diona))
|
||||
if(istype(loc, /obj/item/weapon/holder/diona))
|
||||
var/obj/item/weapon/holder/diona/L = loc
|
||||
src.loc = L.loc
|
||||
forceMove(L.loc)
|
||||
qdel(L)
|
||||
|
||||
for(var/datum/language/L in languages)
|
||||
@@ -187,12 +153,12 @@
|
||||
|
||||
adult.name = "diona ([rand(100,999)])"
|
||||
adult.real_name = adult.name
|
||||
adult.ckey = src.ckey
|
||||
adult.ckey = ckey
|
||||
adult.real_name = pick(diona_names) //I hate this being here of all places but unfortunately dna is based on real_name!
|
||||
adult.rename_self("diona")
|
||||
|
||||
for(var/obj/item/W in src.contents)
|
||||
src.unEquip(W)
|
||||
for(var/obj/item/W in contents)
|
||||
unEquip(W)
|
||||
|
||||
qdel(src)
|
||||
|
||||
@@ -207,7 +173,8 @@
|
||||
|
||||
var/mob/living/carbon/human/M = input(src,"Who do you wish to take a sample from?") in null|choices
|
||||
|
||||
if(!M || !src) return
|
||||
if(!M || !src)
|
||||
return
|
||||
|
||||
if(M.species.flags & NO_BLOOD)
|
||||
to_chat(src, "<span class='warning'>That donor has no blood to take.</span>")
|
||||
@@ -217,7 +184,7 @@
|
||||
to_chat(src, "<span class='warning'>That donor offers you nothing new.</span>")
|
||||
return
|
||||
|
||||
src.visible_message("<span class='danger'>[src] flicks out a feeler and neatly steals a sample of [M]'s blood.</span>","<span class='danger'>You flick out a feeler and neatly steal a sample of [M]'s blood.</span>")
|
||||
visible_message("<span class='danger'>[src] flicks out a feeler and neatly steals a sample of [M]'s blood.</span>","<span class='danger'>You flick out a feeler and neatly steal a sample of [M]'s blood.</span>")
|
||||
donors += M.real_name
|
||||
for(var/datum/language/L in M.languages)
|
||||
if(!(L.flags & HIVEMIND))
|
||||
@@ -241,7 +208,7 @@
|
||||
|
||||
|
||||
/mob/living/simple_animal/diona/put_in_hands(obj/item/W)
|
||||
W.loc = get_turf(src)
|
||||
W.forceMove(get_turf(src))
|
||||
W.layer = initial(W.layer)
|
||||
W.plane = initial(W.plane)
|
||||
W.dropped()
|
||||
@@ -250,7 +217,7 @@
|
||||
to_chat(src, "<span class='warning'>You don't have any hands!</span>")
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/diona/emote(var/act, var/m_type=1, var/message = null)
|
||||
/mob/living/simple_animal/diona/emote(act, m_type=1, message = null)
|
||||
if(stat)
|
||||
return
|
||||
|
||||
|
||||
@@ -95,7 +95,8 @@
|
||||
visible_message(
|
||||
"<span class='danger'>[src] devours [L]!</span>",
|
||||
"<span class='userdanger'>You feast on [L], restoring your health!</span>")
|
||||
adjustBruteLoss(-L.maxHealth/2)
|
||||
if(!is_station_level(z) && !client) //NPC monsters won't heal while on station
|
||||
adjustBruteLoss(-L.maxHealth/2)
|
||||
L.gib()
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/ex_act(severity, target)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/mob/living/simple_animal/hostile/mimic
|
||||
name = "crate"
|
||||
desc = "A rectangular steel crate."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon = 'icons/obj/crates.dmi'
|
||||
icon_state = "crate"
|
||||
icon_living = "crate"
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ var/global/list/ts_spiderlist = list()
|
||||
else if(istype(target, /obj/machinery/door/firedoor))
|
||||
var/obj/machinery/door/firedoor/F = target
|
||||
if(F.density)
|
||||
if(F.blocked)
|
||||
if(F.welded)
|
||||
to_chat(src, "The fire door is welded shut.")
|
||||
else
|
||||
visible_message("<span class='danger'>\The [src] pries open the firedoor!</span>")
|
||||
@@ -293,7 +293,7 @@ var/global/list/ts_spiderlist = list()
|
||||
try_open_airlock(L)
|
||||
if(istype(A, /obj/machinery/door/firedoor))
|
||||
var/obj/machinery/door/firedoor/F = A
|
||||
if(F.density && !F.blocked)
|
||||
if(F.density && !F.welded)
|
||||
F.open()
|
||||
..()
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
dir = possessed_item.dir
|
||||
color = possessed_item.color
|
||||
overlays = possessed_item.overlays
|
||||
opacity = possessed_item.opacity
|
||||
set_opacity(possessed_item.opacity)
|
||||
|
||||
visible_message("<span class='warning'>[src] rises into the air and begins to float!</span>") // Inform those around us that shit's gettin' spooky.
|
||||
animate_ghostly_presence(src, -1, 20, 1)
|
||||
|
||||
@@ -95,3 +95,29 @@
|
||||
|
||||
/mob/living/proc/update_stamina()
|
||||
return
|
||||
|
||||
/mob/living/on_varedit(modified_var)
|
||||
switch(modified_var)
|
||||
if("weakened")
|
||||
SetWeakened(weakened)
|
||||
if("stunned")
|
||||
SetStunned(stunned)
|
||||
if("paralysis")
|
||||
SetParalysis(paralysis)
|
||||
if("sleeping")
|
||||
SetSleeping(sleeping)
|
||||
if("eye_blind")
|
||||
SetEyeBlind(eye_blind)
|
||||
if("eye_blurry")
|
||||
SetEyeBlurry(eye_blurry)
|
||||
if("ear_deaf")
|
||||
SetEarDeaf(ear_deaf)
|
||||
if("ear_damage")
|
||||
SetEarDamage(ear_damage)
|
||||
if("druggy")
|
||||
SetDruggy(druggy)
|
||||
if("maxHealth")
|
||||
updatehealth()
|
||||
if("resize")
|
||||
update_transform()
|
||||
..()
|
||||
@@ -72,6 +72,8 @@
|
||||
for(var/datum/alternate_appearance/AA in viewing_alternate_appearances)
|
||||
AA.display_to(list(src))
|
||||
|
||||
update_client_colour(0)
|
||||
|
||||
callHook("mob_login", list("client" = client, "mob" = src))
|
||||
|
||||
// Calling update_interface() in /mob/Login() causes the Cyborg to immediately be ghosted; because of winget().
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
for(var/datum/alternate_appearance/AA in viewing_alternate_appearances)
|
||||
AA.viewers -= src
|
||||
viewing_alternate_appearances = null
|
||||
return ..()
|
||||
..()
|
||||
return QDEL_HINT_HARDDEL_NOW
|
||||
|
||||
/mob/New()
|
||||
mob_list += src
|
||||
|
||||
@@ -194,7 +194,7 @@
|
||||
animate(affecting, pixel_x = 0, pixel_y = 0, 5, 1, LINEAR_EASING)
|
||||
return //KJK
|
||||
/* if(force_down) //THIS GOES ABOVE THE RETURN LABELED KJK
|
||||
affecting.set_dir(SOUTH)*///This shows how you can apply special directions based on a variable. //face up
|
||||
affecting.setDir(SOUTH)*///This shows how you can apply special directions based on a variable. //face up
|
||||
|
||||
var/shift = 0
|
||||
var/adir = get_dir(assailant, affecting)
|
||||
@@ -204,18 +204,18 @@
|
||||
shift = 8
|
||||
if(dancing) //look at partner
|
||||
shift = 10
|
||||
assailant.set_dir(get_dir(assailant, affecting))
|
||||
assailant.setDir(get_dir(assailant, affecting))
|
||||
if(GRAB_AGGRESSIVE)
|
||||
shift = 12
|
||||
if(GRAB_NECK, GRAB_UPGRADING)
|
||||
shift = -10
|
||||
adir = assailant.dir
|
||||
affecting.set_dir(assailant.dir)
|
||||
affecting.setDir(assailant.dir)
|
||||
affecting.loc = assailant.loc
|
||||
if(GRAB_KILL)
|
||||
shift = 0
|
||||
adir = 1
|
||||
affecting.set_dir(SOUTH)//face up
|
||||
affecting.setDir(SOUTH)//face up
|
||||
affecting.loc = assailant.loc
|
||||
|
||||
switch(adir)
|
||||
@@ -254,8 +254,8 @@
|
||||
force_down = 1
|
||||
affecting.Weaken(3)
|
||||
step_to(assailant, affecting)
|
||||
assailant.set_dir(EAST) //face the victim
|
||||
affecting.set_dir(SOUTH) //face up //This is an example of a new feature based on the context of the location of the victim.
|
||||
assailant.setDir(EAST) //face the victim
|
||||
affecting.setDir(SOUTH) //face up //This is an example of a new feature based on the context of the location of the victim.
|
||||
*/ //It means that upgrading while someone is lying on the ground would cause you to go into pin mode.
|
||||
state = GRAB_AGGRESSIVE
|
||||
icon_state = "grabbed1"
|
||||
@@ -268,7 +268,7 @@
|
||||
assailant.visible_message("<span class='warning'>[assailant] has reinforced \his grip on [affecting] (now neck)!</span>")
|
||||
state = GRAB_NECK
|
||||
icon_state = "grabbed+1"
|
||||
assailant.set_dir(get_dir(assailant, affecting))
|
||||
assailant.setDir(get_dir(assailant, affecting))
|
||||
affecting.create_attack_log("<font color='orange'>Has had their neck grabbed by [assailant.name] ([assailant.ckey])</font>")
|
||||
assailant.create_attack_log("<font color='red'>Grabbed the neck of [affecting.name] ([affecting.ckey])</font>")
|
||||
log_attack("<font color='red'>[assailant.name] ([assailant.ckey]) grabbed the neck of [affecting.name] ([affecting.ckey])</font>")
|
||||
@@ -291,7 +291,7 @@
|
||||
|
||||
assailant.next_move = world.time + 10
|
||||
affecting.AdjustLoseBreath(1)
|
||||
affecting.set_dir(WEST)
|
||||
affecting.setDir(WEST)
|
||||
adjust_position()
|
||||
|
||||
//This is used to make sure the victim hasn't managed to yackety sax away before using the grab.
|
||||
@@ -378,8 +378,8 @@
|
||||
affecting.Weaken(3)
|
||||
affecting.lying = 1
|
||||
step_to(assailant, affecting)
|
||||
assailant.set_dir(EAST) //face the victim
|
||||
affecting.set_dir(SOUTH) //face up
|
||||
assailant.setDir(EAST) //face the victim
|
||||
affecting.setDir(SOUTH) //face up
|
||||
return
|
||||
else
|
||||
to_chat(assailant, "<span class='warning'>You are already pinning [affecting] to the ground.</span>")
|
||||
|
||||
@@ -22,6 +22,25 @@
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/proc/get_screen_colour()
|
||||
|
||||
/mob/proc/update_client_colour(var/time = 10) //Update the mob's client.color with an animation the specified time in length.
|
||||
if(!client) //No client_colour without client. If the player logs back in they'll be back through here anyway.
|
||||
return
|
||||
client.colour_transition(get_screen_colour(), time = time) //Get the colour matrix we're going to transition to depending on relevance (magic glasses first, eyes second).
|
||||
|
||||
/mob/living/carbon/human/get_screen_colour() //Fetch the colour matrix from wherever (e.g. eyes) so it can be compared to client.color.
|
||||
. = ..()
|
||||
if(.)
|
||||
return .
|
||||
|
||||
var/obj/item/clothing/glasses/worn_glasses = glasses
|
||||
var/obj/item/organ/internal/eyes/eyes = get_int_organ(/obj/item/organ/internal/eyes)
|
||||
if(istype(worn_glasses) && worn_glasses.color_view) //Check to see if they got those magic glasses and they're augmenting the colour of what the wearer sees. If they're not, color_view should be null.
|
||||
return worn_glasses.color_view
|
||||
else if(eyes) //If they're not, check to see if their eyes got one of them there colour matrices. Will be null if eyes are robotic/the mob isn't colourblind and they have no default colour matrix.
|
||||
return eyes.get_colourmatrix()
|
||||
|
||||
/proc/isloyal(A) //Checks to see if the person contains a mindshield implant, then checks that the implant is actually inside of them
|
||||
for(var/obj/item/weapon/implant/loyalty/L in A)
|
||||
if(L && L.implanted)
|
||||
@@ -291,10 +310,10 @@ proc/muffledspeech(phrase)
|
||||
|
||||
|
||||
/mob/proc/abiotic(var/full_body = 0)
|
||||
if(full_body && ((src.l_hand && !(src.l_hand.flags & ABSTRACT)) || (src.r_hand && !(src.r_hand.flags & ABSTRACT)) || (src.back || src.wear_mask)))
|
||||
if(full_body && ((l_hand && !(l_hand.flags & ABSTRACT)) || (r_hand && !(r_hand.flags & ABSTRACT)) || (back || wear_mask)))
|
||||
return 1
|
||||
|
||||
if((src.l_hand && !(src.l_hand.flags & ABSTRACT)) || (src.r_hand && !(src.r_hand.flags & ABSTRACT)))
|
||||
if((l_hand && !(l_hand.flags & ABSTRACT)) || (r_hand && !(r_hand.flags & ABSTRACT)))
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
@@ -276,7 +276,7 @@
|
||||
|
||||
for(var/obj/item/weapon/grab/G in mob)
|
||||
if(G.state == GRAB_NECK)
|
||||
mob.set_dir(reverse_dir[direct])
|
||||
mob.setDir(reverse_dir[direct])
|
||||
G.adjust_position()
|
||||
for(var/obj/item/weapon/grab/G in mob.grabbed_by)
|
||||
G.adjust_position()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/mob/living/carbon/human/proc/monkeyize()
|
||||
var/mob/H = src
|
||||
H.dna.SetSEState(MONKEYBLOCK,1)
|
||||
domutcheck(H, null)
|
||||
genemutcheck(H,MONKEYBLOCK,null,MUTCHK_FORCED)
|
||||
|
||||
/mob/new_player/AIize()
|
||||
spawning = 1
|
||||
|
||||
@@ -319,7 +319,7 @@ field_generator power level display
|
||||
if(O.last_warning && temp)
|
||||
if((world.time - O.last_warning) > 50) //to stop message-spam
|
||||
temp = 0
|
||||
message_admins("A singulo exists and a containment field has failed.",1)
|
||||
message_admins("A singulo exists and a containment field has failed. Location: [get_area(src)] (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</A>)",1)
|
||||
investigate_log("has <font color='red'>failed</font> whilst a singulo exists.","singulo")
|
||||
O.last_warning = world.time
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
icon_state = "smatter"
|
||||
temperature = T20C+80
|
||||
density = 1
|
||||
opacity = 1
|
||||
set_opacity(1)
|
||||
blocks_air = 1
|
||||
|
||||
spawn(2)
|
||||
|
||||
@@ -118,18 +118,6 @@
|
||||
projectile_type = /obj/item/projectile/meteor
|
||||
select_name = "goddamn meteor"
|
||||
|
||||
/obj/item/ammo_casing/energy/kinetic
|
||||
projectile_type = /obj/item/projectile/kinetic
|
||||
select_name = "kinetic"
|
||||
e_cost = 5000
|
||||
fire_sound = 'sound/weapons/Kenetic_accel.ogg' // fine spelling there chap
|
||||
|
||||
/obj/item/ammo_casing/energy/kinetic/super
|
||||
projectile_type = /obj/item/projectile/kinetic/super
|
||||
|
||||
/obj/item/ammo_casing/energy/kinetic/hyper
|
||||
projectile_type = /obj/item/projectile/kinetic/hyper
|
||||
|
||||
/obj/item/ammo_casing/energy/disabler
|
||||
projectile_type = /obj/item/projectile/beam/disabler
|
||||
select_name = "disable"
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/guns_righthand.dmi'
|
||||
|
||||
var/obj/item/device/flashlight/F = null
|
||||
var/obj/item/device/flashlight/gun_light = null
|
||||
var/can_flashlight = 0
|
||||
|
||||
var/list/upgrades = list()
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
/obj/item/weapon/gun/New()
|
||||
..()
|
||||
if(F)
|
||||
if(gun_light)
|
||||
verbs += /obj/item/weapon/gun/proc/toggle_gunlight
|
||||
build_zooming()
|
||||
|
||||
@@ -241,27 +241,27 @@ obj/item/weapon/gun/proc/newshot()
|
||||
if(istype(I, /obj/item/device/flashlight/seclite))
|
||||
var/obj/item/device/flashlight/seclite/S = I
|
||||
if(can_flashlight)
|
||||
if(!F)
|
||||
if(!gun_light)
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You click [S] into place on [src].</span>")
|
||||
if(S.on)
|
||||
set_light(0)
|
||||
F = S
|
||||
gun_light = S
|
||||
I.loc = src
|
||||
update_icon()
|
||||
update_gunlight(user)
|
||||
update_gun_light(user)
|
||||
var/datum/action/A = new /datum/action/item_action/toggle_gunlight(src)
|
||||
if(loc == user)
|
||||
A.Grant(user)
|
||||
|
||||
if(istype(I, /obj/item/weapon/screwdriver))
|
||||
if(F && can_flashlight)
|
||||
if(gun_light && can_flashlight)
|
||||
for(var/obj/item/device/flashlight/seclite/S in src)
|
||||
to_chat(user, "<span class='notice'>You unscrew the seclite from [src].</span>")
|
||||
F = null
|
||||
gun_light = null
|
||||
S.loc = get_turf(user)
|
||||
update_gunlight(user)
|
||||
update_gun_light(user)
|
||||
S.update_brightness(user)
|
||||
update_icon()
|
||||
for(var/datum/action/item_action/toggle_gunlight/TGL in actions)
|
||||
@@ -273,26 +273,26 @@ obj/item/weapon/gun/proc/newshot()
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/proc/toggle_gunlight()
|
||||
set name = "Toggle Gunlight"
|
||||
set name = "Toggle Gun Light"
|
||||
set category = "Object"
|
||||
set desc = "Click to toggle your weapon's attached flashlight."
|
||||
|
||||
if(!F)
|
||||
if(!gun_light)
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/user = usr
|
||||
if(!isturf(user.loc))
|
||||
to_chat(user, "<span class='warning'>You cannot turn the light on while in this [user.loc]!</span>")
|
||||
F.on = !F.on
|
||||
to_chat(user, "<span class='notice'>You toggle the gunlight [F.on ? "on":"off"].</span>")
|
||||
gun_light.on = !gun_light.on
|
||||
to_chat(user, "<span class='notice'>You toggle the gun light [gun_light.on ? "on":"off"].</span>")
|
||||
|
||||
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
|
||||
update_gunlight(user)
|
||||
update_gun_light(user)
|
||||
|
||||
/obj/item/weapon/gun/proc/update_gunlight(mob/user = null)
|
||||
if(F)
|
||||
if(F.on)
|
||||
set_light(F.brightness_on)
|
||||
/obj/item/weapon/gun/proc/update_gun_light(mob/user = null)
|
||||
if(gun_light)
|
||||
if(gun_light.on)
|
||||
set_light(gun_light.brightness_on)
|
||||
else
|
||||
set_light(0)
|
||||
update_icon()
|
||||
|
||||
@@ -30,6 +30,12 @@
|
||||
else
|
||||
power_supply = new(src)
|
||||
power_supply.give(power_supply.maxcharge)
|
||||
update_ammo_types()
|
||||
if(selfcharge)
|
||||
processing_objects.Add(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/proc/update_ammo_types()
|
||||
var/obj/item/ammo_casing/energy/shot
|
||||
for(var/i = 1, i <= ammo_type.len, i++)
|
||||
var/shottype = ammo_type[i]
|
||||
@@ -38,9 +44,6 @@
|
||||
shot = ammo_type[select]
|
||||
fire_sound = shot.fire_sound
|
||||
fire_delay = shot.delay
|
||||
if(selfcharge)
|
||||
processing_objects.Add(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/Destroy()
|
||||
if(selfcharge)
|
||||
@@ -129,9 +132,9 @@
|
||||
overlays += image(icon = icon, icon_state = iconState, pixel_x = ammo_x_offset * (i -1))
|
||||
else
|
||||
overlays += image(icon = icon, icon_state = "[icon_state]_[modifystate ? "[shot.select_name]_" : ""]charge[ratio]")
|
||||
if(F && can_flashlight)
|
||||
if(gun_light && can_flashlight)
|
||||
var/iconF = "flight"
|
||||
if(F.on)
|
||||
if(gun_light.on)
|
||||
iconF = "flight_on"
|
||||
overlays += image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset)
|
||||
if(itemState)
|
||||
@@ -160,6 +163,14 @@
|
||||
playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1)
|
||||
return (OXYLOSS)
|
||||
|
||||
/obj/item/weapon/gun/energy/on_varedit(modified_var)
|
||||
if(modified_var == "selfcharge")
|
||||
if(selfcharge)
|
||||
processing_objects.Add(src)
|
||||
else
|
||||
processing_objects.Remove(src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/energy/proc/robocharge()
|
||||
if(isrobot(loc))
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
|
||||
@@ -0,0 +1,416 @@
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator
|
||||
name = "proto-kinetic accelerator"
|
||||
desc = "A self recharging, ranged mining tool that does increased damage in low pressure. Capable of holding up to six slots worth of mod kits."
|
||||
icon_state = "kineticgun"
|
||||
item_state = "kineticgun"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/kinetic)
|
||||
cell_type = /obj/item/weapon/stock_parts/cell/emproof
|
||||
needs_permit = 0
|
||||
unique_rename = 1
|
||||
origin_tech = "combat=3;powerstorage=3;engineering=3"
|
||||
weapon_weight = WEAPON_LIGHT
|
||||
can_flashlight = 1
|
||||
flight_x_offset = 15
|
||||
flight_y_offset = 9
|
||||
var/overheat_time = 16
|
||||
var/holds_charge = FALSE
|
||||
var/unique_frequency = FALSE // modified by KA modkits
|
||||
var/overheat = FALSE
|
||||
|
||||
var/max_mod_capacity = 100
|
||||
var/list/modkits = list()
|
||||
|
||||
var/empty_state = "kineticgun_empty"
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/examine(mob/user)
|
||||
if(..(user, 1))
|
||||
if(max_mod_capacity)
|
||||
to_chat(user, "<b>[get_remaining_mod_capacity()]%</b> mod capacity remaining.")
|
||||
for(var/A in get_modkits())
|
||||
var/obj/item/borg/upgrade/modkit/M = A
|
||||
to_chat(user, "<span class='notice'>There is a [M.name] mod installed, using <b>[M.cost]%</b> capacity.</span>")
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/attackby(obj/item/A, mob/user)
|
||||
if(istype(A, /obj/item/weapon/crowbar))
|
||||
if(modkits.len)
|
||||
to_chat(user, "<span class='notice'>You pry the modifications out.</span>")
|
||||
playsound(loc, 'sound/items/Crowbar.ogg', 100, 1)
|
||||
for(var/obj/item/borg/upgrade/modkit/M in modkits)
|
||||
M.uninstall(src)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There are no modifications currently installed.</span>")
|
||||
else if(istype(A, /obj/item/borg/upgrade/modkit))
|
||||
var/obj/item/borg/upgrade/modkit/MK = A
|
||||
MK.install(src, user)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/get_remaining_mod_capacity()
|
||||
var/current_capacity_used = 0
|
||||
for(var/A in get_modkits())
|
||||
var/obj/item/borg/upgrade/modkit/M = A
|
||||
current_capacity_used += M.cost
|
||||
return max_mod_capacity - current_capacity_used
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/get_modkits()
|
||||
. = list()
|
||||
for(var/A in modkits)
|
||||
. += A
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/modify_projectile(obj/item/projectile/kinetic/K)
|
||||
for(var/A in get_modkits())
|
||||
var/obj/item/borg/upgrade/modkit/M = A
|
||||
M.modify_projectile(K)
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/cyborg
|
||||
holds_charge = TRUE
|
||||
unique_frequency = TRUE
|
||||
max_mod_capacity = 80
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/New()
|
||||
. = ..()
|
||||
if(!holds_charge)
|
||||
empty()
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/shoot_live_shot()
|
||||
. = ..()
|
||||
attempt_reload()
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/equipped(mob/user)
|
||||
. = ..()
|
||||
if(!can_shoot())
|
||||
attempt_reload()
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/dropped()
|
||||
. = ..()
|
||||
if(!holds_charge)
|
||||
// Put it on a delay because moving item from slot to hand
|
||||
// calls dropped().
|
||||
spawn(2)
|
||||
empty_if_not_held()
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/empty_if_not_held()
|
||||
if(!ismob(loc))
|
||||
empty()
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/empty()
|
||||
power_supply.use(5000)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/attempt_reload()
|
||||
if(overheat)
|
||||
return
|
||||
overheat = TRUE
|
||||
|
||||
var/carried = 0
|
||||
if(!unique_frequency)
|
||||
for(var/obj/item/weapon/gun/energy/kinetic_accelerator/K in \
|
||||
loc.GetAllContents())
|
||||
|
||||
carried++
|
||||
|
||||
carried = max(carried, 1)
|
||||
else
|
||||
carried = 1
|
||||
|
||||
spawn(overheat_time * carried)
|
||||
reload()
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/emp_act(severity)
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/reload()
|
||||
power_supply.give(5000)
|
||||
if(!suppressed)
|
||||
playsound(loc, 'sound/weapons/kenetic_reload.ogg', 60, 1)
|
||||
else if(isliving(loc))
|
||||
to_chat(loc, "<span class='warning'>[src] silently charges up.<span>")
|
||||
update_icon()
|
||||
overheat = FALSE
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/update_icon()
|
||||
overlays.Cut()
|
||||
if(empty_state && !can_shoot())
|
||||
overlays += empty_state
|
||||
|
||||
if(gun_light && can_flashlight)
|
||||
var/iconF = "flight"
|
||||
if(gun_light.on)
|
||||
iconF = "flight_on"
|
||||
overlays += image(icon = icon, icon_state = iconF, pixel_x = flight_x_offset, pixel_y = flight_y_offset)
|
||||
|
||||
|
||||
//Casing
|
||||
/obj/item/ammo_casing/energy/kinetic
|
||||
projectile_type = /obj/item/projectile/kinetic
|
||||
select_name = "kinetic"
|
||||
e_cost = 5000
|
||||
fire_sound = 'sound/weapons/Kenetic_accel.ogg' // fine spelling there chap
|
||||
|
||||
/obj/item/ammo_casing/energy/kinetic/ready_proj(atom/target, mob/living/user, quiet, zone_override = "")
|
||||
..()
|
||||
if(loc && istype(loc, /obj/item/weapon/gun/energy/kinetic_accelerator))
|
||||
var/obj/item/weapon/gun/energy/kinetic_accelerator/KA = loc
|
||||
KA.modify_projectile(BB)
|
||||
|
||||
var/turf/proj_turf = get_turf(BB)
|
||||
if(!isturf(proj_turf))
|
||||
return
|
||||
var/datum/gas_mixture/environment = proj_turf.return_air()
|
||||
var/pressure = environment.return_pressure()
|
||||
if(pressure > 50)
|
||||
BB.name = "weakened [BB.name]"
|
||||
var/obj/item/projectile/kinetic/K = BB
|
||||
K.damage *= K.pressure_decrease
|
||||
|
||||
|
||||
//Projectiles
|
||||
/obj/item/projectile/kinetic
|
||||
name = "kinetic force"
|
||||
icon_state = null
|
||||
damage = 40
|
||||
damage_type = BRUTE
|
||||
flag = "bomb"
|
||||
range = 3
|
||||
log_override = TRUE
|
||||
|
||||
var/pressure_decrease = 0.25
|
||||
var/turf_aoe = FALSE
|
||||
var/mob_aoe = 0
|
||||
var/list/hit_overlays = list()
|
||||
|
||||
/obj/item/projectile/kinetic/on_range()
|
||||
strike_thing()
|
||||
..()
|
||||
|
||||
/obj/item/projectile/kinetic/on_hit(atom/target)
|
||||
strike_thing(target)
|
||||
. = ..()
|
||||
|
||||
/obj/item/projectile/kinetic/proc/strike_thing(atom/target)
|
||||
var/turf/target_turf = get_turf(target)
|
||||
if(!target_turf)
|
||||
target_turf = get_turf(src)
|
||||
if(ismineralturf(target_turf))
|
||||
var/turf/simulated/mineral/M = target_turf
|
||||
M.gets_drilled(firer)
|
||||
var/obj/effect/overlay/temp/kinetic_blast/K = new /obj/effect/overlay/temp/kinetic_blast(target_turf)
|
||||
K.color = color
|
||||
for(var/type in hit_overlays)
|
||||
new type(target_turf)
|
||||
if(turf_aoe)
|
||||
for(var/T in RANGE_TURFS(1, target_turf) - target_turf)
|
||||
if(ismineralturf(T))
|
||||
var/turf/simulated/mineral/M = T
|
||||
M.gets_drilled(firer)
|
||||
if(mob_aoe)
|
||||
for(var/mob/living/L in range(1, target_turf) - firer - target)
|
||||
var/armor = L.run_armor_check(def_zone, flag, "", "", armour_penetration)
|
||||
L.apply_damage(damage*mob_aoe, damage_type, def_zone, armor)
|
||||
to_chat(L, "<span class='userdanger'>You're struck by a [name]!</span>")
|
||||
|
||||
|
||||
//Modkits
|
||||
/obj/item/borg/upgrade/modkit
|
||||
name = "modification kit"
|
||||
desc = "An upgrade for kinetic accelerators."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "modkit"
|
||||
origin_tech = "programming=2;materials=2;magnets=4"
|
||||
require_module = 1
|
||||
module_type = /obj/item/weapon/robot_module/miner
|
||||
var/denied_type = null
|
||||
var/maximum_of_type = 1
|
||||
var/cost = 30
|
||||
var/modifier = 1 //For use in any mod kit that has numerical modifiers
|
||||
|
||||
/obj/item/borg/upgrade/modkit/examine(mob/user)
|
||||
if(..(user, 1))
|
||||
to_chat(user, "<span class='notice'>Occupies <b>[cost]%</b> of mod capacity.</span>")
|
||||
|
||||
/obj/item/borg/upgrade/modkit/attackby(obj/item/A, mob/user)
|
||||
if(istype(A, /obj/item/weapon/gun/energy/kinetic_accelerator) && !issilicon(user))
|
||||
install(A, user)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/borg/upgrade/modkit/action(mob/living/silicon/robot/R)
|
||||
if(..())
|
||||
return
|
||||
|
||||
for(var/obj/item/weapon/gun/energy/kinetic_accelerator/cyborg/H in R.module.modules)
|
||||
return install(H, usr)
|
||||
|
||||
/obj/item/borg/upgrade/modkit/proc/install(obj/item/weapon/gun/energy/kinetic_accelerator/KA, mob/user)
|
||||
. = TRUE
|
||||
if(denied_type)
|
||||
var/number_of_denied = 0
|
||||
for(var/A in KA.get_modkits())
|
||||
var/obj/item/borg/upgrade/modkit/M = A
|
||||
if(istype(M, denied_type))
|
||||
number_of_denied++
|
||||
if(number_of_denied >= maximum_of_type)
|
||||
. = FALSE
|
||||
break
|
||||
if(KA.get_remaining_mod_capacity() >= cost)
|
||||
if(.)
|
||||
to_chat(user, "<span class='notice'>You install the modkit.</span>")
|
||||
playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1)
|
||||
user.unEquip(src)
|
||||
forceMove(KA)
|
||||
KA.modkits += src
|
||||
else
|
||||
to_chat(user, "<span class='notice'>The modkit you're trying to install would conflict with an already installed modkit. Use a crowbar to remove existing modkits.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You don't have room(<b>[KA.get_remaining_mod_capacity()]%</b> remaining, [cost]% needed) to install this modkit. Use a crowbar to remove existing modkits.</span>")
|
||||
. = FALSE
|
||||
|
||||
/obj/item/borg/upgrade/modkit/proc/uninstall(obj/item/weapon/gun/energy/kinetic_accelerator/KA)
|
||||
forceMove(get_turf(KA))
|
||||
KA.modkits -= src
|
||||
|
||||
/obj/item/borg/upgrade/modkit/proc/modify_projectile(obj/item/projectile/kinetic/K)
|
||||
|
||||
|
||||
//Range
|
||||
/obj/item/borg/upgrade/modkit/range
|
||||
name = "range increase"
|
||||
desc = "Increases the range of a kinetic accelerator when installed."
|
||||
modifier = 1
|
||||
cost = 24 //so you can fit four plus a tracer cosmetic
|
||||
|
||||
/obj/item/borg/upgrade/modkit/range/modify_projectile(obj/item/projectile/kinetic/K)
|
||||
K.range += modifier
|
||||
|
||||
|
||||
//Damage
|
||||
/obj/item/borg/upgrade/modkit/damage
|
||||
name = "damage increase"
|
||||
desc = "Increases the damage of kinetic accelerator when installed."
|
||||
modifier = 10
|
||||
|
||||
/obj/item/borg/upgrade/modkit/damage/modify_projectile(obj/item/projectile/kinetic/K)
|
||||
K.damage += modifier
|
||||
|
||||
|
||||
//Cooldown
|
||||
/obj/item/borg/upgrade/modkit/cooldown
|
||||
name = "cooldown decrease"
|
||||
desc = "Decreases the cooldown of a kinetic accelerator."
|
||||
modifier = 2.5
|
||||
|
||||
/obj/item/borg/upgrade/modkit/cooldown/install(obj/item/weapon/gun/energy/kinetic_accelerator/KA, mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
KA.overheat_time -= modifier
|
||||
|
||||
/obj/item/borg/upgrade/modkit/cooldown/uninstall(obj/item/weapon/gun/energy/kinetic_accelerator/KA)
|
||||
KA.overheat_time += modifier
|
||||
..()
|
||||
|
||||
|
||||
//AoE blasts
|
||||
/obj/item/borg/upgrade/modkit/aoe
|
||||
modifier = 0
|
||||
|
||||
/obj/item/borg/upgrade/modkit/aoe/modify_projectile(obj/item/projectile/kinetic/K)
|
||||
K.name = "kinetic explosion"
|
||||
if(!K.turf_aoe && !K.mob_aoe)
|
||||
K.hit_overlays += /obj/effect/overlay/temp/explosion/fast
|
||||
K.mob_aoe += modifier
|
||||
|
||||
/obj/item/borg/upgrade/modkit/aoe/turfs
|
||||
name = "mining explosion"
|
||||
desc = "Causes the kinetic accelerator to destroy rock in an AoE."
|
||||
denied_type = /obj/item/borg/upgrade/modkit/aoe/turfs
|
||||
|
||||
/obj/item/borg/upgrade/modkit/aoe/turfs/modify_projectile(obj/item/projectile/kinetic/K)
|
||||
..()
|
||||
K.turf_aoe = TRUE
|
||||
|
||||
/obj/item/borg/upgrade/modkit/aoe/turfs/andmobs
|
||||
name = "offensive mining explosion"
|
||||
desc = "Causes the kinetic accelerator to destroy rock and damage mobs in an AoE."
|
||||
maximum_of_type = 3
|
||||
modifier = 0.25
|
||||
|
||||
/obj/item/borg/upgrade/modkit/aoe/mobs
|
||||
name = "offensive explosion"
|
||||
desc = "Causes the kinetic accelerator to damage mobs in an AoE."
|
||||
modifier = 0.2
|
||||
|
||||
|
||||
//Indoors
|
||||
/obj/item/borg/upgrade/modkit/indoors
|
||||
name = "decrease pressure penalty"
|
||||
desc = "Increases the damage a kinetic accelerator does in a high pressure environment."
|
||||
modifier = 2
|
||||
denied_type = /obj/item/borg/upgrade/modkit/indoors
|
||||
maximum_of_type = 2
|
||||
cost = 40
|
||||
|
||||
/obj/item/borg/upgrade/modkit/indoors/modify_projectile(obj/item/projectile/kinetic/K)
|
||||
K.pressure_decrease *= modifier
|
||||
|
||||
|
||||
//Trigger Guard
|
||||
/obj/item/borg/upgrade/modkit/trigger_guard
|
||||
name = "modified trigger guard"
|
||||
desc = "Allows creatures normally incapable of firing guns to operate the weapon when installed."
|
||||
cost = 20
|
||||
denied_type = /obj/item/borg/upgrade/modkit/trigger_guard
|
||||
|
||||
/obj/item/borg/upgrade/modkit/trigger_guard/install(obj/item/weapon/gun/energy/kinetic_accelerator/KA, mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
KA.trigger_guard = TRIGGER_GUARD_ALLOW_ALL
|
||||
|
||||
/obj/item/borg/upgrade/modkit/trigger_guard/uninstall(obj/item/weapon/gun/energy/kinetic_accelerator/KA)
|
||||
KA.trigger_guard = TRIGGER_GUARD_NORMAL
|
||||
..()
|
||||
|
||||
|
||||
//Cosmetic
|
||||
|
||||
/obj/item/borg/upgrade/modkit/chassis_mod
|
||||
name = "super chassis"
|
||||
desc = "Makes your KA yellow. All the fun of having a more powerful KA without actually having a more powerful KA."
|
||||
cost = 0
|
||||
denied_type = /obj/item/borg/upgrade/modkit/chassis_mod
|
||||
var/chassis_icon = "kineticgun_u"
|
||||
var/chassis_name = "super-kinetic accelerator"
|
||||
|
||||
/obj/item/borg/upgrade/modkit/chassis_mod/install(obj/item/weapon/gun/energy/kinetic_accelerator/KA, mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
KA.icon_state = chassis_icon
|
||||
KA.name = chassis_name
|
||||
|
||||
/obj/item/borg/upgrade/modkit/chassis_mod/uninstall(obj/item/weapon/gun/energy/kinetic_accelerator/KA)
|
||||
KA.icon_state = initial(KA.icon_state)
|
||||
KA.name = initial(KA.name)
|
||||
..()
|
||||
|
||||
/obj/item/borg/upgrade/modkit/chassis_mod/orange
|
||||
name = "hyper chassis"
|
||||
desc = "Makes your KA orange. All the fun of having explosive blasts without actually having explosive blasts."
|
||||
chassis_icon = "kineticgun_h"
|
||||
chassis_name = "hyper-kinetic accelerator"
|
||||
|
||||
/obj/item/borg/upgrade/modkit/tracer
|
||||
name = "white tracer bolts"
|
||||
desc = "Causes kinetic accelerator bolts to have a white tracer trail and explosion."
|
||||
cost = 0
|
||||
denied_type = /obj/item/borg/upgrade/modkit/tracer
|
||||
var/bolt_color = "#FFFFFF"
|
||||
|
||||
/obj/item/borg/upgrade/modkit/tracer/modify_projectile(obj/item/projectile/kinetic/K)
|
||||
K.icon_state = "ka_tracer"
|
||||
K.color = bolt_color
|
||||
|
||||
/obj/item/borg/upgrade/modkit/tracer/adjustable
|
||||
name = "adjustable tracer bolts"
|
||||
desc = "Causes kinetic accelerator bolts to have a adjustably-colored tracer trail and explosion. Use in-hand to change color."
|
||||
|
||||
/obj/item/borg/upgrade/modkit/tracer/adjustable/attack_self(mob/user)
|
||||
bolt_color = input(user,"Choose Color") as color
|
||||
@@ -37,14 +37,14 @@
|
||||
can_flashlight = 0 // Can't attach or detach the flashlight, and override it's icon update
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/mini/New()
|
||||
F = new /obj/item/device/flashlight/seclite(src)
|
||||
gun_light = new /obj/item/device/flashlight/seclite(src)
|
||||
..()
|
||||
power_supply.maxcharge = 6000
|
||||
power_supply.charge = 6000
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/mini/update_icon()
|
||||
..()
|
||||
if(F && F.on)
|
||||
if(gun_light && gun_light.on)
|
||||
overlays += "mini-light"
|
||||
|
||||
/obj/item/weapon/gun/energy/gun/hos
|
||||
|
||||
@@ -84,141 +84,6 @@
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/mindflayer)
|
||||
ammo_x_offset = 2
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator
|
||||
name = "proto-kinetic accelerator"
|
||||
desc = "In the year 2544, only a year after the discovery of a potentially \
|
||||
world-changing substance, now colloquially referred to as plasma, the \
|
||||
Nanotrasen-UEG mining conglomerate introduced a prototype of a gun-like \
|
||||
device intended for quick, effective mining of plasma in the low \
|
||||
pressures of the solar system. Included in this presentation were \
|
||||
demonstrations of the gun being fired at collections of rocks contained \
|
||||
in vacuumed environments, obliterating them instantly while maintaining \
|
||||
the structure of the ores buried within them. Additionally, volunteers \
|
||||
were called from the crowd to have the gun used on them, only proving that \
|
||||
the gun caused little harm to objects in standard pressure. \n\
|
||||
An official from an unnamed, now long dissipated company observed this \
|
||||
presentation and offered to share their self-recharger cells, powered \
|
||||
by the user's bioelectrical field, another new and unknown technology. \
|
||||
They warned that the cells were incredibly experimental and several times \
|
||||
had injured workers, but the scientists as Nanotrasen were unable to resist \
|
||||
the money-saving potential of self recharging cells. Upon accepting this \
|
||||
offer, it took only a matter of days to prove the volatility of these cells, \
|
||||
as they exploded left and right whenever inserted into the prototype devices, \
|
||||
only throwing more money in the bin. \n\
|
||||
Whenever the Nanotrasen scientists were on the edge of giving up, a \
|
||||
breakthrough was made by head researcher Miles Parks McCollum, who \
|
||||
demonstrated that the cells could be stabilized when exposed to radium \
|
||||
then cooled with cryostylane. After this discovery, the low pressure gun, \
|
||||
now named the Kinetic Accelerator, was hastily completed and made compatible \
|
||||
with the self-recharging cells. As a result of poor testing, the currently \
|
||||
used guns lose their charge when not in use, and when two Kinetic Accelerators \
|
||||
come in proximity of one another, they will interfere with each other. Despite \
|
||||
this, the shoddy guns still see use in the mining of plasma to this day."
|
||||
icon_state = "kineticgun"
|
||||
item_state = "kineticgun"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/kinetic)
|
||||
cell_type = /obj/item/weapon/stock_parts/cell/emproof
|
||||
// Apparently these are safe to carry? I'm sure goliaths would disagree.
|
||||
needs_permit = 0
|
||||
unique_rename = 1
|
||||
origin_tech = "combat=3;powerstorage=3;engineering=3"
|
||||
weapon_weight = WEAPON_LIGHT
|
||||
can_flashlight = 1
|
||||
flight_x_offset = 15
|
||||
flight_y_offset = 9
|
||||
var/overheat_time = 16
|
||||
var/holds_charge = FALSE
|
||||
var/unique_frequency = FALSE // modified by KA modkits
|
||||
var/overheat = FALSE
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/super
|
||||
name = "super-kinetic accelerator"
|
||||
desc = "An upgraded, superior version of the proto-kinetic accelerator."
|
||||
icon_state = "kineticgun_u"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/kinetic/super)
|
||||
overheat_time = 15
|
||||
origin_tech = "combat=3;powerstorage=2"
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/hyper
|
||||
name = "hyper-kinetic accelerator"
|
||||
desc = "An upgraded, even more superior version of the proto-kinetic accelerator."
|
||||
icon_state = "kineticgun_h"
|
||||
ammo_type = list(/obj/item/ammo_casing/energy/kinetic/hyper)
|
||||
overheat_time = 14
|
||||
origin_tech = "combat=4;powerstorage=3"
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/cyborg
|
||||
holds_charge = TRUE
|
||||
unique_frequency = TRUE
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/hyper/cyborg
|
||||
holds_charge = TRUE
|
||||
unique_frequency = TRUE
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/New()
|
||||
. = ..()
|
||||
if(!holds_charge)
|
||||
empty()
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/shoot_live_shot()
|
||||
. = ..()
|
||||
attempt_reload()
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/equipped(mob/user)
|
||||
. = ..()
|
||||
if(!can_shoot())
|
||||
attempt_reload()
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/dropped()
|
||||
. = ..()
|
||||
if(!holds_charge)
|
||||
// Put it on a delay because moving item from slot to hand
|
||||
// calls dropped().
|
||||
spawn(1)
|
||||
if(!ismob(loc))
|
||||
empty()
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/empty()
|
||||
power_supply.use(5000)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/attempt_reload()
|
||||
if(overheat)
|
||||
return
|
||||
overheat = TRUE
|
||||
|
||||
var/carried = 0
|
||||
if(!unique_frequency)
|
||||
for(var/obj/item/weapon/gun/energy/kinetic_accelerator/K in \
|
||||
loc.GetAllContents())
|
||||
|
||||
carried++
|
||||
|
||||
carried = max(carried, 1)
|
||||
else
|
||||
carried = 1
|
||||
|
||||
spawn(overheat_time * carried)
|
||||
reload()
|
||||
overheat = FALSE
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/emp_act(severity)
|
||||
return
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/proc/reload()
|
||||
power_supply.give(5000)
|
||||
if(!suppressed)
|
||||
playsound(loc, 'sound/weapons/kenetic_reload.ogg', 60, 1)
|
||||
else if(ismob(loc))
|
||||
to_chat(loc, "<span class='warning'>[src] silently charges up.<span>")
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/update_icon()
|
||||
if(!can_shoot())
|
||||
icon_state = "[initial(icon_state)]_empty"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/crossbow
|
||||
name = "mini energy crossbow"
|
||||
desc = "A weapon favored by syndicate stealth specialists."
|
||||
@@ -234,6 +99,9 @@
|
||||
overheat_time = 20
|
||||
holds_charge = TRUE
|
||||
unique_frequency = TRUE
|
||||
can_flashlight = 0
|
||||
max_mod_capacity = 0
|
||||
empty_state = null
|
||||
|
||||
/obj/item/weapon/gun/energy/kinetic_accelerator/crossbow/ninja
|
||||
name = "energy dart thrower"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user