mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-02-01 03:42:50 +00:00
Merge branch 'bleeding-edge-freeze' of https://github.com/Baystation12/Baystation12 into bleeding-edge-freeze
This commit is contained in:
@@ -166,11 +166,6 @@
|
||||
#include "code\datums\helper_datums\global_iterator.dm"
|
||||
#include "code\datums\helper_datums\teleport.dm"
|
||||
#include "code\datums\helper_datums\topic_input.dm"
|
||||
#include "code\datums\organs\organ.dm"
|
||||
#include "code\datums\organs\organ_external.dm"
|
||||
#include "code\datums\organs\organ_internal.dm"
|
||||
#include "code\datums\organs\pain.dm"
|
||||
#include "code\datums\organs\wound.dm"
|
||||
#include "code\datums\spells\area_teleport.dm"
|
||||
#include "code\datums\spells\conjure.dm"
|
||||
#include "code\datums\spells\dumbfire.dm"
|
||||
@@ -1030,6 +1025,12 @@
|
||||
#include "code\modules\mob\new_player\preferences_setup.dm"
|
||||
#include "code\modules\mob\new_player\skill.dm"
|
||||
#include "code\modules\mob\new_player\sprite_accessories.dm"
|
||||
#include "code\modules\organs\blood.dm"
|
||||
#include "code\modules\organs\organ.dm"
|
||||
#include "code\modules\organs\organ_external.dm"
|
||||
#include "code\modules\organs\organ_internal.dm"
|
||||
#include "code\modules\organs\pain.dm"
|
||||
#include "code\modules\organs\wound.dm"
|
||||
#include "code\modules\paperwork\clipboard.dm"
|
||||
#include "code\modules\paperwork\filingcabinet.dm"
|
||||
#include "code\modules\paperwork\folders.dm"
|
||||
@@ -1145,22 +1146,67 @@
|
||||
#include "code\modules\research\research.dm"
|
||||
#include "code\modules\research\research_shuttle.dm"
|
||||
#include "code\modules\research\server.dm"
|
||||
#include "code\modules\research\xenoarchaeology\archaeo_chem.dm"
|
||||
#include "code\modules\research\xenoarchaeology\archaeo_excavate.dm"
|
||||
#include "code\modules\research\xenoarchaeology\archaeo_machinery.dm"
|
||||
#include "code\modules\research\xenoarchaeology\archaeo_tools.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact_analysis.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact_db.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact_effect.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact_harvester.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact_misc.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact_synthetic.dm"
|
||||
#include "code\modules\research\xenoarchaeology\core_sampler.dm"
|
||||
#include "code\modules\research\xenoarchaeology\finds.dm"
|
||||
#include "code\modules\research\xenoarchaeology\areas.dm"
|
||||
#include "code\modules\research\xenoarchaeology\chemistry.dm"
|
||||
#include "code\modules\research\xenoarchaeology\geosample.dm"
|
||||
#include "code\modules\research\xenoarchaeology\manuals.dm"
|
||||
#include "code\modules\research\xenoarchaeology\misc.dm"
|
||||
#include "code\modules\research\xenoarchaeology\readme.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\artifact.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\artifact_autocloner.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\artifact_crystal.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\artifact_gigadrill.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\artifact_hoverpod.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\artifact_replicator.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\artifact_unknown.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effect.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_affect_cold.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_badfeeling.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_cellcharge.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_celldrain.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_dnaswitch.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_emp.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_forcefield.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_gasco2.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_gasnitro.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_gasoxy.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_gasplasma.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_gassleeping.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_goodfeeling.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_heal.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_heat.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_hurt.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_radiate.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_roboheal.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_robohurt.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_sleepy.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_stun.dm"
|
||||
#include "code\modules\research\xenoarchaeology\artifact\effects\unknown_effect_teleport.dm"
|
||||
#include "code\modules\research\xenoarchaeology\finds\finds.dm"
|
||||
#include "code\modules\research\xenoarchaeology\finds\finds_defines.dm"
|
||||
#include "code\modules\research\xenoarchaeology\finds\finds_fossils.dm"
|
||||
#include "code\modules\research\xenoarchaeology\finds\finds_misc.dm"
|
||||
#include "code\modules\research\xenoarchaeology\finds\finds_talkingitem.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\analysis_accelerator.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\analysis_base.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\analysis_fourier_transform.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\analysis_gas_chromatography.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\analysis_hyperspectral.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\analysis_ion_mobility.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\analysis_isotope_ratio.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\artifact_analyser.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\artifact_harvester.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\artifact_scanner.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\ano_device_battery.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\anomaly_suit.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\bunsen_burner.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\gearbelt.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\suspension_generator.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\tools.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\tools_coresampler.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\tools_depthscanner.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\tools_locater.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\tools_pickaxe.dm"
|
||||
#include "code\modules\scripting\Errors.dm"
|
||||
#include "code\modules\scripting\IDE.dm"
|
||||
#include "code\modules\scripting\Options.dm"
|
||||
|
||||
@@ -1,55 +1,55 @@
|
||||
|
||||
//---------- actual energy field
|
||||
|
||||
/obj/effect/energy_field
|
||||
name = "energy field"
|
||||
desc = "Impenetrable field of energy, capable of blocking anything as long as it's active."
|
||||
icon = 'shielding.dmi'
|
||||
icon_state = "shieldsparkles"
|
||||
anchored = 1
|
||||
layer = 2.1
|
||||
density = 0
|
||||
invisibility = 101
|
||||
var/strength = 0
|
||||
|
||||
/obj/effect/energy_field/ex_act(var/severity)
|
||||
Stress(0.5 + severity)
|
||||
|
||||
/obj/effect/energy_field/bullet_act(var/obj/item/projectile/Proj)
|
||||
Stress(Proj.damage / 10)
|
||||
|
||||
/obj/effect/energy_field/meteorhit(obj/effect/meteor/M as obj)
|
||||
if(M)
|
||||
walk(M,0)
|
||||
Stress(2)
|
||||
|
||||
/obj/effect/energy_field/proc/Stress(var/severity)
|
||||
strength -= severity
|
||||
|
||||
//if we take too much damage, drop out - the generator will bring us back up if we have enough power
|
||||
if(strength < 1)
|
||||
invisibility = 101
|
||||
density = 0
|
||||
else if(strength >= 1)
|
||||
invisibility = 0
|
||||
density = 1
|
||||
|
||||
/obj/effect/energy_field/proc/Strengthen(var/severity)
|
||||
strength += severity
|
||||
|
||||
//if we take too much damage, drop out - the generator will bring us back up if we have enough power
|
||||
if(strength >= 1)
|
||||
invisibility = 0
|
||||
density = 1
|
||||
else if(strength < 1)
|
||||
invisibility = 101
|
||||
density = 0
|
||||
|
||||
/obj/effect/energy_field/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
|
||||
//Purpose: Determines if the object (or airflow) can pass this atom.
|
||||
//Called by: Movement, airflow.
|
||||
//Inputs: The moving atom (optional), target turf, "height" and air group
|
||||
//Outputs: Boolean if can pass.
|
||||
|
||||
//return (!density || !height || air_group)
|
||||
return !density
|
||||
|
||||
//---------- actual energy field
|
||||
|
||||
/obj/effect/energy_field
|
||||
name = "energy field"
|
||||
desc = "Impenetrable field of energy, capable of blocking anything as long as it's active."
|
||||
icon = 'shielding.dmi'
|
||||
icon_state = "shieldsparkles"
|
||||
anchored = 1
|
||||
layer = 4.1 //just above mobs
|
||||
density = 0
|
||||
invisibility = 101
|
||||
var/strength = 0
|
||||
|
||||
/obj/effect/energy_field/ex_act(var/severity)
|
||||
Stress(0.5 + severity)
|
||||
|
||||
/obj/effect/energy_field/bullet_act(var/obj/item/projectile/Proj)
|
||||
Stress(Proj.damage / 10)
|
||||
|
||||
/obj/effect/energy_field/meteorhit(obj/effect/meteor/M as obj)
|
||||
if(M)
|
||||
walk(M,0)
|
||||
Stress(2)
|
||||
|
||||
/obj/effect/energy_field/proc/Stress(var/severity)
|
||||
strength -= severity
|
||||
|
||||
//if we take too much damage, drop out - the generator will bring us back up if we have enough power
|
||||
if(strength < 1)
|
||||
invisibility = 101
|
||||
density = 0
|
||||
else if(strength >= 1)
|
||||
invisibility = 0
|
||||
density = 1
|
||||
|
||||
/obj/effect/energy_field/proc/Strengthen(var/severity)
|
||||
strength += severity
|
||||
|
||||
//if we take too much damage, drop out - the generator will bring us back up if we have enough power
|
||||
if(strength >= 1)
|
||||
invisibility = 0
|
||||
density = 1
|
||||
else if(strength < 1)
|
||||
invisibility = 101
|
||||
density = 0
|
||||
|
||||
/obj/effect/energy_field/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
|
||||
//Purpose: Determines if the object (or airflow) can pass this atom.
|
||||
//Called by: Movement, airflow.
|
||||
//Inputs: The moving atom (optional), target turf, "height" and air group
|
||||
//Outputs: Boolean if can pass.
|
||||
|
||||
//return (!density || !height || air_group)
|
||||
return !density
|
||||
|
||||
@@ -146,11 +146,12 @@ proc/listclearnulls(list/list)
|
||||
* Sorting
|
||||
*/
|
||||
|
||||
//Reverses the order of items in the list (Turning a stack into a queue)
|
||||
/proc/reverselist(var/list/input)
|
||||
var/list/output = new/list()
|
||||
for(var/A in input)
|
||||
output += A
|
||||
//Reverses the order of items in the list
|
||||
/proc/reverselist(list/L)
|
||||
var/list/output = list()
|
||||
if(L)
|
||||
for(var/i = L.len; i >= 1; i--)
|
||||
output += L[i]
|
||||
return output
|
||||
|
||||
//Randomize: Return the list in a random order
|
||||
@@ -320,4 +321,28 @@ proc/listclearnulls(list/list)
|
||||
for(var/T in L)
|
||||
if(istype(T, type))
|
||||
i++
|
||||
return i
|
||||
return i
|
||||
|
||||
//Don't use this on lists larger than half a dozen or so
|
||||
/proc/insertion_sort_numeric_list_ascending(var/list/L)
|
||||
//world.log << "ascending len input: [L.len]"
|
||||
var/list/out = list(pop(L))
|
||||
for(var/entry in L)
|
||||
if(isnum(entry))
|
||||
var/success = 0
|
||||
for(var/i=1, i<=out.len, i++)
|
||||
if(entry <= out[i])
|
||||
success = 1
|
||||
out.Insert(i, entry)
|
||||
break
|
||||
if(!success)
|
||||
out.Add(entry)
|
||||
|
||||
//world.log << " output: [out.len]"
|
||||
return out
|
||||
|
||||
/proc/insertion_sort_numeric_list_descending(var/list/L)
|
||||
//world.log << "descending len input: [L.len]"
|
||||
var/list/out = insertion_sort_numeric_list_ascending(L)
|
||||
//world.log << " output: [out.len]"
|
||||
return reverselist(out)
|
||||
|
||||
@@ -130,9 +130,10 @@ datum/shuttle_controller
|
||||
|
||||
start_location.move_contents_to(end_location, null, NORTH)
|
||||
|
||||
for(var/obj/machinery/door/D in world)
|
||||
for(var/obj/machinery/door/unpowered/D in world)
|
||||
if( get_area(D) == end_location )
|
||||
spawn(0)
|
||||
D.locked = 0
|
||||
D.open()
|
||||
|
||||
for(var/mob/M in end_location)
|
||||
@@ -291,9 +292,10 @@ datum/shuttle_controller
|
||||
// Just before it leaves, close the damn doors!
|
||||
if(timeleft == 2 || timeleft == 1)
|
||||
var/area/start_location = locate(/area/shuttle/escape/station)
|
||||
for(var/obj/machinery/door/D in start_location)
|
||||
for(var/obj/machinery/door/unpowered/shuttle/D in start_location)
|
||||
spawn(0)
|
||||
D.close()
|
||||
D.locked = 1
|
||||
|
||||
if(timeleft>0)
|
||||
return 0
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/datum/organ
|
||||
var/name = "organ"
|
||||
var/mob/living/carbon/human/owner = null
|
||||
var/list/datum/autopsy_data/autopsy_data = list()
|
||||
|
||||
var/list/trace_chemicals = list() // traces of chemicals in the organ,
|
||||
// links chemical IDs to number of ticks for which they'll stay in the blood
|
||||
|
||||
|
||||
///datum/organ/proc/process()
|
||||
// return 0
|
||||
|
||||
///datum/organ/proc/receive_chem(chemical as obj)
|
||||
// return 0
|
||||
|
||||
proc/process()
|
||||
return 0
|
||||
|
||||
proc/receive_chem(chemical as obj)
|
||||
return 0
|
||||
@@ -12,11 +12,11 @@
|
||||
access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels,
|
||||
access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva,
|
||||
access_heads, access_construction, access_sec_doors,
|
||||
access_ce, access_RC_announce, access_keycard_auth, access_tcomsat)
|
||||
access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload)
|
||||
minimal_access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels,
|
||||
access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva,
|
||||
access_heads, access_construction, access_sec_doors,
|
||||
access_ce, access_RC_announce, access_keycard_auth, access_tcomsat)
|
||||
access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload)
|
||||
minimal_player_age = 7
|
||||
|
||||
|
||||
|
||||
@@ -45,12 +45,6 @@ var/const/ASSISTANT =(1<<13)
|
||||
|
||||
|
||||
var/list/assistant_occupations = list(
|
||||
"Assistant",
|
||||
"Atmospheric Technician",
|
||||
"Cargo Technician",
|
||||
"Chaplain",
|
||||
"Lawyer",
|
||||
"Librarian"
|
||||
)
|
||||
|
||||
|
||||
@@ -68,7 +62,6 @@ var/list/engineering_positions = list(
|
||||
"Chief Engineer",
|
||||
"Station Engineer",
|
||||
"Atmospheric Technician",
|
||||
"Roboticist"
|
||||
)
|
||||
|
||||
|
||||
@@ -85,7 +78,7 @@ var/list/science_positions = list(
|
||||
"Research Director",
|
||||
"Scientist",
|
||||
"Geneticist", //Part of both medical and science
|
||||
"Roboticist" //Part of both engineering and science
|
||||
"Roboticist"
|
||||
)
|
||||
|
||||
//BS12 EDIT
|
||||
|
||||
@@ -194,6 +194,10 @@
|
||||
name = "Circuit board (Mining Shuttle)"
|
||||
build_path = "/obj/machinery/computer/mining_shuttle"
|
||||
origin_tech = "programming=2"
|
||||
/obj/item/weapon/circuitboard/research_shuttle
|
||||
name = "Circuit board (Research Shuttle)"
|
||||
build_path = "/obj/machinery/computer/research_shuttle"
|
||||
origin_tech = "programming=2"
|
||||
/obj/item/weapon/circuitboard/HolodeckControl // Not going to let people get this, but it's just here for future
|
||||
name = "Circuit board (Holodeck Control)"
|
||||
build_path = "/obj/machinery/computer/HolodeckControl"
|
||||
|
||||
@@ -122,15 +122,6 @@
|
||||
if(emergency_shuttle.online)
|
||||
post_status("shuttle")
|
||||
src.state = STATE_DEFAULT
|
||||
if("crewtransfer")
|
||||
src.state= STATE_DEFAULT
|
||||
if(src.authenticated)
|
||||
src.state = STATE_CREWTRANSFER
|
||||
if("crewtransfer2")
|
||||
if(src.authenticated)
|
||||
init_shift_change(usr) //key difference here
|
||||
if(emergency_shuttle.online)
|
||||
post_status("shuttle")
|
||||
if("cancelshuttle")
|
||||
src.state = STATE_DEFAULT
|
||||
if(src.authenticated)
|
||||
@@ -323,7 +314,6 @@
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=cancelshuttle'>Cancel Shuttle Call</A> \]"
|
||||
else
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=callshuttle'>Call Emergency Shuttle</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=crewtransfer'>Initiate Crew Transfer</A> \]"
|
||||
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=status'>Set Status Display</A> \]"
|
||||
else
|
||||
@@ -331,8 +321,6 @@
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=messagelist'>Message List</A> \]"
|
||||
if(STATE_CALLSHUTTLE)
|
||||
dat += "Are you sure you want to call the shuttle? \[ <A HREF='?src=\ref[src];operation=callshuttle2'>OK</A> | <A HREF='?src=\ref[src];operation=main'>Cancel</A> \]"
|
||||
if(STATE_CREWTRANSFER) // this is the shiftchage screen.
|
||||
dat += "Are you sure you want to initiate a crew transfer? This will call the shuttle. \[ <a HREF='?src=\ref[src];operation=crewtransfer2'>OK</a> | <A HREF='?src=\ref[src];operation=main'>Cancel</A> \]"
|
||||
if(STATE_CANCELSHUTTLE)
|
||||
dat += "Are you sure you want to cancel the shuttle? \[ <A HREF='?src=\ref[src];operation=cancelshuttle2'>OK</A> | <A HREF='?src=\ref[src];operation=main'>Cancel</A> \]"
|
||||
if(STATE_MESSAGELIST)
|
||||
|
||||
@@ -6,66 +6,58 @@
|
||||
icon_state = "flood00"
|
||||
density = 1
|
||||
var/on = 0
|
||||
var/obj/item/weapon/cell/cell = null
|
||||
var/use = 1
|
||||
var/obj/item/weapon/cell/high/cell = null
|
||||
var/use = 5
|
||||
var/unlocked = 0
|
||||
var/open = 0
|
||||
var/brightness_on = 999 //can't remember what the maxed out value is
|
||||
|
||||
/obj/machinery/floodlight/New()
|
||||
src.cell = new(src)
|
||||
..()
|
||||
|
||||
/obj/machinery/floodlight/proc/updateicon()
|
||||
icon_state = "flood[open ? "o" : ""][open && cell ? "b" : ""]0[on]"
|
||||
|
||||
/obj/machinery/floodlight/process()
|
||||
if (!on)
|
||||
if (luminosity)
|
||||
if(on)
|
||||
cell.charge -= use
|
||||
if(cell.charge <= 0)
|
||||
on = 0
|
||||
updateicon()
|
||||
//sd_SetLuminosity(0)
|
||||
return
|
||||
|
||||
if(!luminosity && cell && cell.charge > 0)
|
||||
//sd_SetLuminosity(10)
|
||||
updateicon()
|
||||
|
||||
if(!cell && luminosity)
|
||||
on = 0
|
||||
updateicon()
|
||||
//sd_SetLuminosity(0)
|
||||
return
|
||||
|
||||
cell.charge -= use
|
||||
|
||||
if(cell.charge <= 0 && luminosity)
|
||||
on = 0
|
||||
updateicon()
|
||||
//sd_SetLuminosity(0)
|
||||
return
|
||||
SetLuminosity(0)
|
||||
src.visible_message("<span class='warning'>[src] shuts down due to lack of power!</span>")
|
||||
return
|
||||
|
||||
/obj/machinery/floodlight/attack_hand(mob/user as mob)
|
||||
if(open && cell)
|
||||
cell.loc = usr
|
||||
cell.layer = 20
|
||||
if (user.hand )
|
||||
user.l_hand = cell
|
||||
if(ishuman(user))
|
||||
if(!user.get_active_hand())
|
||||
user.put_in_hands(cell)
|
||||
cell.loc = user.loc
|
||||
else
|
||||
user.r_hand = cell
|
||||
cell.loc = loc
|
||||
|
||||
cell.add_fingerprint(user)
|
||||
updateicon()
|
||||
cell.updateicon()
|
||||
|
||||
src.cell = null
|
||||
user << "You remove the power cell"
|
||||
updateicon()
|
||||
return
|
||||
|
||||
if(on)
|
||||
on = 0
|
||||
user << "You turn off the light"
|
||||
user << "\blue You turn off the light"
|
||||
SetLuminosity(0)
|
||||
else
|
||||
if(!cell)
|
||||
return
|
||||
if(cell.charge <= 0)
|
||||
return
|
||||
on = 1
|
||||
user << "You turn on the light"
|
||||
user << "\blue You turn on the light"
|
||||
SetLuminosity(brightness_on)
|
||||
|
||||
updateicon()
|
||||
|
||||
@@ -101,10 +93,3 @@
|
||||
cell = W
|
||||
user << "You insert the power cell."
|
||||
updateicon()
|
||||
|
||||
/obj/machinery/floodlight/New()
|
||||
src.cell = new/obj/item/weapon/cell(src)
|
||||
cell.maxcharge = 1000
|
||||
cell.charge = 1000
|
||||
..()
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
if(istype(src.beaker, /obj/item/weapon/reagent_containers/blood))
|
||||
// speed up transfer on blood packs
|
||||
transfer_amount = 4
|
||||
src.beaker.reagents.trans_to(src.attached, transfer_amount)
|
||||
attached.inject_blood(beaker,transfer_amount)
|
||||
update_icon()
|
||||
|
||||
// Take blood
|
||||
@@ -99,52 +99,23 @@
|
||||
var/mob/living/carbon/human/T = attached
|
||||
|
||||
if(!istype(T)) return
|
||||
var/datum/reagent/B
|
||||
for(var/datum/reagent/blood/Blood in beaker.reagents.reagent_list)
|
||||
if(Blood.data && Blood.data["blood_type"]==T.dna.b_type)
|
||||
B = Blood
|
||||
break
|
||||
if(!B) B = new /datum/reagent/blood
|
||||
if(!T.dna)
|
||||
return
|
||||
if(NOCLONE in T.mutations)
|
||||
return
|
||||
|
||||
// If the human is losing too much blood, beep.
|
||||
if(T.vessel.get_reagent_amount("blood") < BLOOD_VOLUME_SAFE) if(prob(5))
|
||||
visible_message("\The [src] beeps loudly.")
|
||||
if(T.vessel.get_reagent_amount("blood") < amount)
|
||||
return
|
||||
B.holder = beaker
|
||||
B.volume += amount
|
||||
//set reagent data
|
||||
B.data["donor"] = T
|
||||
|
||||
if(T.virus2)
|
||||
B.data["virus2"] = T.virus2.getcopy()
|
||||
var/datum/reagent/B = T.take_blood(beaker,amount)
|
||||
|
||||
B.data["blood_DNA"] = copytext(T.dna.unique_enzymes,1,0)
|
||||
if(T.resistances && T.resistances.len)
|
||||
if(B.data["resistances"])
|
||||
B.data["resistances"] |= T.resistances.Copy()
|
||||
else
|
||||
B.data["resistances"] = T.resistances.Copy()
|
||||
|
||||
B.data["blood_type"] = copytext(T.dna.b_type,1,0)
|
||||
|
||||
var/list/temp_chem = list()
|
||||
for(var/datum/reagent/R in T.reagents.reagent_list)
|
||||
temp_chem += R.name
|
||||
temp_chem[R.name] = R.volume
|
||||
B.data["trace_chem"] = list2params(temp_chem)
|
||||
B.data["antibodies"] |= T.antibodies
|
||||
|
||||
T.vessel.remove_reagent("blood",amount) // Removes blood if human
|
||||
|
||||
beaker.reagents.reagent_list |= B
|
||||
beaker.reagents.update_total()
|
||||
beaker.on_reagent_change()
|
||||
beaker.reagents.handle_reactions()
|
||||
update_icon()
|
||||
if (B)
|
||||
beaker.reagents.reagent_list |= B
|
||||
beaker.reagents.update_total()
|
||||
beaker.on_reagent_change()
|
||||
beaker.reagents.handle_reactions()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/iv_drip/attack_hand(mob/user as mob)
|
||||
if(src.beaker)
|
||||
|
||||
@@ -85,6 +85,8 @@
|
||||
|
||||
M << "<B>You have joined the ranks of the Syndicate and become a traitor to the station!</B>"
|
||||
|
||||
message_admins("[N]/([N.ckey]) has accepted a traitor objective from a syndicate beacon.")
|
||||
|
||||
var/obj_count = 1
|
||||
for(var/datum/objective/OBJ in M.mind.objectives)
|
||||
M << "<B>Objective #[obj_count]</B>: [OBJ.explanation_text]"
|
||||
|
||||
@@ -20,6 +20,9 @@ proc/empulse(turf/epicenter, heavy_range, light_range, log=0)
|
||||
if(heavy_range > light_range)
|
||||
light_range = heavy_range
|
||||
|
||||
for(var/mob/M in range(heavy_range, epicenter))
|
||||
M << 'sound/effects/EMPulse.ogg'
|
||||
|
||||
for(var/atom/T in range(light_range, epicenter))
|
||||
var/distance = get_dist(epicenter, T)
|
||||
if(distance < 0)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
icon_state = "intercom"
|
||||
anchored = 1
|
||||
w_class = 4.0
|
||||
canhear_range = 7
|
||||
canhear_range = 2
|
||||
var/number = 0
|
||||
var/anyai = 1
|
||||
var/mob/living/silicon/ai/ai = list()
|
||||
|
||||
@@ -287,7 +287,7 @@
|
||||
var/datum/organ/external/affecting = H.get_organ(pick("l_foot", "r_foot"))
|
||||
if(affecting.status & ORGAN_ROBOT)
|
||||
return
|
||||
|
||||
|
||||
H.Weaken(3)
|
||||
if(affecting.take_damage(5, 0))
|
||||
H.UpdateDamageIcon()
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
/*
|
||||
* Spoons
|
||||
*/
|
||||
/obj/item/weapon/kitchen/utensil/spoon
|
||||
/obj/item/weapon/kitchen/utensil/spoon
|
||||
name = "spoon"
|
||||
desc = "SPOON!"
|
||||
icon_state = "spoon"
|
||||
|
||||
@@ -193,6 +193,10 @@ proc/move_mining_shuttle()
|
||||
var/digspeed = 40 //moving the delay to an item var so R&D can make improved picks. --NEO
|
||||
origin_tech = "materials=1;engineering=1"
|
||||
attack_verb = list("hit", "pierced", "sliced", "attacked")
|
||||
var/drill_sound = 'sound/weapons/Genhit.ogg'
|
||||
var/drill_verb = "picking"
|
||||
|
||||
var/excavation_amount = 100
|
||||
|
||||
hammer
|
||||
name = "sledgehammer"
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
/**********************Mineral deposits**************************/
|
||||
|
||||
#define XENOARCH_SPAWN_CHANCE 0.5
|
||||
#define XENOARCH_SPREAD_CHANCE 15
|
||||
#define ARTIFACT_SPAWN_CHANCE 20
|
||||
|
||||
/turf/simulated/mineral //wall piece
|
||||
name = "Rock"
|
||||
icon = 'icons/turf/walls.dmi'
|
||||
@@ -14,9 +18,18 @@
|
||||
var/mineralAmt = 0
|
||||
var/spread = 0 //will the seam spread?
|
||||
var/spreadChance = 0 //the percentual chance of an ore spreading to the neighbouring tiles
|
||||
var/artifactChance = 0.3 //percent chance to spawn a xenoarchaelogical artifact
|
||||
var/last_act = 0
|
||||
|
||||
var/datum/geosample/geological_data
|
||||
var/excavation_level = 0
|
||||
var/list/finds = list()
|
||||
var/list/excavation_minerals = list()
|
||||
var/next_rock = 0
|
||||
var/archaeo_overlay = ""
|
||||
var/excav_overlay = ""
|
||||
var/obj/item/weapon/last_find
|
||||
var/datum/artifact_find/artifact_find
|
||||
|
||||
/turf/simulated/mineral/Del()
|
||||
return
|
||||
|
||||
@@ -55,24 +68,89 @@
|
||||
T.overlays += image('icons/turf/walls.dmi', "rock_side_e", layer=6)
|
||||
|
||||
if (mineralName && mineralAmt && spread && spreadChance)
|
||||
if(prob(spreadChance))
|
||||
if(istype(get_step(src, SOUTH), /turf/simulated/mineral/random))
|
||||
new src.type(get_step(src, SOUTH))
|
||||
if(prob(spreadChance))
|
||||
if(istype(get_step(src, NORTH), /turf/simulated/mineral/random))
|
||||
new src.type(get_step(src, NORTH))
|
||||
if(prob(spreadChance))
|
||||
if(istype(get_step(src, WEST), /turf/simulated/mineral/random))
|
||||
new src.type(get_step(src, WEST))
|
||||
if(prob(spreadChance))
|
||||
if(istype(get_step(src, EAST), /turf/simulated/mineral/random))
|
||||
new src.type(get_step(src, EAST))
|
||||
for(var/trydir in list(1,2,4,8))
|
||||
if(prob(spreadChance))
|
||||
if(istype(get_step(src, trydir), /turf/simulated/mineral/random))
|
||||
var/turf/simulated/mineral/T = get_step(src, trydir)
|
||||
var/turf/simulated/mineral/M = new src.type(T)
|
||||
//keep any digsite data as constant as possible
|
||||
if(T.finds.len && !M.finds.len)
|
||||
M.finds = T.finds
|
||||
if(T.archaeo_overlay)
|
||||
M.overlays += archaeo_overlay
|
||||
|
||||
|
||||
//---- Xenoarchaeology BEGIN
|
||||
|
||||
//put into spawn so that digsite data can be preserved over the turf replacements via spreading mineral veins
|
||||
spawn(0)
|
||||
if(mineralAmt > 0 && !excavation_minerals.len)
|
||||
for(var/i=0, i<mineralAmt, i++)
|
||||
excavation_minerals.Add(rand(5,95))
|
||||
excavation_minerals = insertion_sort_numeric_list_descending(excavation_minerals)
|
||||
|
||||
if(!finds.len && prob(XENOARCH_SPAWN_CHANCE))
|
||||
//create a new archaeological deposit
|
||||
var/digsite = get_random_digsite_type()
|
||||
|
||||
var/list/turfs_to_process = list(src)
|
||||
var/list/processed_turfs = list()
|
||||
while(turfs_to_process.len)
|
||||
var/turf/simulated/mineral/M = turfs_to_process[1]
|
||||
for(var/turf/simulated/mineral/T in orange(1, M))
|
||||
if(T.finds.len)
|
||||
continue
|
||||
if(T in processed_turfs)
|
||||
continue
|
||||
if(prob(XENOARCH_SPREAD_CHANCE))
|
||||
turfs_to_process.Add(T)
|
||||
|
||||
turfs_to_process.Remove(M)
|
||||
processed_turfs.Add(M)
|
||||
if(!M.finds.len)
|
||||
if(prob(50))
|
||||
M.finds.Add(new/datum/find(digsite, rand(5,95)))
|
||||
else if(prob(75))
|
||||
M.finds.Add(new/datum/find(digsite, rand(5,45)))
|
||||
M.finds.Add(new/datum/find(digsite, rand(55,95)))
|
||||
else
|
||||
M.finds.Add(new/datum/find(digsite, rand(5,30)))
|
||||
M.finds.Add(new/datum/find(digsite, rand(35,75)))
|
||||
M.finds.Add(new/datum/find(digsite, rand(75,95)))
|
||||
|
||||
//sometimes a find will be close enough to the surface to show
|
||||
var/datum/find/F = M.finds[1]
|
||||
if(F.excavation_required <= F.view_range)
|
||||
archaeo_overlay = "overlay_archaeo[rand(1,3)]"
|
||||
M.overlays += archaeo_overlay
|
||||
|
||||
//dont create artifact machinery in animal or plant digsites, or if we already have one
|
||||
if(!artifact_find && digsite != 1 && digsite != 2 && prob(ARTIFACT_SPAWN_CHANCE))
|
||||
artifact_find = new()
|
||||
artifact_spawning_turfs.Add(src)
|
||||
|
||||
if(!src.geological_data)
|
||||
src.geological_data = new/datum/geosample(src)
|
||||
src.geological_data.UpdateTurf(src)
|
||||
|
||||
//for excavated turfs placeable in the map editor
|
||||
/*if(excavation_level > 0)
|
||||
if(excavation_level < 25)
|
||||
src.overlays += image('icons/obj/xenoarchaeology.dmi', "overlay_excv1_[rand(1,3)]")
|
||||
else if(excavation_level < 50)
|
||||
src.overlays += image('icons/obj/xenoarchaeology.dmi', "overlay_excv2_[rand(1,3)]")
|
||||
else if(excavation_level < 75)
|
||||
src.overlays += image('icons/obj/xenoarchaeology.dmi', "overlay_excv3_[rand(1,3)]")
|
||||
else
|
||||
src.overlays += image('icons/obj/xenoarchaeology.dmi', "overlay_excv4_[rand(1,3)]")
|
||||
desc = "It appears to be partially excavated."*/
|
||||
|
||||
return
|
||||
|
||||
/turf/simulated/mineral/random
|
||||
name = "Mineral deposit"
|
||||
var/mineralAmtList = list("Uranium" = 5, "Iron" = 5, "Diamond" = 5, "Gold" = 5, "Silver" = 5, "Plasma" = 5, "Archaeo" = 3/*, "Adamantine" = 5*/)
|
||||
var/mineralSpawnChanceList = list("Uranium" = 5, "Iron" = 50, "Diamond" = 1, "Gold" = 5, "Silver" = 5, "Plasma" = 25, "Archaeo" = 5/*, "Adamantine" =5*/)//Currently, Adamantine won't spawn as it has no uses. -Durandan
|
||||
var/mineralAmtList = list("Uranium" = 5, "Iron" = 5, "Diamond" = 5, "Gold" = 5, "Silver" = 5, "Plasma" = 5/*, "Adamantine" = 5*/)
|
||||
var/mineralSpawnChanceList = list("Uranium" = 5, "Iron" = 50, "Diamond" = 1, "Gold" = 5, "Silver" = 5, "Plasma" = 25/*, "Adamantine" =5*/)//Currently, Adamantine won't spawn as it has no uses. -Durandan
|
||||
var/mineralChance = 10 //means 10% chance of this plot changing to a mineral deposit
|
||||
|
||||
/turf/simulated/mineral/random/New()
|
||||
@@ -95,16 +173,22 @@
|
||||
M = new/turf/simulated/mineral/silver(src)
|
||||
if("Plasma")
|
||||
M = new/turf/simulated/mineral/plasma(src)
|
||||
if("Archaeo")
|
||||
M = new/turf/simulated/mineral/archaeo(src)
|
||||
/*if("Adamantine")
|
||||
M = new/turf/simulated/mineral/adamantine(src)*/
|
||||
if(M)
|
||||
src = M
|
||||
M.levelupdate()
|
||||
else if (prob(artifactChance))
|
||||
//spawn a rare, xeno-arch artifact here
|
||||
new/obj/machinery/artifact(src)
|
||||
|
||||
//preserve archaeo data
|
||||
M.geological_data = src.geological_data
|
||||
M.excavation_minerals = src.excavation_minerals
|
||||
M.overlays = src.overlays
|
||||
M.artifact_find = src.artifact_find
|
||||
M.archaeo_overlay = src.archaeo_overlay
|
||||
M.excav_overlay = src.excav_overlay
|
||||
|
||||
/*else if (prob(artifactChance))
|
||||
new/obj/machinery/artifact(src)*/
|
||||
return
|
||||
|
||||
/turf/simulated/mineral/random/high_chance
|
||||
@@ -169,15 +253,6 @@
|
||||
spread = 1
|
||||
|
||||
|
||||
/turf/simulated/mineral/archaeo
|
||||
name = "Strange rock formation"
|
||||
icon_state = "rock_Archaeo"
|
||||
mineralName = "Archaeo"
|
||||
mineralAmt = 3
|
||||
spreadChance = 25
|
||||
spread = 1
|
||||
|
||||
|
||||
/turf/simulated/mineral/clown
|
||||
name = "Bananium deposit"
|
||||
icon_state = "rock_Clown"
|
||||
@@ -222,6 +297,24 @@ commented out in r5061, I left it because of the shroom thingies
|
||||
usr << "\red You don't have the dexterity to do this!"
|
||||
return
|
||||
|
||||
if (istype(W, /obj/item/device/core_sampler))
|
||||
src.geological_data.UpdateNearbyArtifactInfo(src)
|
||||
var/obj/item/device/core_sampler/C = W
|
||||
C.sample_item(src, user)
|
||||
return
|
||||
|
||||
if (istype(W, /obj/item/device/depth_scanner))
|
||||
var/obj/item/device/depth_scanner/C = W
|
||||
C.scan_atom(user, src)
|
||||
return
|
||||
|
||||
if (istype(W, /obj/item/device/measuring_tape))
|
||||
var/obj/item/device/measuring_tape/P = W
|
||||
user.visible_message("\blue[user] extends [P] towards [src].","\blue You extend [P] towards [src].")
|
||||
if(do_after(user,40))
|
||||
user << "\blue \icon[P] [src] has been excavated to a depth of [2*src.excavation_level]cm."
|
||||
return
|
||||
|
||||
if (istype(W, /obj/item/weapon/pickaxe))
|
||||
var/turf/T = user.loc
|
||||
if (!( istype(T, /turf) ))
|
||||
@@ -233,56 +326,276 @@ commented out in r5061, I left it because of the shroom thingies
|
||||
return
|
||||
*/
|
||||
//Watch your tabbing, microwave. --NEO
|
||||
if(last_act+W:digspeed > world.time)//prevents message spam
|
||||
|
||||
var/obj/item/weapon/pickaxe/P = W
|
||||
if(last_act+P.digspeed > world.time)//prevents message spam
|
||||
return
|
||||
last_act = world.time
|
||||
user << "\red You start picking."
|
||||
playsound(user, 'sound/weapons/Genhit.ogg', 20, 1)
|
||||
|
||||
if(do_after(user,W:digspeed))
|
||||
user << "\blue You finish cutting into the rock."
|
||||
gets_drilled()
|
||||
playsound(user, P.drill_sound, 20, 1)
|
||||
|
||||
//handle any archaeological finds we might uncover
|
||||
var/fail_message
|
||||
if(src.finds.len)
|
||||
var/datum/find/F = src.finds[1]
|
||||
if(src.excavation_level + P.excavation_amount > F.excavation_required)
|
||||
//Chance to destroy / extract any finds here
|
||||
fail_message = ", <b>[pick("there is a crunching noise","[W] collides with some different rock","part of the rock face crumbles away","something breaks under [W]")]</b>"
|
||||
|
||||
user << "\red You start [P.drill_verb][fail_message ? fail_message : ""]."
|
||||
|
||||
if(fail_message)
|
||||
if(prob(50))
|
||||
if(prob(25))
|
||||
excavate_find(5, src.finds[1])
|
||||
else if(prob(50))
|
||||
src.finds.Remove(src.finds[1])
|
||||
|
||||
if(do_after(user,P.digspeed))
|
||||
user << "\blue You finish [P.drill_verb] the rock."
|
||||
|
||||
if(finds.len)
|
||||
var/datum/find/F = src.finds[1]
|
||||
if(round(src.excavation_level + P.excavation_amount) == F.excavation_required)
|
||||
//Chance to extract any items here perfectly, otherwise just pull them out along with the rock surrounding them
|
||||
if(src.excavation_level + P.excavation_amount > F.excavation_required)
|
||||
//if you can get slightly over, perfect extraction
|
||||
excavate_find(100, F)
|
||||
else
|
||||
excavate_find(80, F)
|
||||
|
||||
else if(src.excavation_level + P.excavation_amount > F.excavation_required - F.clearance_range)
|
||||
//just pull the surrounding rock out
|
||||
excavate_find(0, F)
|
||||
|
||||
if( src.excavation_level + P.excavation_amount >= 100 || (!finds.len && !excavation_minerals.len) )
|
||||
//if players have been excavating this turf, have a chance to leave some rocky debris behind
|
||||
var/boulder_prob = 0
|
||||
var/obj/structure/boulder/B
|
||||
|
||||
if(src.excavation_level > 15)
|
||||
boulder_prob = 10
|
||||
if(artifact_find)
|
||||
boulder_prob += 25
|
||||
if(src.excavation_level >= 100)
|
||||
boulder_prob += 40
|
||||
else if(src.excavation_level > 95)
|
||||
boulder_prob += 25
|
||||
else if(src.excavation_level > 90)
|
||||
boulder_prob += 10
|
||||
if(prob(boulder_prob))
|
||||
B = new(src)
|
||||
if(artifact_find)
|
||||
B.artifact_find = artifact_find
|
||||
else if(src.excavation_level + P.excavation_amount >= 100)
|
||||
spawn(0)
|
||||
artifact_debris()
|
||||
|
||||
gets_drilled(B ? 0 : 1)
|
||||
return
|
||||
else
|
||||
src.excavation_level += P.excavation_amount
|
||||
|
||||
//archaeo overlays
|
||||
if(!archaeo_overlay && finds.len)
|
||||
var/datum/find/F = src.finds[1]
|
||||
if(F.excavation_required <= src.excavation_level + F.view_range)
|
||||
archaeo_overlay = "overlay_archaeo[rand(1,3)]"
|
||||
overlays += archaeo_overlay
|
||||
|
||||
//there's got to be a better way to do this
|
||||
var/update_excav_overlay = 0
|
||||
if(src.excavation_level >= 75)
|
||||
if(src.excavation_level - P.excavation_amount < 75)
|
||||
update_excav_overlay = 1
|
||||
else if(src.excavation_level >= 50)
|
||||
if(src.excavation_level - P.excavation_amount < 50)
|
||||
update_excav_overlay = 1
|
||||
else if(src.excavation_level >= 25)
|
||||
if(src.excavation_level - P.excavation_amount < 25)
|
||||
update_excav_overlay = 1
|
||||
|
||||
//update overlays displaying excavation level
|
||||
if( !(excav_overlay && excavation_level > 0) || update_excav_overlay )
|
||||
var/excav_quadrant = round(excavation_level / 25) + 1
|
||||
excav_overlay = "overlay_excv[excav_quadrant]_[rand(1,3)]"
|
||||
overlays += excav_overlay
|
||||
|
||||
//extract pesky minerals while we're excavating
|
||||
while(excavation_minerals.len && src.excavation_level > excavation_minerals[excavation_minerals.len])
|
||||
drop_mineral()
|
||||
//have a 50% chance to extract bonus minerals this way
|
||||
//if(prob(50))
|
||||
pop(excavation_minerals)
|
||||
mineralAmt--
|
||||
|
||||
//drop some rocks
|
||||
next_rock += P.excavation_amount * 10
|
||||
while(next_rock > 100)
|
||||
next_rock -= 100
|
||||
var/obj/item/weapon/ore/O = new(src)
|
||||
src.geological_data.UpdateNearbyArtifactInfo(src)
|
||||
O.geological_data = src.geological_data
|
||||
|
||||
else
|
||||
return attack_hand(user)
|
||||
return
|
||||
|
||||
/turf/simulated/mineral/proc/gets_drilled()
|
||||
var/destroyed = 0 //used for breaking strange rocks
|
||||
/turf/simulated/mineral/proc/drop_mineral()
|
||||
var/obj/item/weapon/ore/O
|
||||
if (src.mineralName == "Uranium")
|
||||
O = new /obj/item/weapon/ore/uranium(src)
|
||||
if (src.mineralName == "Iron")
|
||||
O = new /obj/item/weapon/ore/iron(src)
|
||||
if (src.mineralName == "Gold")
|
||||
O = new /obj/item/weapon/ore/gold(src)
|
||||
if (src.mineralName == "Silver")
|
||||
O = new /obj/item/weapon/ore/silver(src)
|
||||
if (src.mineralName == "Plasma")
|
||||
O = new /obj/item/weapon/ore/plasma(src)
|
||||
if (src.mineralName == "Diamond")
|
||||
O = new /obj/item/weapon/ore/diamond(src)
|
||||
/*if (src.mineralName == "Archaeo")
|
||||
//new /obj/item/weapon/archaeological_find(src)
|
||||
//if(prob(10) || delicate)
|
||||
if(prob(50)) //Don't have delicate tools (hand pick/excavation tool) yet, temporarily change to 50% instead of 10% -Mij
|
||||
O = new /obj/item/weapon/ore/strangerock(src)
|
||||
else
|
||||
destroyed = 1*/
|
||||
if (src.mineralName == "Clown")
|
||||
O = new /obj/item/weapon/ore/clown(src)
|
||||
if(O)
|
||||
src.geological_data.UpdateNearbyArtifactInfo(src)
|
||||
O.geological_data = src.geological_data
|
||||
return O
|
||||
|
||||
/turf/simulated/mineral/proc/gets_drilled(var/artifact_fail = 0)
|
||||
//var/destroyed = 0 //used for breaking strange rocks
|
||||
if ((src.mineralName != "") && (src.mineralAmt > 0) && (src.mineralAmt < 11))
|
||||
var/i
|
||||
for (i=0;i<mineralAmt;i++)
|
||||
if (src.mineralName == "Uranium")
|
||||
new /obj/item/weapon/ore/uranium(src)
|
||||
if (src.mineralName == "Iron")
|
||||
new /obj/item/weapon/ore/iron(src)
|
||||
if (src.mineralName == "Gold")
|
||||
new /obj/item/weapon/ore/gold(src)
|
||||
if (src.mineralName == "Silver")
|
||||
new /obj/item/weapon/ore/silver(src)
|
||||
if (src.mineralName == "Plasma")
|
||||
new /obj/item/weapon/ore/plasma(src)
|
||||
if (src.mineralName == "Diamond")
|
||||
new /obj/item/weapon/ore/diamond(src)
|
||||
if (src.mineralName == "Archaeo")
|
||||
//spawn strange rocks here
|
||||
//if(prob(10) || delicate)
|
||||
if(prob(50)) //Don't have delicate tools (hand pick/excavation tool) yet, temporarily change to 50% instead of 10% -Mij
|
||||
new /obj/item/weapon/ore/strangerock(src)
|
||||
else
|
||||
destroyed = 1
|
||||
if (src.mineralName == "Clown")
|
||||
new /obj/item/weapon/ore/clown(src)
|
||||
if (prob(src.artifactChance))
|
||||
|
||||
//if the turf has already been excavated, some of it's ore has been removed
|
||||
for (var/i=0;i<mineralAmt;i++)
|
||||
drop_mineral()
|
||||
|
||||
/*if (prob(src.artifactChance))
|
||||
//spawn a rare artifact here
|
||||
new /obj/machinery/artifact(src)
|
||||
new /obj/machinery/artifact(src)*/
|
||||
var/turf/simulated/floor/plating/airless/asteroid/N = ChangeTurf(/turf/simulated/floor/plating/airless/asteroid)
|
||||
N.fullUpdateMineralOverlays()
|
||||
|
||||
if(destroyed) //Display message about being a terrible miner
|
||||
usr << "\red You destroy some of the rocks!"
|
||||
//destroyed artifacts have weird, unpleasant effects
|
||||
if(artifact_find && artifact_fail)
|
||||
var/pain = 0
|
||||
if(prob(50))
|
||||
pain = 1
|
||||
for(var/mob/living/M in range(src, 200))
|
||||
M << "<font color='red'><b>[pick("A high pitched [pick("keening","wailing","whistle")]","A rumbling noise like [pick("thunder","heavy machinery")]")] somehow penetrates your mind before fadaing away!</b></font>"
|
||||
if(pain)
|
||||
flick("pain",M.pain)
|
||||
if(prob(50))
|
||||
M.adjustBruteLoss(5)
|
||||
else
|
||||
flick("flash",M.flash)
|
||||
if(prob(50))
|
||||
M.Stun(5)
|
||||
M.apply_effect(25, IRRADIATE)
|
||||
|
||||
/*if(destroyed) //Display message about being a terrible miner
|
||||
usr << "\red You destroy some of the rocks!"*/
|
||||
return
|
||||
|
||||
/turf/simulated/mineral/proc/excavate_find(var/prob_clean = 0, var/datum/find/F)
|
||||
//with skill and luck, players can cleanly extract finds
|
||||
//otherwise, they come out inside a chunk of rock
|
||||
var/obj/item/weapon/X
|
||||
if(prob_clean)
|
||||
X = new/obj/item/weapon/archaeological_find(src, new_item_type = F.find_type)
|
||||
else
|
||||
X = new/obj/item/weapon/ore/strangerock(src, inside_item_type = F.find_type)
|
||||
src.geological_data.UpdateNearbyArtifactInfo(src)
|
||||
X:geological_data = src.geological_data
|
||||
|
||||
//some find types delete the /obj/item/weapon/archaeological_find and replace it with something else, this handles when that happens
|
||||
//yuck
|
||||
var/display_name = "something"
|
||||
if(!X)
|
||||
X = last_find
|
||||
if(X)
|
||||
display_name = X.name
|
||||
|
||||
//many finds are ancient and thus very delicate - luckily there is a specialised energy suspension field which protects them when they're being extracted
|
||||
if(prob(F.prob_delicate))
|
||||
var/obj/effect/suspension_field/S = locate() in src
|
||||
if(!S || S.field_type != get_responsive_reagent(F.find_type))
|
||||
if(X)
|
||||
src.visible_message("\red<b>[pick("[display_name] crumbles away into dust","[display_name] breaks apart","[display_name] collapses onto itself")].</b>")
|
||||
del(X)
|
||||
|
||||
src.finds.Remove(F)
|
||||
|
||||
/turf/simulated/mineral/proc/artifact_debris()
|
||||
//cael's patented random limited drop componentized loot system!
|
||||
var/materials = 0
|
||||
var/list/viable_materials = list(1,2,4,8,16,32,64,128,256)
|
||||
|
||||
var/num_materials = rand(1,5)
|
||||
for(var/i=0, i<num_materials, i++)
|
||||
var/chosen = pick(viable_materials)
|
||||
materials |= chosen
|
||||
viable_materials.Remove(chosen)
|
||||
|
||||
if(materials & 1)
|
||||
var/quantity = rand(0,3)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
var/obj/item/stack/rods/R = new(src)
|
||||
R.amount = rand(5,25)
|
||||
|
||||
if(materials & 2)
|
||||
var/quantity = pick(0, 0, 1)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
var/obj/item/stack/tile/R = new(src)
|
||||
R.amount = rand(1,5)
|
||||
|
||||
if(materials & 4)
|
||||
var/quantity = rand(0,3)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
var/obj/item/stack/sheet/metal/R = new(src)
|
||||
R.amount = rand(5,25)
|
||||
|
||||
if(materials & 8)
|
||||
var/quantity = rand(0,3)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
var/obj/item/stack/sheet/plasteel/R = new(src)
|
||||
R.amount = rand(5,25)
|
||||
|
||||
if(materials & 16)
|
||||
var/quantity = rand(0,3)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
new /obj/item/weapon/shard(src)
|
||||
|
||||
if(materials & 32)
|
||||
var/quantity = rand(0,3)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
new /obj/item/weapon/shard/plasma(src)
|
||||
|
||||
if(materials & 64)
|
||||
var/quantity = rand(0,3)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
var/obj/item/stack/sheet/mineral/uranium/R = new(src)
|
||||
R.amount = rand(5,25)
|
||||
|
||||
if(materials & 128)
|
||||
var/quantity = rand(0,3)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
var/obj/item/stack/sheet/mineral/mythril/R = new(src)
|
||||
R.amount = rand(5,25)
|
||||
|
||||
if(materials & 256)
|
||||
var/quantity = rand(0,3)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
var/obj/item/stack/sheet/mineral/adamantine/R = new(src)
|
||||
R.amount = rand(5,25)
|
||||
|
||||
/*
|
||||
/turf/simulated/mineral/proc/setRandomMinerals()
|
||||
var/s = pickweight(list("uranium" = 5, "iron" = 50, "gold" = 5, "silver" = 5, "plasma" = 50, "diamond" = 1))
|
||||
@@ -448,7 +761,6 @@ commented out in r5061, I left it because of the shroom thingies
|
||||
if(istype(get_step(src, WEST), /turf/simulated/mineral))
|
||||
src.overlays += image('icons/turf/walls.dmi', "rock_side_w", layer=6)
|
||||
|
||||
|
||||
/turf/simulated/floor/plating/airless/asteroid/proc/fullUpdateMineralOverlays()
|
||||
var/turf/simulated/floor/plating/airless/asteroid/A
|
||||
if(istype(get_step(src, WEST), /turf/simulated/floor/plating/airless/asteroid))
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
/obj/item/weapon/ore
|
||||
name = "Rock"
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "ore"
|
||||
|
||||
icon_state = "ore2"
|
||||
var/datum/geosample/geological_data
|
||||
|
||||
/obj/item/weapon/ore/uranium
|
||||
name = "Uranium ore"
|
||||
@@ -59,19 +59,16 @@
|
||||
desc = "Completely useless"
|
||||
icon_state = "slag"
|
||||
|
||||
/obj/item/weapon/ore/strangerock //see artifact_archaeo.dm in modules/research for more info
|
||||
name = "Strange rock"
|
||||
desc = "Seems to have some unusal strata evident throughout it."
|
||||
icon_state = "strange"
|
||||
var/obj/inside
|
||||
var/method // 0 = fire, 1+ = acid
|
||||
origin_tech = "materials=5"
|
||||
//unacidable = 1 //This can prevent acid from gooey grey massing
|
||||
|
||||
/obj/item/weapon/ore/New()
|
||||
pixel_x = rand(0,16)-8
|
||||
pixel_y = rand(0,8)-8
|
||||
|
||||
/obj/item/weapon/ore/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/device/core_sampler))
|
||||
var/obj/item/device/core_sampler/C = W
|
||||
C.sample_item(src, user)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/*****************************Coin********************************/
|
||||
|
||||
@@ -152,4 +149,4 @@
|
||||
overlays = list()
|
||||
string_attached = null
|
||||
user << "\blue You detach the string from the coin."
|
||||
else ..()
|
||||
else ..()
|
||||
|
||||
@@ -5,10 +5,6 @@
|
||||
icon = 'icons/mob/human.dmi'
|
||||
icon_state = "body_m_s"
|
||||
|
||||
var/datum/reagents/vessel
|
||||
// TODO: make this actually affect the way the mob is rendered
|
||||
var/pale = 0
|
||||
|
||||
|
||||
/mob/living/carbon/human/dummy
|
||||
real_name = "Test Dummy"
|
||||
@@ -24,78 +20,14 @@
|
||||
if(!dna)
|
||||
dna = new /datum/dna(null)
|
||||
|
||||
//initialise organs
|
||||
organs = list()
|
||||
organs_by_name["chest"] = new/datum/organ/external/chest()
|
||||
organs_by_name["groin"] = new/datum/organ/external/groin(organs_by_name["chest"])
|
||||
organs_by_name["head"] = new/datum/organ/external/head(organs_by_name["chest"])
|
||||
organs_by_name["l_arm"] = new/datum/organ/external/l_arm(organs_by_name["chest"])
|
||||
organs_by_name["r_arm"] = new/datum/organ/external/r_arm(organs_by_name["chest"])
|
||||
organs_by_name["r_leg"] = new/datum/organ/external/r_leg(organs_by_name["groin"])
|
||||
organs_by_name["l_leg"] = new/datum/organ/external/l_leg(organs_by_name["groin"])
|
||||
organs_by_name["l_hand"] = new/datum/organ/external/l_hand(organs_by_name["l_arm"])
|
||||
organs_by_name["r_hand"] = new/datum/organ/external/r_hand(organs_by_name["r_arm"])
|
||||
organs_by_name["l_foot"] = new/datum/organ/external/l_foot(organs_by_name["l_leg"])
|
||||
organs_by_name["r_foot"] = new/datum/organ/external/r_foot(organs_by_name["r_leg"])
|
||||
|
||||
new/datum/organ/internal/heart(src)
|
||||
new/datum/organ/internal/lungs(src)
|
||||
new/datum/organ/internal/liver(src)
|
||||
new/datum/organ/internal/kidney(src)
|
||||
new/datum/organ/internal/brain(src)
|
||||
|
||||
|
||||
for(var/name in organs_by_name)
|
||||
organs += organs_by_name[name]
|
||||
|
||||
for(var/datum/organ/external/O in organs)
|
||||
O.owner = src
|
||||
|
||||
..()
|
||||
|
||||
if(dna)
|
||||
dna.real_name = real_name
|
||||
|
||||
prev_gender = gender // Debug for plural genders
|
||||
|
||||
|
||||
vessel = new/datum/reagents(600)
|
||||
vessel.my_atom = src
|
||||
vessel.add_reagent("blood",560)
|
||||
spawn(1)
|
||||
fixblood()
|
||||
|
||||
/mob/living/carbon/human/proc/drip(var/amt as num)
|
||||
if(!amt)
|
||||
return
|
||||
|
||||
var/amm = 0.1 * amt
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/obj/effect/decal/cleanable/blood/drip/nums = list()
|
||||
var/list/iconL = list("1","2","3","4","5")
|
||||
|
||||
vessel.remove_reagent("blood",amm)
|
||||
|
||||
for(var/obj/effect/decal/cleanable/blood/drip/G in T)
|
||||
nums += G
|
||||
iconL.Remove(G.icon_state)
|
||||
|
||||
if (nums.len < 5)
|
||||
var/obj/effect/decal/cleanable/blood/drip/this = new(T)
|
||||
this.icon_state = pick(iconL)
|
||||
this.blood_DNA = list()
|
||||
this.blood_DNA[dna.unique_enzymes] = dna.b_type
|
||||
else
|
||||
for(var/obj/effect/decal/cleanable/blood/drip/G in nums)
|
||||
del G
|
||||
T.add_blood(src)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/fixblood()
|
||||
for(var/datum/reagent/blood/B in vessel.reagent_list)
|
||||
if(B.id == "blood")
|
||||
B.data = list("donor"=src,"viruses"=null,"blood_DNA"=dna.unique_enzymes,"blood_type"=dna.b_type,"resistances"=null,"trace_chem"=null, "virus2" = null, "antobodies" = null)
|
||||
|
||||
make_organs()
|
||||
make_blood()
|
||||
|
||||
/mob/living/carbon/human/Bump(atom/movable/AM as mob|obj, yes)
|
||||
if ((!( yes ) || now_pushing))
|
||||
|
||||
@@ -47,9 +47,6 @@
|
||||
var/icon/stand_icon = null
|
||||
var/icon/lying_icon = null
|
||||
|
||||
var/list/organs = list() //Gets filled up in the constructor (human.dm, New() proc, line 24. I'm sick and tired of missing comments. -Agouri
|
||||
var/list/organs_by_name = list() // map organ names to organs
|
||||
|
||||
var/miming = null //Toggle for the mime's abilities.
|
||||
var/special_voice = "" // For changing our voice. Used by a symptom.
|
||||
|
||||
|
||||
@@ -21,11 +21,6 @@
|
||||
#define COLD_GAS_DAMAGE_LEVEL_2 1.5 //Amount of damage applied when the current breath's temperature passes the 200K point
|
||||
#define COLD_GAS_DAMAGE_LEVEL_3 3 //Amount of damage applied when the current breath's temperature passes the 120K point
|
||||
|
||||
var/const/BLOOD_VOLUME_SAFE = 501
|
||||
var/const/BLOOD_VOLUME_OKAY = 336
|
||||
var/const/BLOOD_VOLUME_BAD = 224
|
||||
var/const/BLOOD_VOLUME_SURVIVE = 122
|
||||
|
||||
/mob/living/carbon/human
|
||||
var/oxygen_alert = 0
|
||||
var/toxins_alert = 0
|
||||
@@ -133,100 +128,6 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
|
||||
|
||||
/mob/living/carbon/human
|
||||
|
||||
proc/handle_blood()
|
||||
// take care of blood and blood loss
|
||||
if(stat < 2 && bodytemperature >= 170)
|
||||
var/blood_volume = round(vessel.get_reagent_amount("blood"))
|
||||
if(blood_volume < 560 && blood_volume)
|
||||
var/datum/reagent/blood/B = locate() in vessel.reagent_list //Grab some blood
|
||||
if(B) // Make sure there's some blood at all
|
||||
if(B.data["donor"] != src) //If it's not theirs, then we look for theirs
|
||||
for(var/datum/reagent/blood/D in vessel.reagent_list)
|
||||
if(D.data["donor"] == src)
|
||||
B = D
|
||||
break
|
||||
var/datum/reagent/nutriment/F = locate() in reagents.reagent_list
|
||||
if(F != null)
|
||||
if(F.volume >= 1)
|
||||
// nutriment speeds it up quite a bit
|
||||
B.volume += 0.4
|
||||
F.volume -= 0.1
|
||||
else
|
||||
//At this point, we dun care which blood we are adding to, as long as they get more blood.
|
||||
B.volume = B.volume + 0.1 // regenerate blood VERY slowly
|
||||
|
||||
// Damaged heart virtually reduces the blood volume, as the blood isn't
|
||||
// being pumped properly anymore.
|
||||
var/datum/organ/internal/heart/heart = internal_organs["heart"]
|
||||
switch(heart.damage)
|
||||
if(5 to 10)
|
||||
blood_volume *= 0.8
|
||||
if(11 to 20)
|
||||
blood_volume *= 0.5
|
||||
if(21 to INFINITY)
|
||||
blood_volume *= 0.3
|
||||
|
||||
switch(blood_volume)
|
||||
if(BLOOD_VOLUME_SAFE to 10000)
|
||||
if(pale)
|
||||
pale = 0
|
||||
update_body()
|
||||
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
|
||||
if(!pale)
|
||||
pale = 1
|
||||
update_body()
|
||||
var/word = pick("dizzy","woosey","faint")
|
||||
src << "\red You feel [word]"
|
||||
if(prob(1))
|
||||
var/word = pick("dizzy","woosey","faint")
|
||||
src << "\red You feel [word]"
|
||||
if(oxyloss < 20)
|
||||
// hint that they're getting close to suffocation
|
||||
oxyloss += 3
|
||||
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
|
||||
if(!pale)
|
||||
pale = 1
|
||||
update_body()
|
||||
eye_blurry += 6
|
||||
if(oxyloss < 50)
|
||||
oxyloss += 10
|
||||
oxyloss += 1
|
||||
if(prob(15))
|
||||
Paralyse(rand(1,3))
|
||||
var/word = pick("dizzy","woosey","faint")
|
||||
src << "\red You feel extremely [word]"
|
||||
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
|
||||
oxyloss += 5
|
||||
toxloss += 5
|
||||
if(prob(15))
|
||||
var/word = pick("dizzy","woosey","faint")
|
||||
src << "\red You feel extremely [word]"
|
||||
if(0 to BLOOD_VOLUME_SURVIVE)
|
||||
// There currently is a strange bug here. If the mob is not below -100 health
|
||||
// when death() is called, apparently they will be just fine, and this way it'll
|
||||
// spam deathgasp. Adjusting toxloss ensures the mob will stay dead.
|
||||
toxloss += 300 // just to be safe!
|
||||
death()
|
||||
|
||||
// Without enough blood you slowly go hungry.
|
||||
if(blood_volume < BLOOD_VOLUME_SAFE)
|
||||
if(nutrition >= 300)
|
||||
nutrition -= 10
|
||||
else if(nutrition >= 200)
|
||||
nutrition -= 3
|
||||
|
||||
var/blood_max = 0
|
||||
for(var/datum/organ/external/temp in organs)
|
||||
if(!(temp.status & ORGAN_BLEEDING) || temp.status & ORGAN_ROBOT)
|
||||
continue
|
||||
for(var/datum/wound/W in temp.wounds) if(W.bleeding())
|
||||
blood_max += W.damage / 4
|
||||
if(temp.status & ORGAN_DESTROYED && !(temp.status & ORGAN_GAUZED) && !temp.amputated)
|
||||
blood_max += 20 //Yer missing a fucking limb.
|
||||
if (temp.open)
|
||||
blood_max += 2 //Yer stomach is cut open
|
||||
drip(blood_max)
|
||||
|
||||
proc/handle_disabilities()
|
||||
if (disabilities & EPILEPSY)
|
||||
if ((prob(1) && paralysis < 1))
|
||||
@@ -293,108 +194,6 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
|
||||
src << "\red Your legs won't respond properly, you fall down."
|
||||
lying = 1
|
||||
|
||||
proc/handle_organs()
|
||||
// take care of organ related updates, such as broken and missing limbs
|
||||
|
||||
// recalculate number of wounds
|
||||
number_wounds = 0
|
||||
for(var/datum/organ/external/E in organs)
|
||||
if(!E)
|
||||
world << name
|
||||
continue
|
||||
number_wounds += E.number_wounds
|
||||
|
||||
var/leg_tally = 2
|
||||
var/canstand_l = 1 //Can stand on left leg
|
||||
var/canstand_r = 1 //Can stand on right leg
|
||||
var/hasleg_l = 1 //Have left leg
|
||||
var/hasleg_r = 1 //Have right leg
|
||||
var/hasarm_l = 1 //Have left arm
|
||||
var/hasarm_r = 1 //Have right arm
|
||||
for(var/datum/organ/external/E in organs)
|
||||
E.process()
|
||||
if(E.status & ORGAN_ROBOT && prob(E.brute_dam + E.burn_dam))
|
||||
if(E.name == "l_hand" || E.name == "l_arm")
|
||||
if(hand && equipped())
|
||||
drop_item()
|
||||
emote("me", 1, "drops what they were holding, their [E.display_name?"[E.display_name]":"[E]"] malfunctioning!")
|
||||
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
|
||||
spark_system.set_up(5, 0, src)
|
||||
spark_system.attach(src)
|
||||
spark_system.start()
|
||||
spawn(10)
|
||||
del(spark_system)
|
||||
else if(E.name == "r_hand" || E.name == "r_arm")
|
||||
if(!hand && equipped())
|
||||
drop_item()
|
||||
emote("me", 1, "drops what they were holding, their [E.display_name?"[E.display_name]":"[E]"] malfunctioning!")
|
||||
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
|
||||
spark_system.set_up(5, 0, src)
|
||||
spark_system.attach(src)
|
||||
spark_system.start()
|
||||
spawn(10)
|
||||
del(spark_system)
|
||||
else if(E.name == "l_leg" || E.name == "l_foot" \
|
||||
|| E.name == "r_leg" || E.name == "r_foot" && !lying)
|
||||
leg_tally-- // let it fail even if just foot&leg
|
||||
if(E.status & ORGAN_BROKEN || (E.status & ORGAN_DESTROYED && !E.amputated))
|
||||
if(E.name == "l_hand" || E.name == "l_arm")
|
||||
if(hand && equipped())
|
||||
if(E.status & ORGAN_SPLINTED && prob(10))
|
||||
drop_item()
|
||||
emote("scream")
|
||||
else
|
||||
drop_item()
|
||||
emote("scream")
|
||||
else if(E.name == "r_hand" || E.name == "r_arm")
|
||||
if(!hand && equipped())
|
||||
if(E.status & ORGAN_SPLINTED && prob(10))
|
||||
drop_item()
|
||||
emote("scream")
|
||||
else
|
||||
drop_item()
|
||||
emote("scream")
|
||||
else if(E.name == "l_leg" || E.name == "l_foot" \
|
||||
|| E.name == "r_leg" || E.name == "r_foot" && !lying)
|
||||
if(!(E.status & ORGAN_SPLINTED))
|
||||
leg_tally-- // let it fail even if just foot&leg
|
||||
|
||||
// standing is poor
|
||||
if(leg_tally <= 0 && !paralysis && !(lying || resting) && prob(5))
|
||||
emote("scream")
|
||||
emote("collapse")
|
||||
paralysis = 10
|
||||
|
||||
|
||||
//Check arms and legs for existence
|
||||
var/datum/organ/external/E
|
||||
E = get_organ("l_leg")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
canstand_l = 0
|
||||
hasleg_l = 0
|
||||
E = get_organ("r_leg")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
canstand_r = 0
|
||||
hasleg_r = 0
|
||||
E = get_organ("l_foot")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
canstand_l = 0
|
||||
E = get_organ("r_foot")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
canstand_r = 0
|
||||
E = get_organ("l_arm")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
hasarm_l = 0
|
||||
E = get_organ("r_arm")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
hasarm_r = 0
|
||||
|
||||
// Can stand if have at least one full leg (with leg and foot parts present)
|
||||
// Has limbs to move around if at least one arm or leg is at least partially there
|
||||
can_stand = canstand_l||canstand_r
|
||||
has_limbs = hasleg_l||hasleg_r||hasarm_l||hasarm_r
|
||||
|
||||
|
||||
proc/handle_mutations_and_radiation()
|
||||
if(getFireLoss())
|
||||
if((COLD_RESISTANCE in mutations) || (prob(1)))
|
||||
@@ -457,20 +256,14 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
|
||||
if(reagents.has_reagent("lexorin")) return
|
||||
if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return
|
||||
|
||||
var/lung_ruptured = is_lung_ruptured()
|
||||
|
||||
if(lung_ruptured && prob(2))
|
||||
spawn emote("me", 1, "coughs up blood!")
|
||||
src.drip(10)
|
||||
var/datum/organ/internal/lungs/L = internal_organs["lungs"]
|
||||
L.process()
|
||||
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
var/datum/gas_mixture/breath
|
||||
// HACK NEED CHANGING LATER
|
||||
if(health < 0)
|
||||
losebreath++
|
||||
if(lung_ruptured && prob(4))
|
||||
spawn emote("me", 1, "gasps for air!")
|
||||
losebreath += 5
|
||||
if(losebreath>0) //Suffocating so do not take a breath
|
||||
losebreath--
|
||||
if (prob(10)) //Gasp per 10 ticks? Sounds about right.
|
||||
@@ -500,7 +293,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
|
||||
breath = loc.remove_air(breath_moles)
|
||||
|
||||
|
||||
if(!lung_ruptured)
|
||||
if(!is_lung_ruptured())
|
||||
if(!breath || breath.total_moles < BREATH_MOLES / 5 || breath.total_moles > BREATH_MOLES * 5)
|
||||
if(prob(5))
|
||||
rupture_lung()
|
||||
@@ -1063,34 +856,10 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
|
||||
dizziness = max(0, dizziness - 3)
|
||||
jitteriness = max(0, jitteriness - 3)
|
||||
|
||||
handle_trace_chems()
|
||||
|
||||
if(life_tick % 10 == 0)
|
||||
// handle trace chemicals for autopsy
|
||||
for(var/datum/organ/O in organs)
|
||||
for(var/chemID in O.trace_chemicals)
|
||||
O.trace_chemicals[chemID] = O.trace_chemicals[chemID] - 1
|
||||
if(O.trace_chemicals[chemID] <= 0)
|
||||
O.trace_chemicals.Remove(chemID)
|
||||
for(var/datum/reagent/A in reagents.reagent_list)
|
||||
// add chemistry traces to a random organ
|
||||
var/datum/organ/O = pick(organs)
|
||||
O.trace_chemicals[A.name] = 100
|
||||
|
||||
var/damaged_liver_process_accuracy = 10
|
||||
if(life_tick % damaged_liver_process_accuracy == 0)
|
||||
// Damaged liver means some chemicals are very dangerous
|
||||
var/datum/organ/internal/liver/liver = internal_organs["liver"]
|
||||
if(liver.damage >= liver.min_bruised_damage)
|
||||
for(var/datum/reagent/R in src.reagents.reagent_list)
|
||||
// Ethanol and all drinks are bad
|
||||
if(istype(R, /datum/reagent/ethanol))
|
||||
adjustToxLoss(0.1 * damaged_liver_process_accuracy)
|
||||
|
||||
// Can't cope with toxins at all
|
||||
for(var/toxin in list("toxin", "plasma", "sacid", "pacid", "cyanide", "lexorin", "amatoxin", "chloralhydrate", "carpotoxin", "zombiepowder", "mindbreaker"))
|
||||
if(src.reagents.has_reagent(toxin))
|
||||
adjustToxLoss(0.3 * damaged_liver_process_accuracy)
|
||||
|
||||
var/datum/organ/internal/liver/liver = internal_organs["liver"]
|
||||
liver.process()
|
||||
|
||||
updatehealth()
|
||||
|
||||
|
||||
@@ -450,9 +450,10 @@ var/list/department_radio_keys = list(
|
||||
del(B)
|
||||
*/
|
||||
|
||||
//talking crystals
|
||||
for(var/obj/item/weapon/talkingcrystal/O in view(3,src))
|
||||
O.catchMessage(message,src)
|
||||
//talking items
|
||||
for(var/obj/item/weapon/O in view(3,src))
|
||||
if(O.listening_to_players)
|
||||
O.catchMessage(message, src)
|
||||
|
||||
log_say("[name]/[key] : [message]")
|
||||
|
||||
|
||||
213
code/modules/organs/blood.dm
Normal file
213
code/modules/organs/blood.dm
Normal file
@@ -0,0 +1,213 @@
|
||||
/****************************************************
|
||||
BLOOD SYSTEM
|
||||
****************************************************/
|
||||
//Blood levels
|
||||
var/const/BLOOD_VOLUME_SAFE = 501
|
||||
var/const/BLOOD_VOLUME_OKAY = 336
|
||||
var/const/BLOOD_VOLUME_BAD = 224
|
||||
var/const/BLOOD_VOLUME_SURVIVE = 122
|
||||
|
||||
/mob/living/carbon/human/var/datum/reagents/vessel //Container for blood and BLOOD ONLY. Do not transfer other chems here.
|
||||
/mob/living/carbon/human/var/var/pale = 0 //Should affect how mob sprite is drawn, but currently doesn't.
|
||||
|
||||
//Initializes blood vessels
|
||||
/mob/living/carbon/human/proc/make_blood()
|
||||
if (vessel)
|
||||
return
|
||||
vessel = new/datum/reagents(600)
|
||||
vessel.my_atom = src
|
||||
vessel.add_reagent("blood",560)
|
||||
spawn(1)
|
||||
fixblood()
|
||||
|
||||
//Resets blood data
|
||||
/mob/living/carbon/human/proc/fixblood()
|
||||
for(var/datum/reagent/blood/B in vessel.reagent_list)
|
||||
if(B.id == "blood")
|
||||
B.data = list( "donor"=src,"viruses"=null,"blood_DNA"=dna.unique_enzymes,"blood_type"=dna.b_type, \
|
||||
"resistances"=null,"trace_chem"=null, "virus2" = null, "antobodies" = null)
|
||||
|
||||
// Takes care blood loss and regeneration
|
||||
/mob/living/carbon/human/proc/handle_blood()
|
||||
if(stat != DEAD && bodytemperature >= 170) //Dead or cryosleep people do not pump the blood.
|
||||
|
||||
var/blood_volume = round(vessel.get_reagent_amount("blood"))
|
||||
|
||||
//Blood regeneration if there is some space
|
||||
if(blood_volume < 560 && blood_volume)
|
||||
var/datum/reagent/blood/B = locate() in vessel.reagent_list //Grab some blood
|
||||
if(B) // Make sure there's some blood at all
|
||||
if(B.data["donor"] != src) //If it's not theirs, then we look for theirs
|
||||
for(var/datum/reagent/blood/D in vessel.reagent_list)
|
||||
if(D.data["donor"] == src)
|
||||
B = D
|
||||
break
|
||||
|
||||
B.volume += 0.1 // regenerate blood VERY slowly
|
||||
if (reagents.has_reagent("nutriment")) //Getting food speeds it up
|
||||
B.volume += 0.4
|
||||
reagents.remove_reagent("nutriment", 0.1)
|
||||
if (reagents.has_reagent("iron")) //Hematogen candy anyone?
|
||||
B.volume += 0.8
|
||||
reagents.remove_reagent("iron", 0.1)
|
||||
|
||||
// Damaged heart virtually reduces the blood volume, as the blood isn't
|
||||
// being pumped properly anymore.
|
||||
var/datum/organ/internal/heart/heart = internal_organs["heart"]
|
||||
switch(heart.damage)
|
||||
if(5 to 10)
|
||||
blood_volume *= 0.8
|
||||
if(11 to 20)
|
||||
blood_volume *= 0.5
|
||||
if(21 to INFINITY)
|
||||
blood_volume *= 0.3
|
||||
|
||||
//Effects of bloodloss
|
||||
switch(blood_volume)
|
||||
if(BLOOD_VOLUME_SAFE to 10000)
|
||||
if(pale)
|
||||
pale = 0
|
||||
update_body()
|
||||
if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE)
|
||||
if(!pale)
|
||||
pale = 1
|
||||
update_body()
|
||||
var/word = pick("dizzy","woosey","faint")
|
||||
src << "\red You feel [word]"
|
||||
if(prob(1))
|
||||
var/word = pick("dizzy","woosey","faint")
|
||||
src << "\red You feel [word]"
|
||||
if(oxyloss < 20)
|
||||
oxyloss += 3
|
||||
if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY)
|
||||
if(!pale)
|
||||
pale = 1
|
||||
update_body()
|
||||
eye_blurry += 6
|
||||
if(oxyloss < 50)
|
||||
oxyloss += 10
|
||||
oxyloss += 1
|
||||
if(prob(15))
|
||||
Paralyse(rand(1,3))
|
||||
var/word = pick("dizzy","woosey","faint")
|
||||
src << "\red You feel extremely [word]"
|
||||
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
|
||||
oxyloss += 5
|
||||
toxloss += 5
|
||||
if(prob(15))
|
||||
var/word = pick("dizzy","woosey","faint")
|
||||
src << "\red You feel extremely [word]"
|
||||
if(0 to BLOOD_VOLUME_SURVIVE)
|
||||
// There currently is a strange bug here. If the mob is not below -100 health
|
||||
// when death() is called, apparently they will be just fine, and this way it'll
|
||||
// spam deathgasp. Adjusting toxloss ensures the mob will stay dead.
|
||||
toxloss += 300 // just to be safe!
|
||||
death()
|
||||
|
||||
// Without enough blood you slowly go hungry.
|
||||
if(blood_volume < BLOOD_VOLUME_SAFE)
|
||||
if(nutrition >= 300)
|
||||
nutrition -= 10
|
||||
else if(nutrition >= 200)
|
||||
nutrition -= 3
|
||||
|
||||
//Bleeding out
|
||||
var/blood_max = 0
|
||||
for(var/datum/organ/external/temp in organs)
|
||||
if(!(temp.status & ORGAN_BLEEDING) || temp.status & ORGAN_ROBOT)
|
||||
continue
|
||||
for(var/datum/wound/W in temp.wounds) if(W.bleeding())
|
||||
blood_max += W.damage / 4
|
||||
if(temp.status & ORGAN_DESTROYED && !(temp.status & ORGAN_GAUZED) && !temp.amputated)
|
||||
blood_max += 20 //Yer missing a fucking limb.
|
||||
if (temp.open)
|
||||
blood_max += 2 //Yer stomach is cut open
|
||||
drip(blood_max)
|
||||
|
||||
//Makes a blood drop, leaking certain amount of blood from the mob
|
||||
/mob/living/carbon/human/proc/drip(var/amt as num)
|
||||
if(!amt)
|
||||
return
|
||||
|
||||
var/amm = 0.1 * amt
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/obj/effect/decal/cleanable/blood/drip/nums = list()
|
||||
var/list/iconL = list("1","2","3","4","5")
|
||||
|
||||
vessel.remove_reagent("blood",amm)
|
||||
|
||||
for(var/obj/effect/decal/cleanable/blood/drip/G in T)
|
||||
nums += G
|
||||
iconL.Remove(G.icon_state)
|
||||
|
||||
if (nums.len < 5)
|
||||
var/obj/effect/decal/cleanable/blood/drip/this = new(T)
|
||||
this.icon_state = pick(iconL)
|
||||
this.blood_DNA = list()
|
||||
this.blood_DNA[dna.unique_enzymes] = dna.b_type
|
||||
else
|
||||
for(var/obj/effect/decal/cleanable/blood/drip/G in nums)
|
||||
del G
|
||||
T.add_blood(src)
|
||||
|
||||
/****************************************************
|
||||
BLOOD TRANSFERS
|
||||
****************************************************/
|
||||
|
||||
//Gets blood from mob to the container, preserving all data in it.
|
||||
/mob/living/carbon/proc/take_blood(obj/item/weapon/reagent_containers/container, var/amount)
|
||||
var/datum/reagent/B = get_blood(container.reagents)
|
||||
if(!B) B = new /datum/reagent/blood
|
||||
B.holder = container
|
||||
B.volume += amount
|
||||
|
||||
//set reagent data
|
||||
B.data["donor"] = src
|
||||
if(src.virus2)
|
||||
B.data["virus2"] = src.virus2.getcopy()
|
||||
B.data["antibodies"] |= src.antibodies
|
||||
B.data["blood_DNA"] = copytext(src.dna.unique_enzymes,1,0)
|
||||
if(src.resistances && src.resistances.len)
|
||||
if(B.data["resistances"])
|
||||
B.data["resistances"] |= src.resistances.Copy()
|
||||
else
|
||||
B.data["resistances"] = src.resistances.Copy()
|
||||
B.data["blood_type"] = copytext(src.dna.b_type,1,0)
|
||||
|
||||
var/list/temp_chem = list()
|
||||
for(var/datum/reagent/R in src.reagents.reagent_list)
|
||||
temp_chem += R.name
|
||||
temp_chem[R.name] = R.volume
|
||||
B.data["trace_chem"] = list2params(temp_chem)
|
||||
return B
|
||||
|
||||
//For humans, blood does not appear from blue, it comes from vessels.
|
||||
/mob/living/carbon/human/take_blood(obj/item/weapon/reagent_containers/container, var/amount)
|
||||
if(vessel.get_reagent_amount("blood") < amount)
|
||||
return null
|
||||
. = ..()
|
||||
vessel.remove_reagent("blood",amount) // Removes blood if human
|
||||
|
||||
//Transfers blood from container ot vessels, respecting blood types compatability.
|
||||
/mob/living/carbon/human/proc/inject_blood(obj/item/weapon/reagent_containers/container, var/amount)
|
||||
var/datum/reagent/blood/our = get_blood(vessel)
|
||||
var/datum/reagent/blood/injected = get_blood(container.reagents)
|
||||
|
||||
if(blood_incompatible(injected.data["blood_type"],our.data["blood_type"]) )
|
||||
reagents.add_reagent("toxin",amount * 0.5)
|
||||
reagents.update_total()
|
||||
else
|
||||
vessel.add_reagent("blood", amount)
|
||||
vessel.update_total()
|
||||
|
||||
container.reagents.remove_reagent("blood", amount)
|
||||
|
||||
//Gets human's own blood.
|
||||
/mob/living/carbon/proc/get_blood(datum/reagents/container)
|
||||
var/datum/reagent/blood/res = locate() in container.reagent_list //Grab some blood
|
||||
if(res) // Make sure there's some blood at all
|
||||
if(res.data["donor"] != src) //If it's not theirs, then we look for theirs
|
||||
for(var/datum/reagent/blood/D in container.reagent_list)
|
||||
if(D.data["donor"] == src)
|
||||
return D
|
||||
return res
|
||||
148
code/modules/organs/organ.dm
Normal file
148
code/modules/organs/organ.dm
Normal file
@@ -0,0 +1,148 @@
|
||||
/datum/organ
|
||||
var/name = "organ"
|
||||
var/mob/living/carbon/human/owner = null
|
||||
|
||||
var/list/datum/autopsy_data/autopsy_data = list()
|
||||
var/list/trace_chemicals = list() // traces of chemicals in the organ,
|
||||
// links chemical IDs to number of ticks for which they'll stay in the blood
|
||||
proc/process()
|
||||
return 0
|
||||
|
||||
proc/receive_chem(chemical as obj)
|
||||
return 0
|
||||
|
||||
//Handles chem traces
|
||||
/mob/living/carbon/human/proc/handle_trace_chems()
|
||||
//New are added for reagents to random organs.
|
||||
for(var/datum/reagent/A in reagents.reagent_list)
|
||||
var/datum/organ/O = pick(organs)
|
||||
O.trace_chemicals[A.name] = 100
|
||||
|
||||
//Adds autopsy data for used_weapon.
|
||||
/datum/organ/proc/add_autopsy_data(var/used_weapon, var/damage)
|
||||
var/datum/autopsy_data/W = autopsy_data[used_weapon]
|
||||
if(!W)
|
||||
W = new()
|
||||
W.weapon = used_weapon
|
||||
autopsy_data[used_weapon] = W
|
||||
|
||||
W.hits += 1
|
||||
W.damage += damage
|
||||
W.time_inflicted = world.time
|
||||
|
||||
/mob/living/carbon/human/var/list/organs = list()
|
||||
/mob/living/carbon/human/var/list/organs_by_name = list() // map organ names to organs
|
||||
|
||||
//Creates and initializes and connects external and internal organs
|
||||
/mob/living/carbon/human/proc/make_organs()
|
||||
organs = list()
|
||||
organs_by_name["chest"] = new/datum/organ/external/chest()
|
||||
organs_by_name["groin"] = new/datum/organ/external/groin(organs_by_name["chest"])
|
||||
organs_by_name["head"] = new/datum/organ/external/head(organs_by_name["chest"])
|
||||
organs_by_name["l_arm"] = new/datum/organ/external/l_arm(organs_by_name["chest"])
|
||||
organs_by_name["r_arm"] = new/datum/organ/external/r_arm(organs_by_name["chest"])
|
||||
organs_by_name["r_leg"] = new/datum/organ/external/r_leg(organs_by_name["groin"])
|
||||
organs_by_name["l_leg"] = new/datum/organ/external/l_leg(organs_by_name["groin"])
|
||||
organs_by_name["l_hand"] = new/datum/organ/external/l_hand(organs_by_name["l_arm"])
|
||||
organs_by_name["r_hand"] = new/datum/organ/external/r_hand(organs_by_name["r_arm"])
|
||||
organs_by_name["l_foot"] = new/datum/organ/external/l_foot(organs_by_name["l_leg"])
|
||||
organs_by_name["r_foot"] = new/datum/organ/external/r_foot(organs_by_name["r_leg"])
|
||||
|
||||
new/datum/organ/internal/heart(src)
|
||||
new/datum/organ/internal/lungs(src)
|
||||
new/datum/organ/internal/liver(src)
|
||||
new/datum/organ/internal/kidney(src)
|
||||
new/datum/organ/internal/brain(src)
|
||||
|
||||
for(var/name in organs_by_name)
|
||||
organs += organs_by_name[name]
|
||||
|
||||
for(var/datum/organ/external/O in organs)
|
||||
O.owner = src
|
||||
|
||||
// Takes care of organ related updates, such as broken and missing limbs
|
||||
/mob/living/carbon/human/proc/handle_organs()
|
||||
number_wounds = 0
|
||||
var/leg_tally = 2
|
||||
for(var/datum/organ/external/E in organs)
|
||||
if(!E)
|
||||
continue
|
||||
E.process()
|
||||
number_wounds += E.number_wounds
|
||||
|
||||
//Robotic limb malfunctions
|
||||
var/malfunction = 0
|
||||
if (E.status & ORGAN_ROBOT && prob(E.brute_dam + E.burn_dam))
|
||||
malfunction = 1
|
||||
|
||||
//Broken limbs hurt too
|
||||
var/broken = 0
|
||||
if(E.status & ORGAN_BROKEN && !(E.status & ORGAN_SPLINTED && prob(10)) )
|
||||
broken = 1
|
||||
|
||||
//Special effects for limbs.
|
||||
if(E.name in list("l_hand","l_arm","r_hand","r_arm"))
|
||||
var/obj/item/c_hand //Getting what's in this hand
|
||||
if(E.name == "l_hand" || E.name == "l_arm")
|
||||
c_hand = l_hand
|
||||
if(E.name == "r_hand" || E.name == "r_arm")
|
||||
c_hand = r_hand
|
||||
|
||||
if (c_hand)
|
||||
if (broken||malfunction)
|
||||
u_equip(c_hand)
|
||||
|
||||
if(broken)
|
||||
emote("me", 1, "screams in pain and drops what they were holding in their [E.display_name?"[E.display_name]":"[E]"]!")
|
||||
if(malfunction)
|
||||
emote("me", 1, "drops what they were holding, their [E.display_name?"[E.display_name]":"[E]"] malfunctioning!")
|
||||
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
|
||||
spark_system.set_up(5, 0, src)
|
||||
spark_system.attach(src)
|
||||
spark_system.start()
|
||||
spawn(10)
|
||||
del(spark_system)
|
||||
|
||||
else if(E.name in list("l_leg","l_foot","r_leg","r_foot") && !lying)
|
||||
if (E.status & ORGAN_DESTROYED || malfunction || (broken && !(E.status & ORGAN_SPLINTED)))
|
||||
leg_tally-- // let it fail even if just foot&leg
|
||||
|
||||
// standing is poor
|
||||
if(leg_tally <= 0 && !paralysis && !(lying || resting) && prob(5))
|
||||
emote("scream")
|
||||
emote("collapse")
|
||||
paralysis = 10
|
||||
|
||||
//Check arms and legs for existence
|
||||
var/canstand_l = 1 //Can stand on left leg
|
||||
var/canstand_r = 1 //Can stand on right leg
|
||||
var/hasleg_l = 1 //Have left leg
|
||||
var/hasleg_r = 1 //Have right leg
|
||||
var/hasarm_l = 1 //Have left arm
|
||||
var/hasarm_r = 1 //Have right arm
|
||||
var/datum/organ/external/E
|
||||
E = get_organ("l_leg")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
canstand_l = 0
|
||||
hasleg_l = 0
|
||||
E = get_organ("r_leg")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
canstand_r = 0
|
||||
hasleg_r = 0
|
||||
E = get_organ("l_foot")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
canstand_l = 0
|
||||
E = get_organ("r_foot")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
canstand_r = 0
|
||||
E = get_organ("l_arm")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
hasarm_l = 0
|
||||
E = get_organ("r_arm")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
hasarm_r = 0
|
||||
|
||||
// Can stand if have at least one full leg (with leg and foot parts present)
|
||||
// Has limbs to move around if at least one arm or leg is at least partially there
|
||||
can_stand = canstand_l||canstand_r
|
||||
has_limbs = hasleg_l||hasleg_r||hasarm_l||hasarm_r
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,120 +1,83 @@
|
||||
/****************************************************
|
||||
INTERNAL ORGANS
|
||||
****************************************************/
|
||||
|
||||
/*
|
||||
/datum/organ/internal
|
||||
name = "internal"
|
||||
var/damage = 0
|
||||
var/max_damage = 100
|
||||
|
||||
/datum/organ/internal/skeleton
|
||||
name = "spooky scary skeleton"
|
||||
max_damage = 200
|
||||
|
||||
/datum/organ/internal/skin
|
||||
name = "skin"
|
||||
max_damage = 100
|
||||
|
||||
/datum/organ/internal/blood_vessels
|
||||
name = "blood vessels"
|
||||
var/heart = null
|
||||
var/lungs = null
|
||||
var/kidneys = null
|
||||
|
||||
/datum/organ/internal/brain
|
||||
name = "brain"
|
||||
var/head = null
|
||||
|
||||
/datum/organ/internal/excretory
|
||||
name = "excretory"
|
||||
var/excretory = 7.0
|
||||
var/blood_vessels = null
|
||||
|
||||
/datum/organ/internal/heart
|
||||
name = "heart"
|
||||
|
||||
/datum/organ/internal/immune_system
|
||||
name = "immune system"
|
||||
var/blood_vessels = null
|
||||
var/isys = null
|
||||
|
||||
/datum/organ/internal/intestines
|
||||
name = "intestines"
|
||||
var/intestines = 3.0
|
||||
var/blood_vessels = null
|
||||
|
||||
/datum/organ/internal/liver
|
||||
name = "liver"
|
||||
var/intestines = null
|
||||
var/blood_vessels = null
|
||||
|
||||
/datum/organ/internal/lungs
|
||||
name = "lungs"
|
||||
var/lungs = 3.0
|
||||
var/throat = null
|
||||
var/blood_vessels = null
|
||||
|
||||
/datum/organ/internal/stomach
|
||||
name = "stomach"
|
||||
var/intestines = null
|
||||
|
||||
/datum/organ/internal/throat
|
||||
name = "throat"
|
||||
var/lungs = null
|
||||
var/stomach = null
|
||||
|
||||
*/
|
||||
|
||||
/mob/living/carbon/human/var/list/internal_organs = list()
|
||||
|
||||
/datum/organ/internal
|
||||
// amount of damage to the organ
|
||||
var/damage = 0
|
||||
var/min_bruised_damage = 10
|
||||
var/min_broken_damage = 30
|
||||
var/parent_organ = "chest"
|
||||
|
||||
/datum/organ/internal/proc/is_bruised()
|
||||
return damage >= min_bruised_damage
|
||||
|
||||
/datum/organ/internal/proc/is_broken()
|
||||
return damage >= min_broken_damage
|
||||
|
||||
|
||||
/datum/organ/internal/New(mob/living/carbon/human/H)
|
||||
..()
|
||||
var/datum/organ/external/E = H.organs_by_name[src.parent_organ]
|
||||
if(E.internal_organs == null)
|
||||
E.internal_organs = list()
|
||||
E.internal_organs += src
|
||||
H.internal_organs[src.name] = src
|
||||
src.owner = H
|
||||
|
||||
/datum/organ/internal/proc/take_damage(amount)
|
||||
src.damage += amount
|
||||
|
||||
var/datum/organ/external/parent = owner.get_organ(parent_organ)
|
||||
owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1)
|
||||
|
||||
/datum/organ/internal/heart
|
||||
name = "heart"
|
||||
parent_organ = "chest"
|
||||
|
||||
|
||||
/datum/organ/internal/lungs
|
||||
name = "lungs"
|
||||
parent_organ = "chest"
|
||||
|
||||
/datum/organ/internal/liver
|
||||
name = "liver"
|
||||
parent_organ = "chest"
|
||||
|
||||
|
||||
/datum/organ/internal/kidney
|
||||
name = "kidney"
|
||||
parent_organ = "chest"
|
||||
|
||||
/datum/organ/internal/brain
|
||||
name = "brain"
|
||||
/****************************************************
|
||||
INTERNAL ORGANS
|
||||
****************************************************/
|
||||
|
||||
/mob/living/carbon/human/var/list/internal_organs = list()
|
||||
|
||||
/datum/organ/internal
|
||||
// amount of damage to the organ
|
||||
var/damage = 0
|
||||
var/min_bruised_damage = 10
|
||||
var/min_broken_damage = 30
|
||||
var/parent_organ = "chest"
|
||||
|
||||
/datum/organ/internal/proc/is_bruised()
|
||||
return damage >= min_bruised_damage
|
||||
|
||||
/datum/organ/internal/proc/is_broken()
|
||||
return damage >= min_broken_damage
|
||||
|
||||
|
||||
/datum/organ/internal/New(mob/living/carbon/human/H)
|
||||
..()
|
||||
var/datum/organ/external/E = H.organs_by_name[src.parent_organ]
|
||||
if(E.internal_organs == null)
|
||||
E.internal_organs = list()
|
||||
E.internal_organs += src
|
||||
H.internal_organs[src.name] = src
|
||||
src.owner = H
|
||||
|
||||
/datum/organ/internal/proc/take_damage(amount)
|
||||
src.damage += amount
|
||||
|
||||
var/datum/organ/external/parent = owner.get_organ(parent_organ)
|
||||
owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1)
|
||||
|
||||
/****************************************************
|
||||
INTERNAL ORGANS DEFINES
|
||||
****************************************************/
|
||||
|
||||
/datum/organ/internal/heart
|
||||
name = "heart"
|
||||
parent_organ = "chest"
|
||||
|
||||
|
||||
/datum/organ/internal/lungs
|
||||
name = "lungs"
|
||||
parent_organ = "chest"
|
||||
|
||||
process()
|
||||
if(is_bruised())
|
||||
if(prob(2))
|
||||
spawn owner.emote("me", 1, "coughs up blood!")
|
||||
owner.drip(10)
|
||||
if(prob(4))
|
||||
spawn owner.emote("me", 1, "gasps for air!")
|
||||
owner.losebreath += 5
|
||||
|
||||
/datum/organ/internal/liver
|
||||
name = "liver"
|
||||
parent_organ = "chest"
|
||||
var/process_accuracy = 10
|
||||
|
||||
process()
|
||||
if(owner.life_tick % process_accuracy == 0)
|
||||
// Damaged liver means some chemicals are very dangerous
|
||||
if(src.damage >= src.min_bruised_damage)
|
||||
for(var/datum/reagent/R in owner.reagents.reagent_list)
|
||||
// Ethanol and all drinks are bad
|
||||
if(istype(R, /datum/reagent/ethanol))
|
||||
owner.adjustToxLoss(0.1 * process_accuracy)
|
||||
|
||||
// Can't cope with toxins at all
|
||||
for(var/toxin in list("toxin", "plasma", "sacid", "pacid", "cyanide", "lexorin", "amatoxin", "chloralhydrate", "carpotoxin", "zombiepowder", "mindbreaker"))
|
||||
if(owner.reagents.has_reagent(toxin))
|
||||
owner.adjustToxLoss(0.3 * process_accuracy)
|
||||
|
||||
/datum/organ/internal/kidney
|
||||
name = "kidney"
|
||||
parent_organ = "chest"
|
||||
|
||||
/datum/organ/internal/brain
|
||||
name = "brain"
|
||||
parent_organ = "head"
|
||||
@@ -502,13 +502,7 @@
|
||||
if(prot > 0 || (COLD_RESISTANCE in user.mutations))
|
||||
user << "You remove the light [fitting]"
|
||||
else
|
||||
user << "You try to remove the light [fitting], but you burn your hand on it!"
|
||||
|
||||
var/datum/organ/external/affecting = H.get_organ("[user.hand ? "l" : "r" ]_arm")
|
||||
|
||||
if(affecting.take_damage( 0, 5 )) // 5 burn damage
|
||||
H.UpdateDamageIcon()
|
||||
H.updatehealth()
|
||||
user << "You try to remove the light [fitting], but it's too hot and you don't want to burn your hand."
|
||||
return // if burned, don't remove the light
|
||||
|
||||
// create a light tube/bulb item and put it in the user's hand
|
||||
|
||||
@@ -107,30 +107,9 @@ datum
|
||||
var/current_reagent_transfer = current_reagent.volume * part
|
||||
if(preserve_data)
|
||||
trans_data = current_reagent.data
|
||||
if(current_reagent.id == "blood" && ishuman(target)) // can never be sure
|
||||
var/mob/living/carbon/human/H = target
|
||||
|
||||
var/datum/reagent/blood/HisBlood = locate() in H.vessel.reagent_list //Grab some blood
|
||||
if(HisBlood) // Make sure there's some blood at all
|
||||
if(HisBlood.data["donor"] != H) //If it's not theirs, then we look for theirs
|
||||
for(var/datum/reagent/blood/D in H.vessel.reagent_list)
|
||||
if(D.data["donor"] == H)
|
||||
HisBlood = D
|
||||
break
|
||||
if(HisBlood && HisBlood.data && trans_data)
|
||||
if(blood_incompatible(trans_data["blood_type"],HisBlood.data["blood_type"]))
|
||||
H.reagents.add_reagent("toxin",(current_reagent_transfer * multiplier * 0.5))
|
||||
H.reagents.update_total()
|
||||
else
|
||||
H.vessel.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data)
|
||||
H.vessel.update_total()
|
||||
else
|
||||
H.vessel.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data)
|
||||
H.vessel.update_total()
|
||||
src.remove_reagent(current_reagent.id, current_reagent_transfer)
|
||||
else
|
||||
R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data)
|
||||
src.remove_reagent(current_reagent.id, current_reagent_transfer)
|
||||
R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data)
|
||||
src.remove_reagent(current_reagent.id, current_reagent_transfer)
|
||||
|
||||
src.update_total()
|
||||
R.update_total()
|
||||
@@ -246,6 +225,15 @@ datum
|
||||
continue
|
||||
|
||||
var/datum/chemical_reaction/C = reaction
|
||||
|
||||
//check if this recipe needs to be heated to mix
|
||||
if(C.requires_heating)
|
||||
if(istype(my_atom.loc, /obj/machinery/bunsen_burner))
|
||||
if(!my_atom.loc:heated)
|
||||
continue
|
||||
else
|
||||
continue
|
||||
|
||||
var/total_required_reagents = C.required_reagents.len
|
||||
var/total_matching_reagents = 0
|
||||
var/total_required_catalysts = C.required_catalysts.len
|
||||
@@ -289,7 +277,10 @@ datum
|
||||
|
||||
if(total_matching_reagents == total_required_reagents && total_matching_catalysts == total_required_catalysts && matching_container && matching_other)
|
||||
var/multiplier = min(multipliers)
|
||||
var/preserved_data = null
|
||||
for(var/B in C.required_reagents)
|
||||
if(!preserved_data)
|
||||
preserved_data = get_data(B)
|
||||
remove_reagent(B, (multiplier * C.required_reagents[B]), safety = 1)
|
||||
|
||||
var/created_volume = C.result_amount*multiplier
|
||||
@@ -297,6 +288,11 @@ datum
|
||||
feedback_add_details("chemical_reaction","[C.result]|[C.result_amount*multiplier]")
|
||||
multiplier = max(multiplier, 1) //this shouldnt happen ...
|
||||
add_reagent(C.result, C.result_amount*multiplier)
|
||||
set_data(C.result, preserved_data)
|
||||
|
||||
//add secondary products
|
||||
for(var/S in C.secondary_results)
|
||||
add_reagent(S, C.result_amount * C.secondary_results[S] * multiplier)
|
||||
|
||||
var/list/seen = viewers(4, get_turf(my_atom))
|
||||
for(var/mob/M in seen)
|
||||
@@ -506,6 +502,19 @@ datum
|
||||
|
||||
return res
|
||||
|
||||
//two helper functions to preserve data across reactions (needed for xenoarch)
|
||||
get_data(var/reagent_id)
|
||||
for(var/datum/reagent/D in reagent_list)
|
||||
if(D.id == reagent_id)
|
||||
//world << "proffering a data-carrying reagent ([reagent_id])"
|
||||
return D.data
|
||||
|
||||
set_data(var/reagent_id, var/new_data)
|
||||
for(var/datum/reagent/D in reagent_list)
|
||||
if(D.id == reagent_id)
|
||||
//world << "reagent data set ([reagent_id])"
|
||||
D.data = new_data
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
var/recharged = 0
|
||||
var/list/dispensable_reagents = list("hydrogen","lithium","carbon","nitrogen","oxygen","fluorine",
|
||||
"sodium","aluminum","silicon","phosphorus","sulfur","chlorine","potassium","iron",
|
||||
"copper","mercury","radium","water","ethanol","sugar","sacid")
|
||||
"copper","mercury","radium","water","ethanol","sugar","sacid","tungsten")
|
||||
|
||||
/obj/machinery/chem_dispenser/proc/recharge()
|
||||
if(stat & (BROKEN|NOPOWER)) return
|
||||
@@ -779,6 +779,9 @@
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/wheat = list("flour" = -5),
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0),
|
||||
|
||||
//archaeology!
|
||||
/obj/item/weapon/rocksliver = list("ground_rock" = 50),
|
||||
|
||||
|
||||
|
||||
//All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.!
|
||||
@@ -1106,6 +1109,20 @@
|
||||
break
|
||||
remove_object(O)
|
||||
|
||||
//xenoarch
|
||||
for(var/obj/item/weapon/rocksliver/O in holdingitems)
|
||||
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
|
||||
break
|
||||
var/allowed = get_allowed_by_id(O)
|
||||
for (var/r_id in allowed)
|
||||
var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
|
||||
var/amount = allowed[r_id]
|
||||
beaker.reagents.add_reagent(r_id,min(amount, space), O.geological_data)
|
||||
|
||||
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
|
||||
break
|
||||
remove_object(O)
|
||||
|
||||
//Everything else - Transfers reagents from it into beaker
|
||||
for (var/obj/item/weapon/reagent_containers/O in holdingitems)
|
||||
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
|
||||
|
||||
@@ -13,6 +13,8 @@ datum
|
||||
|
||||
var/result_amount = 0
|
||||
var/secondary = 0 // set to nonzero if secondary reaction
|
||||
var/list/secondary_results = list() //additional reagents produced by the reaction
|
||||
var/requires_heating = 0
|
||||
|
||||
proc
|
||||
on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
|
||||
@@ -94,6 +94,12 @@
|
||||
else if(istype(target, /obj/item/clothing/suit/space/space_ninja))
|
||||
return
|
||||
|
||||
else if(istype(target, /obj/machinery/bunsen_burner))
|
||||
return
|
||||
|
||||
else if(istype(target, /obj/machinery/anomaly))
|
||||
return
|
||||
|
||||
else if(reagents.total_volume)
|
||||
user << "\blue You splash the solution onto [target]."
|
||||
src.reagents.reaction(target, TOUCH)
|
||||
|
||||
@@ -80,57 +80,20 @@
|
||||
if(istype(target, /mob/living/carbon))//maybe just add a blood reagent to all mobs. Then you can suck them dry...With hundreds of syringes. Jolly good idea.
|
||||
var/amount = src.reagents.maximum_volume - src.reagents.total_volume
|
||||
var/mob/living/carbon/T = target
|
||||
var/datum/reagent/B = new /datum/reagent/blood
|
||||
if(!T.dna)
|
||||
usr << "You are unable to locate any blood. (To be specific, your target seems to be missing their DNA datum)"
|
||||
return
|
||||
if(NOCLONE in T.mutations) //target done been et, no more blood in him
|
||||
user << "\red You are unable to locate any blood."
|
||||
return
|
||||
if(ishuman(T))
|
||||
if(T:vessel.get_reagent_amount("blood") < amount)
|
||||
return
|
||||
B.holder = src
|
||||
B.volume = amount
|
||||
//set reagent data
|
||||
B.data["donor"] = T
|
||||
/*
|
||||
if(T.virus && T.virus.spread_type != SPECIAL)
|
||||
B.data["virus"] = new T.virus.type(0)
|
||||
*/
|
||||
|
||||
var/datum/reagent/B = T.take_blood(src,amount)
|
||||
|
||||
|
||||
for(var/datum/disease/D in T.viruses)
|
||||
if(!B.data["viruses"])
|
||||
B.data["viruses"] = list()
|
||||
|
||||
|
||||
B.data["viruses"] += new D.type(0, D, 1)
|
||||
|
||||
if(T.virus2)
|
||||
B.data["virus2"] = T.virus2.getcopy()
|
||||
|
||||
B.data["blood_DNA"] = copytext(T.dna.unique_enzymes,1,0)
|
||||
if(T.resistances&&T.resistances.len)
|
||||
B.data["resistances"] = T.resistances.Copy()
|
||||
if(istype(target, /mob/living/carbon/human))//I wish there was some hasproperty operation...
|
||||
var/mob/living/carbon/human/HT = target
|
||||
B.data["blood_type"] = copytext(HT.dna.b_type,1,0)
|
||||
var/list/temp_chem = list()
|
||||
for(var/datum/reagent/R in target.reagents.reagent_list)
|
||||
temp_chem += R.name
|
||||
temp_chem[R.name] = R.volume
|
||||
B.data["trace_chem"] = list2params(temp_chem)
|
||||
B.data["antibodies"] = T.antibodies
|
||||
|
||||
if(ishuman(T))
|
||||
T:vessel.remove_reagent("blood",amount) // Removes blood if human
|
||||
|
||||
src.reagents.reagent_list += B
|
||||
src.reagents.update_total()
|
||||
src.on_reagent_change()
|
||||
src.reagents.handle_reactions()
|
||||
if (B)
|
||||
src.reagents.reagent_list += B
|
||||
src.reagents.update_total()
|
||||
src.on_reagent_change()
|
||||
src.reagents.handle_reactions()
|
||||
user << "\blue You take a blood sample from [target]"
|
||||
for(var/mob/O in viewers(4, user))
|
||||
O.show_message("\red [user] takes a blood sample from [target].", 1)
|
||||
@@ -182,9 +145,7 @@
|
||||
var/trans
|
||||
if(B && ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
trans = B.volume > 5? 5 : B.volume
|
||||
H.vessel.add_reagent("blood",trans,B.data)
|
||||
src.reagents.remove_reagent("blood",trans)
|
||||
H.inject_blood(src,5)
|
||||
else
|
||||
trans = src.reagents.trans_to(target, amount_per_transfer_from_this)
|
||||
user << "\blue You inject [trans] units of the solution. The syringe now contains [src.reagents.total_volume] units."
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
|
||||
//chemistry stuff here so that it can be easily viewed/modified
|
||||
/*
|
||||
datum
|
||||
reagent
|
||||
tungsten //used purely to make lith-sodi-tungs
|
||||
name = "Tungsten"
|
||||
id = "tungsten"
|
||||
description = "A chemical element, and a strong oxidising agent."
|
||||
reagent_state = SOLID
|
||||
color = "#808080" // rgb: 128, 128, 128, meant to be a silvery grey but idrc
|
||||
|
||||
lithiumsodiumtungstate
|
||||
name = "Lithium Sodium Tungstate"
|
||||
id = "lithiumsodiumtungstate"
|
||||
description = "A reducing agent for geological compounds."
|
||||
reagent_state = LIQUID
|
||||
color = "#808080" // rgb: 128, 128, 128, again, silvery grey
|
||||
|
||||
ground_rock
|
||||
name = "Ground Rock"
|
||||
id = "ground_rock"
|
||||
description = "A fine dust made of ground up geological samples."
|
||||
reagent_state = SOLID
|
||||
color = "#C81040" //rgb: 200, 16, 64
|
||||
//todo: make this brown
|
||||
|
||||
density_separated_sample
|
||||
name = "Density separated sample"
|
||||
id = "density_separated_sample"
|
||||
description = "A watery paste which has had density separation applied to its contents."
|
||||
reagent_state = LIQUID
|
||||
color = "#C81040" //rgb: 200, 16, 64
|
||||
//todo: make this white
|
||||
|
||||
analysis_sample
|
||||
name = "Analysis sample"
|
||||
id = "analysis_sample"
|
||||
description = "A watery paste used in chemical analysis."
|
||||
reagent_state = LIQUID
|
||||
color = "#C81040" //rgb: 200, 16, 64
|
||||
//todo: make this white
|
||||
|
||||
chemical_waste
|
||||
name = "Chemical Waste"
|
||||
id = "chemical_waste"
|
||||
description = "A viscous, toxic liquid left over from many chemical processes."
|
||||
reagent_state = LIQUID
|
||||
color = "#C81040" //rgb: 200, 16, 64
|
||||
//todo: make this fluoro/bright green
|
||||
|
||||
datum
|
||||
chemical_reaction
|
||||
lithiumsodiumtungstate //LiNa2WO4, not the easiest chem to mix
|
||||
name = "Lithium Sodium Tungstate"
|
||||
id = "lithiumsodiumtungstate"
|
||||
result = "lithiumsodiumtungstate"
|
||||
required_reagents = list("lithium" = 1, "sodium" = 2, "tungsten" = 1, "oxygen" = 4)
|
||||
result_amount = 8
|
||||
|
||||
density_separated_liquid
|
||||
name = "Density separated sample"
|
||||
id = "density_separated_sample"
|
||||
result = "density_separated_sample"
|
||||
secondary_results = list("chemical_waste" = 1)
|
||||
required_reagents = list("ground_rock" = 1, "lithiumsodiumtungstate" = 2)
|
||||
result_amount = 2
|
||||
|
||||
analysis_liquid
|
||||
name = "Analysis sample"
|
||||
id = "analysis_sample"
|
||||
result = "analysis_sample"
|
||||
secondary_results = list("chemical_waste" = 1)
|
||||
required_reagents = list("density_separated_sample" = 5)
|
||||
result_amount = 4
|
||||
requires_heating = 1
|
||||
*/
|
||||
@@ -1 +0,0 @@
|
||||
//todo: tape, methods for excavation?
|
||||
@@ -1,119 +0,0 @@
|
||||
obj/machinery/gas_chromatography
|
||||
name = "Gas Chromatography Spectrometer"
|
||||
desc = "A specialised mass spectrometer."
|
||||
icon = 'virology.dmi'
|
||||
icon_state = "analyser"
|
||||
|
||||
obj/machinery/gas_chromatography/Topic(href, href_list)
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=artanalyser")
|
||||
usr.machine = null
|
||||
|
||||
updateDialog()
|
||||
|
||||
obj/machinery/gas_chromatography/attack_hand(var/mob/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
user.machine = src
|
||||
var/dat = "<B>Gas Chromatography Spectrometer</B><BR>"
|
||||
dat += "<hr>"
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>Refresh<BR>"
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close<BR>"
|
||||
user << browse(dat, "window=artanalyser;size=450x500")
|
||||
onclose(user, "artanalyser")
|
||||
|
||||
obj/machinery/accelerator
|
||||
name = "Accelerator Spectrometer"
|
||||
desc = "A specialised mass spectrometer."
|
||||
icon = 'virology.dmi'
|
||||
icon_state = "analyser"
|
||||
|
||||
obj/machinery/accelerator/Topic(href, href_list)
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=artanalyser")
|
||||
usr.machine = null
|
||||
|
||||
updateDialog()
|
||||
|
||||
obj/machinery/accelerator/attack_hand(var/mob/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
user.machine = src
|
||||
var/dat = "<B>Accelerator Spectrometer</B><BR>"
|
||||
dat += "<hr>"
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>Refresh<BR>"
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close<BR>"
|
||||
user << browse(dat, "window=artanalyser;size=450x500")
|
||||
onclose(user, "artanalyser")
|
||||
|
||||
obj/machinery/fourier_transform
|
||||
name = "Fourier Transform Spectroscope"
|
||||
desc = "A specialised geochemical analysis device."
|
||||
icon = 'virology.dmi'
|
||||
icon_state = "analyser"
|
||||
|
||||
obj/machinery/fourier_transform/Topic(href, href_list)
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=artanalyser")
|
||||
usr.machine = null
|
||||
|
||||
updateDialog()
|
||||
|
||||
obj/machinery/fourier_transform/attack_hand(var/mob/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
user.machine = src
|
||||
var/dat = "<B>Fourier Transform Spectroscope</B><BR>"
|
||||
dat += "<hr>"
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>Refresh<BR>"
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close<BR>"
|
||||
user << browse(dat, "window=artanalyser;size=450x500")
|
||||
onclose(user, "artanalyser")
|
||||
|
||||
obj/machinery/radiometric
|
||||
name = "Radiometric Exposure Spectrometer"
|
||||
desc = "A specialised mass spectrometer, able to radiometrically date inserted materials."
|
||||
icon = 'virology.dmi'
|
||||
icon_state = "analyser"
|
||||
|
||||
obj/machinery/radiometric/Topic(href, href_list)
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=artanalyser")
|
||||
usr.machine = null
|
||||
|
||||
updateDialog()
|
||||
|
||||
obj/machinery/radiometric/attack_hand(var/mob/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
user.machine = src
|
||||
var/dat = "<B>Radiometric Exposure Spectrometer</B><BR>"
|
||||
dat += "<hr>"
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>Refresh<BR>"
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close<BR>"
|
||||
user << browse(dat, "window=artanalyser;size=450x500")
|
||||
onclose(user, "artanalyser")
|
||||
|
||||
obj/machinery/ion_mobility
|
||||
name = "Ion Mobility Spectrometer"
|
||||
desc = "A specialised mass spectrometer."
|
||||
icon = 'virology.dmi'
|
||||
icon_state = "analyser"
|
||||
|
||||
obj/machinery/ion_mobility/Topic(href, href_list)
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=artanalyser")
|
||||
usr.machine = null
|
||||
|
||||
updateDialog()
|
||||
|
||||
obj/machinery/ion_mobility/attack_hand(var/mob/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
user.machine = src
|
||||
var/dat = "<B>Ion Mobility Spectrometer</B><BR>"
|
||||
dat += "<hr>"
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>Refresh<BR>"
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close<BR>"
|
||||
user << browse(dat, "window=artanalyser;size=450x500")
|
||||
onclose(user, "artanalyser")
|
||||
@@ -1,40 +0,0 @@
|
||||
/obj/item/device/depth_scanner
|
||||
name = "depth analysis scanner"
|
||||
desc = "Used to check mass spatial depth and density."
|
||||
icon = 'pda.dmi'
|
||||
icon_state = "crap"
|
||||
item_state = "analyzer"
|
||||
w_class = 1.0
|
||||
flags = FPRINT | TABLEPASS
|
||||
slot_flags = SLOT_BELT
|
||||
|
||||
/obj/item/weapon/pickaxe/hand_pick
|
||||
name = "hand pick"
|
||||
//icon_state = "excavation"
|
||||
//item_state = "minipick"
|
||||
digspeed = 50
|
||||
desc = "A smaller, more precise version of the pickaxe."
|
||||
|
||||
/obj/item/weapon/pickaxe/mini_pick
|
||||
name = "mini pick"
|
||||
//icon_state = "excavation"
|
||||
//item_state = "minipick"
|
||||
digspeed = 60
|
||||
desc = "A miniature excavation tool for precise digging around delicate finds."
|
||||
|
||||
/obj/item/device/core_sampler
|
||||
name = "core sampler"
|
||||
desc = "Used to extract cores from geological samples."
|
||||
icon = 'device.dmi'
|
||||
icon_state = "core_sampler"
|
||||
item_state = "screwdriver_brown"
|
||||
w_class = 1.0
|
||||
flags = FPRINT | TABLEPASS
|
||||
slot_flags = SLOT_BELT
|
||||
|
||||
/obj/item/device/beacon_locator
|
||||
name = "locater device"
|
||||
desc = "Used to scan and locate signals on a particular frequency."
|
||||
icon = 'device.dmi'
|
||||
icon_state = "pinoff" //pinonfar, pinonmedium, pinonclose, pinondirect, pinonnull
|
||||
item_state = "electronic"
|
||||
76
code/modules/research/xenoarchaeology/areas.dm
Normal file
76
code/modules/research/xenoarchaeology/areas.dm
Normal file
@@ -0,0 +1,76 @@
|
||||
|
||||
/area/research_outpost
|
||||
name = "Research Outpost"
|
||||
icon_state = "anomaly"
|
||||
|
||||
/area/research_outpost/hallway
|
||||
name = "Research Outpost Hallway"
|
||||
icon_state = "hallC"
|
||||
|
||||
/area/research_outpost/gearstore
|
||||
name = "Expedition Preparation"
|
||||
icon_state = "anog"
|
||||
|
||||
/area/research_outpost/power
|
||||
name = "Research Outpost Power"
|
||||
icon_state = "engine"
|
||||
|
||||
/area/research_outpost/atmos
|
||||
name = "Research Outpost Atmospherics"
|
||||
icon_state = "atmos"
|
||||
|
||||
/area/research_outpost/maint
|
||||
name = "Research Outpost Maintenance"
|
||||
icon_state = "maintcentral"
|
||||
|
||||
/area/research_outpost/iso1
|
||||
name = "Isolation Cell"
|
||||
icon_state = "iso1"
|
||||
|
||||
/area/research_outpost/iso2
|
||||
name = "Isolation Cell"
|
||||
icon_state = "iso2"
|
||||
|
||||
/area/research_outpost/iso3
|
||||
name = "Isolation Cell"
|
||||
icon_state = "iso3"
|
||||
|
||||
/area/research_outpost/harvesting
|
||||
name = "Exotic Particles Collection"
|
||||
icon_state = "anolab"
|
||||
|
||||
/area/research_outpost/sample
|
||||
name = "Sample Preparation Room"
|
||||
icon_state = "anosample"
|
||||
|
||||
/area/research_outpost/spectro
|
||||
name = "Mass Spectrometry Lab"
|
||||
icon_state = "anospectro"
|
||||
|
||||
/area/research_outpost/anomaly
|
||||
name = "Anomalous Materials Lab"
|
||||
icon_state = "anolab"
|
||||
|
||||
/area/research_outpost/med
|
||||
name = "Research Outpost Medbay"
|
||||
icon_state = "medbay3"
|
||||
|
||||
/area/research_outpost/entry
|
||||
name = "Research Outpost Shuttle Dock"
|
||||
icon_state = "entry"
|
||||
|
||||
/area/research_outpost/longtermstorage
|
||||
name = "Long-Term Storage"
|
||||
icon_state = "primarystorage"
|
||||
|
||||
/area/research_outpost/tempstorage
|
||||
name = "Temporary Storage"
|
||||
icon_state = "storage"
|
||||
|
||||
/area/research_outpost/maintstore1
|
||||
name = "Auxiliary Storage"
|
||||
icon_state = "auxstorage"
|
||||
|
||||
/area/research_outpost/maintstore2
|
||||
name = "Maintenance Storage"
|
||||
icon_state = "auxstorage"
|
||||
101
code/modules/research/xenoarchaeology/artifact/artifact.dm
Normal file
101
code/modules/research/xenoarchaeology/artifact/artifact.dm
Normal file
@@ -0,0 +1,101 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Large finds - (Potentially) active alien machinery from the dawn of time
|
||||
|
||||
/datum/artifact_find
|
||||
var/artifact_id
|
||||
var/artifact_find_type
|
||||
var/artifact_detect_range
|
||||
|
||||
/datum/artifact_find/New()
|
||||
artifact_detect_range = rand(5,300)
|
||||
|
||||
artifact_id = "[pick("kappa","sigma","antaeres","beta","omicron","iota","epsilon","omega","gamma","delta","tau","alpha")]-[rand(100,999)]"
|
||||
|
||||
artifact_find_type = pick(\
|
||||
5;/obj/machinery/power/supermatter,\
|
||||
5;/obj/structure/constructshell,\
|
||||
5;/obj/machinery/syndicate_beacon,\
|
||||
25;/obj/machinery/power/supermatter/shard,\
|
||||
50;/obj/structure/cult/pylon,\
|
||||
100;/obj/machinery/auto_cloner,\
|
||||
100;/obj/machinery/giga_drill,\
|
||||
100;/obj/mecha/working/hoverpod,\
|
||||
100;/obj/machinery/replicator,\
|
||||
150;/obj/structure/crystal,\
|
||||
1000;/obj/machinery/artifact)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Boulders - sometimes turn up after excavating turf - excavate further to try and find large xenoarch finds
|
||||
|
||||
/obj/structure/boulder
|
||||
name = "rocky debris"
|
||||
desc = "Leftover rock from an excavation, it's been partially dug out already but there's still a lot to go."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "boulder1"
|
||||
density = 1
|
||||
opacity = 1
|
||||
var/excavation_level = 0
|
||||
var/datum/geosample/geological_data
|
||||
var/datum/artifact_find/artifact_find
|
||||
|
||||
/obj/structure/boulder/New()
|
||||
icon_state = "boulder[rand(1,4)]"
|
||||
excavation_level = rand(5,50)
|
||||
|
||||
/obj/structure/boulder/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if (istype(W, /obj/item/device/core_sampler))
|
||||
src.geological_data.artifact_distance = rand(-100,100) / 100
|
||||
src.geological_data.artifact_id = artifact_find.artifact_id
|
||||
|
||||
var/obj/item/device/core_sampler/C = W
|
||||
C.sample_item(src, user)
|
||||
return
|
||||
|
||||
if (istype(W, /obj/item/device/depth_scanner))
|
||||
var/obj/item/device/depth_scanner/C = W
|
||||
C.scan_atom(user, src)
|
||||
return
|
||||
|
||||
if (istype(W, /obj/item/device/measuring_tape))
|
||||
var/obj/item/device/measuring_tape/P = W
|
||||
user.visible_message("\blue[user] extends [P] towards [src].","\blue You extend [P] towards [src].")
|
||||
if(do_after(user,40))
|
||||
user << "\blue \icon[P] [src] has been excavated to a depth of [2*src.excavation_level]cm."
|
||||
return
|
||||
|
||||
if (istype(W, /obj/item/weapon/pickaxe))
|
||||
var/obj/item/weapon/pickaxe/P = W
|
||||
|
||||
user << "\red You start [P.drill_verb] [src]."
|
||||
|
||||
if(!do_after(user,P.digspeed))
|
||||
return
|
||||
|
||||
user << "\blue You finish [P.drill_verb] [src]."
|
||||
excavation_level += P.excavation_amount
|
||||
|
||||
var/reveal_prob = 1
|
||||
if(excavation_level >= 95)
|
||||
reveal_prob = 50 + (excavation_level - 90) * (excavation_level - 90)
|
||||
else if(excavation_level >= 90)
|
||||
reveal_prob = 5
|
||||
if(excavation_level >= 100)
|
||||
//failure
|
||||
user.visible_message("<font color='red'><b>[src] suddenly crumbles away.</b></font>",\
|
||||
"\red [src] has disintegrated under your onslaught, any secrets it was holding long gone.")
|
||||
del(src)
|
||||
else if(prob(reveal_prob))
|
||||
//success
|
||||
if(artifact_find)
|
||||
var/spawn_type = artifact_find.artifact_find_type
|
||||
var/obj/O = new spawn_type(get_turf(src))
|
||||
if(istype(O,/obj/machinery/artifact))
|
||||
var/obj/machinery/artifact/X = O
|
||||
if(X.my_effect)
|
||||
X.my_effect.artifact_id = artifact_find.artifact_id
|
||||
src.visible_message("<font color='red'><b>[src] suddenly crumbles away.</b></font>")
|
||||
else
|
||||
user.visible_message("<font color='red'><b>[src] suddenly crumbles away.</b></font>",\
|
||||
"\blue [src] has been whittled away under your careful excavation, but there was nothing of interest inside.")
|
||||
del(src)
|
||||
@@ -0,0 +1,87 @@
|
||||
|
||||
/obj/machinery/auto_cloner
|
||||
name = "mysterious pod"
|
||||
desc = "It's full of a viscous liquid, but appears dark and silent."
|
||||
icon = 'icons/obj/cryogenics.dmi'
|
||||
icon_state = "cellold0"
|
||||
var/spawn_type
|
||||
var/current_ticks_spawning = 0
|
||||
var/ticks_required_to_spawn
|
||||
density = 1
|
||||
var/previous_power_state = 0
|
||||
|
||||
use_power = 1
|
||||
active_power_usage = 2000
|
||||
idle_power_usage = 1000
|
||||
|
||||
/obj/machinery/auto_cloner/New()
|
||||
..()
|
||||
|
||||
ticks_required_to_spawn = rand(240,1440)
|
||||
|
||||
//33% chance to spawn nasties
|
||||
if(prob(33))
|
||||
spawn_type = pick(\
|
||||
/mob/living/simple_animal/hostile/giant_spider/nurse,\
|
||||
/mob/living/simple_animal/hostile/alien,\
|
||||
/mob/living/simple_animal/hostile/bear,\
|
||||
/mob/living/simple_animal/hostile/creature,\
|
||||
/mob/living/simple_animal/hostile/panther,\
|
||||
/mob/living/simple_animal/hostile/snake\
|
||||
)
|
||||
else
|
||||
spawn_type = pick(\
|
||||
/mob/living/simple_animal/cat,\
|
||||
/mob/living/simple_animal/corgi,\
|
||||
/mob/living/simple_animal/corgi/puppy,\
|
||||
/mob/living/simple_animal/chicken,\
|
||||
/mob/living/simple_animal/cow,\
|
||||
/mob/living/simple_animal/parrot,\
|
||||
/mob/living/simple_animal/slime,\
|
||||
/mob/living/simple_animal/crab,\
|
||||
/mob/living/simple_animal/mouse,\
|
||||
/mob/living/simple_animal/hostile/retaliate/goat,\
|
||||
/mob/living/carbon/monkey\
|
||||
)
|
||||
|
||||
//todo: how the hell is the asteroid permanently powered?
|
||||
/obj/machinery/auto_cloner/process()
|
||||
if(powered(power_channel))
|
||||
if(!previous_power_state)
|
||||
previous_power_state = 1
|
||||
icon_state = "cellold1"
|
||||
src.visible_message("\blue \icon[src] [src] suddenly comes to life!")
|
||||
|
||||
//slowly grow a mob
|
||||
current_ticks_spawning++
|
||||
if(prob(5))
|
||||
src.visible_message("\blue \icon[src] [src] [pick("gloops","glugs","whirrs","whooshes","hisses","purrs","hums","gushes")].")
|
||||
|
||||
//if we've finished growing...
|
||||
if(current_ticks_spawning >= ticks_required_to_spawn)
|
||||
current_ticks_spawning = 0
|
||||
use_power = 1
|
||||
src.visible_message("\blue \icon[src] [src] pings!")
|
||||
icon_state = "cellold1"
|
||||
desc = "It's full of a bubbling viscous liquid, and is lit by a mysterious glow."
|
||||
if(spawn_type)
|
||||
new spawn_type(src.loc)
|
||||
|
||||
//if we're getting close to finished, kick into overdrive power usage
|
||||
if(current_ticks_spawning / ticks_required_to_spawn > 0.75)
|
||||
use_power = 2
|
||||
icon_state = "cellold2"
|
||||
desc = "It's full of a bubbling viscous liquid, and is lit by a mysterious glow. A dark shape appears to be forming inside..."
|
||||
else
|
||||
use_power = 1
|
||||
icon_state = "cellold1"
|
||||
desc = "It's full of a bubbling viscous liquid, and is lit by a mysterious glow."
|
||||
else
|
||||
if(previous_power_state)
|
||||
previous_power_state = 0
|
||||
icon_state = "cellold0"
|
||||
src.visible_message("\blue \icon[src] [src] suddenly shuts down.")
|
||||
|
||||
//cloned mob slowly breaks down
|
||||
if(current_ticks_spawning > 0)
|
||||
current_ticks_spawning--
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
/obj/structure/crystal
|
||||
name = "large crystal"
|
||||
icon = 'xenoarchaeology.dmi'
|
||||
icon_state = "crystal"
|
||||
density = 1
|
||||
|
||||
/obj/structure/crystal/New()
|
||||
..()
|
||||
|
||||
icon_state = pick("ano70","ano80")
|
||||
|
||||
desc = pick(\
|
||||
"It shines faintly as it catches the light.",\
|
||||
"It appears to have a faint inner glow.",\
|
||||
"It seems to draw you inward as you look it at.",\
|
||||
"Something twinkles faintly as you look at it.",\
|
||||
"It's mesmerizing to behold.")
|
||||
|
||||
/obj/structure/crystal/Del()
|
||||
src.visible_message("\red<b>[src] shatters!</b>")
|
||||
if(prob(75))
|
||||
new /obj/item/weapon/shard/plasma(src.loc)
|
||||
if(prob(50))
|
||||
new /obj/item/weapon/shard/plasma(src.loc)
|
||||
if(prob(25))
|
||||
new /obj/item/weapon/shard/plasma(src.loc)
|
||||
if(prob(75))
|
||||
new /obj/item/weapon/shard(src.loc)
|
||||
if(prob(50))
|
||||
new /obj/item/weapon/shard(src.loc)
|
||||
if(prob(25))
|
||||
new /obj/item/weapon/shard(src.loc)
|
||||
..()
|
||||
|
||||
//todo: laser_act
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
/obj/machinery/giga_drill
|
||||
name = "alien drill"
|
||||
desc = "A giant, alien drill mounted on long treads."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "gigadrill"
|
||||
var/active = 0
|
||||
var/drill_time = 10
|
||||
var/turf/drilling_turf
|
||||
density = 1
|
||||
layer = 3.1 //to go over ores
|
||||
|
||||
/obj/machinery/giga_drill/attack_hand(mob/user as mob)
|
||||
if(active)
|
||||
active = 0
|
||||
icon_state = "gigadrill"
|
||||
user << "\blue You press a button and [src] slowly spins down."
|
||||
else
|
||||
active = 1
|
||||
icon_state = "gigadrill_mov"
|
||||
user << "\blue You press a button and [src] shudders to life."
|
||||
|
||||
/obj/machinery/giga_drill/Bump(atom/A)
|
||||
if(active && !drilling_turf)
|
||||
if(istype(A,/turf/simulated/mineral))
|
||||
var/turf/simulated/mineral/M = A
|
||||
drilling_turf = get_turf(src)
|
||||
src.visible_message("\red <b>[src] begins to drill into [M]!</b>")
|
||||
anchored = 1
|
||||
spawn(drill_time)
|
||||
if(get_turf(src) == drilling_turf && active)
|
||||
M.gets_drilled()
|
||||
src.loc = M
|
||||
drilling_turf = null
|
||||
anchored = 0
|
||||
@@ -0,0 +1,67 @@
|
||||
|
||||
/obj/mecha/working/hoverpod
|
||||
name = "hover pod"
|
||||
icon_state = "engineering_pod"
|
||||
desc = "Stubby and round, it has a human sized access hatch on the top."
|
||||
wreckage = /obj/effect/decal/mecha_wreckage/hoverpod
|
||||
|
||||
//duplicate of parent proc, but without space drifting
|
||||
/obj/mecha/working/hoverpod/dyndomove(direction)
|
||||
if(!can_move)
|
||||
return 0
|
||||
if(src.pr_inertial_movement.active())
|
||||
return 0
|
||||
if(!has_charge(step_energy_drain))
|
||||
return 0
|
||||
var/move_result = 0
|
||||
if(hasInternalDamage(MECHA_INT_CONTROL_LOST))
|
||||
move_result = mechsteprand()
|
||||
else if(src.dir!=direction)
|
||||
move_result = mechturn(direction)
|
||||
else
|
||||
move_result = mechstep(direction)
|
||||
if(move_result)
|
||||
can_move = 0
|
||||
use_power(step_energy_drain)
|
||||
/*if(istype(src.loc, /turf/space))
|
||||
if(!src.check_for_support())
|
||||
src.pr_inertial_movement.start(list(src,direction))
|
||||
src.log_message("Movement control lost. Inertial movement started.")*/
|
||||
if(do_after(step_in))
|
||||
can_move = 1
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//these three procs overriden to play different sounds
|
||||
/obj/mecha/mechturn(direction)
|
||||
dir = direction
|
||||
//playsound(src,'sound/machines/hiss.ogg',40,1)
|
||||
return 1
|
||||
|
||||
/obj/mecha/mechstep(direction)
|
||||
var/result = step(src,direction)
|
||||
if(result)
|
||||
playsound(src,'sound/machines/hiss.ogg',40,1)
|
||||
return result
|
||||
|
||||
|
||||
/obj/mecha/mechsteprand()
|
||||
var/result = step_rand(src)
|
||||
if(result)
|
||||
playsound(src,'sound/machines/hiss.ogg',40,1)
|
||||
return result
|
||||
|
||||
/obj/effect/decal/mecha_wreckage/hoverpod
|
||||
name = "Hover pod wreckage"
|
||||
icon_state = "engineering_pod-broken"
|
||||
|
||||
/*New()
|
||||
..()
|
||||
var/list/parts = list(
|
||||
|
||||
for(var/i=0;i<2;i++)
|
||||
if(!isemptylist(parts) && prob(40))
|
||||
var/part = pick(parts)
|
||||
welder_salvage += part
|
||||
parts -= part
|
||||
return*/
|
||||
@@ -0,0 +1,119 @@
|
||||
|
||||
/obj/machinery/replicator
|
||||
name = "alien machine"
|
||||
desc = "It's some kind of pod with strange wires and gadgets all over it."
|
||||
icon = 'xenoarchaeology.dmi'
|
||||
icon_state = "borgcharger0(old)"
|
||||
density = 1
|
||||
|
||||
idle_power_usage = 100
|
||||
active_power_usage = 1000
|
||||
use_power = 1
|
||||
|
||||
var/spawn_progress = 0
|
||||
var/max_spawn_ticks = 5
|
||||
var/list/construction = list()
|
||||
var/list/spawning_types = list()
|
||||
|
||||
/obj/machinery/replicator/New()
|
||||
..()
|
||||
|
||||
var/list/viables = list(\
|
||||
/obj/item/roller,\
|
||||
/obj/structure/closet/crate,\
|
||||
/obj/structure/closet/acloset,\
|
||||
/mob/living/simple_animal/hostile/mimic,\
|
||||
/mob/living/simple_animal/hostile/viscerator,\
|
||||
/mob/living/simple_animal/hostile/hivebot,\
|
||||
/obj/item/device/analyzer,\
|
||||
/obj/item/device/camera,\
|
||||
/obj/item/device/flash,\
|
||||
/obj/item/device/flashlight,\
|
||||
/obj/item/device/healthanalyzer,\
|
||||
/obj/item/device/multitool,\
|
||||
/obj/item/device/paicard,\
|
||||
/obj/item/device/radio,\
|
||||
/obj/item/device/radio/headset,\
|
||||
/obj/item/device/radio/beacon,\
|
||||
/obj/item/weapon/autopsy_scanner,\
|
||||
/obj/item/weapon/bikehorn,\
|
||||
/obj/item/weapon/bonesetter,\
|
||||
/obj/item/weapon/butch,\
|
||||
/obj/item/weapon/caution,\
|
||||
/obj/item/weapon/caution/cone,\
|
||||
/obj/item/weapon/crowbar,\
|
||||
/obj/item/weapon/clipboard,\
|
||||
/obj/item/weapon/cell,\
|
||||
/obj/item/weapon/circular_saw,\
|
||||
/obj/item/weapon/hatchet,\
|
||||
/obj/item/weapon/handcuffs,\
|
||||
/obj/item/weapon/hemostat,\
|
||||
/obj/item/weapon/kitchenknife,\
|
||||
/obj/item/weapon/lighter,\
|
||||
/obj/item/weapon/lighter,\
|
||||
/obj/item/weapon/light/bulb,\
|
||||
/obj/item/weapon/light/tube,\
|
||||
/obj/item/weapon/pickaxe,\
|
||||
/obj/item/weapon/shovel,\
|
||||
/obj/item/weapon/table_parts,\
|
||||
/obj/item/weapon/weldingtool,\
|
||||
/obj/item/weapon/wirecutters,\
|
||||
/obj/item/weapon/wrench,\
|
||||
/obj/item/weapon/screwdriver,\
|
||||
/obj/item/weapon/grenade/chem_grenade/cleaner,\
|
||||
/obj/item/weapon/grenade/chem_grenade/metalfoam\
|
||||
)
|
||||
|
||||
var/quantity = rand(5,15)
|
||||
for(var/i=0, i<quantity, i++)
|
||||
var/button_desc = "[pick("a yellow","a purple","a green","a blue","a red","an orange","a white")], "
|
||||
button_desc += "[pick("round","square","diamond","heart","dog","human")] shaped "
|
||||
button_desc += "[pick("toggle","switch","lever","button","pad","hole")]"
|
||||
var/type = pick(viables)
|
||||
viables.Remove(type)
|
||||
construction[button_desc] = type
|
||||
|
||||
/obj/machinery/replicator/process()
|
||||
if(spawning_types.len && powered())
|
||||
spawn_progress++
|
||||
if(spawn_progress > max_spawn_ticks)
|
||||
src.visible_message("\blue \icon[src] [src] pings!")
|
||||
var/spawn_type = spawning_types[1]
|
||||
new spawn_type(src.loc)
|
||||
|
||||
spawning_types.Remove(spawning_types[1])
|
||||
spawn_progress = 0
|
||||
max_spawn_ticks = rand(5,30)
|
||||
|
||||
if(!spawning_types.len)
|
||||
use_power = 1
|
||||
icon_state = "borgcharger0(old)"
|
||||
|
||||
else if(prob(5))
|
||||
src.visible_message("\blue \icon[src] [src] [pick("clicks","whizzes","whirrs","whooshes","clanks","clongs","clonks","bangs")].")
|
||||
|
||||
/obj/machinery/replicator/attack_hand(mob/user as mob)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/replicator/interact(mob/user)
|
||||
var/dat = "The control panel displays an incomprehensible selection of controls, many with unusual markings or text around them.<br>"
|
||||
dat += "<br>"
|
||||
for(var/index=1, index<=construction.len, index++)
|
||||
dat += "<A href='?src=\ref[src];activate=[index]'>\[[construction[index]]\]</a><br>"
|
||||
|
||||
user << browse(dat, "window=alien_replicator")
|
||||
|
||||
/obj/machinery/replicator/Topic(href, href_list)
|
||||
|
||||
if(href_list["activate"])
|
||||
var/index = text2num(href_list["activate"])
|
||||
if(index > 0 && index <= construction.len)
|
||||
if(spawning_types.len)
|
||||
src.visible_message("\blue \icon[src] a [pick("light","dial","display","meter","pad")] on [src]'s front [pick("blinks","flashes")] [pick("red","yellow","blue","orange","purple","green","white")].")
|
||||
else
|
||||
src.visible_message("\blue \icon[src] [src]'s front compartment slides shut.")
|
||||
|
||||
spawning_types.Add(construction[construction[index]])
|
||||
spawn_progress = 0
|
||||
use_power = 2
|
||||
icon_state = "borgcharger1(old)"
|
||||
@@ -0,0 +1,362 @@
|
||||
|
||||
#define EFFECT_TOUCH 0
|
||||
#define EFFECT_AURA 1
|
||||
#define EFFECT_PULSE 2
|
||||
#define MAX_EFFECT 2
|
||||
|
||||
#define TRIGGER_TOUCH 0
|
||||
#define TRIGGER_WATER 1
|
||||
#define TRIGGER_ACID 2
|
||||
#define TRIGGER_VOLATILE 3
|
||||
#define TRIGGER_TOXIN 4
|
||||
#define TRIGGER_FORCE 5
|
||||
#define TRIGGER_ENERGY 6
|
||||
#define TRIGGER_HEAT 7
|
||||
#define TRIGGER_COLD 8
|
||||
#define TRIGGER_PLASMA 9
|
||||
#define TRIGGER_OXY 10
|
||||
#define TRIGGER_CO2 11
|
||||
#define TRIGGER_NITRO 12
|
||||
#define MAX_TRIGGER 12
|
||||
/*
|
||||
//sleeping gas appears to be bugged, currently
|
||||
var/list/valid_primary_effect_types = list(\
|
||||
/datum/artifact_effect/cellcharge,\
|
||||
/datum/artifact_effect/celldrain,\
|
||||
/datum/artifact_effect/forcefield,\
|
||||
/datum/artifact_effect/gasoxy,\
|
||||
/datum/artifact_effect/gasplasma,\
|
||||
/* /datum/artifact_effect/gassleeping,\*/
|
||||
/datum/artifact_effect/heal,\
|
||||
/datum/artifact_effect/hurt,\
|
||||
/datum/artifact_effect/emp,\
|
||||
/datum/artifact_effect/teleport,\
|
||||
/datum/artifact_effect/robohurt,\
|
||||
/datum/artifact_effect/roboheal)
|
||||
|
||||
var/list/valid_secondary_effect_types = list(\
|
||||
/datum/artifact_effect/cold,\
|
||||
/datum/artifact_effect/badfeeling,\
|
||||
/datum/artifact_effect/cellcharge,\
|
||||
/datum/artifact_effect/celldrain,\
|
||||
/datum/artifact_effect/dnaswitch,\
|
||||
/datum/artifact_effect/emp,\
|
||||
/datum/artifact_effect/gasco2,\
|
||||
/datum/artifact_effect/gasnitro,\
|
||||
/datum/artifact_effect/gasoxy,\
|
||||
/datum/artifact_effect/gasplasma,\
|
||||
/* /datum/artifact_effect/gassleeping,\*/
|
||||
/datum/artifact_effect/goodfeeling,\
|
||||
/datum/artifact_effect/heal,\
|
||||
/datum/artifact_effect/hurt,\
|
||||
/datum/artifact_effect/radiate,\
|
||||
/datum/artifact_effect/roboheal,\
|
||||
/datum/artifact_effect/robohurt,\
|
||||
/datum/artifact_effect/sleepy,\
|
||||
/datum/artifact_effect/stun,\
|
||||
/datum/artifact_effect/teleport)
|
||||
*/
|
||||
|
||||
/obj/machinery/artifact
|
||||
name = "alien artifact"
|
||||
desc = "A large alien device."
|
||||
icon = 'xenoarchaeology.dmi'
|
||||
icon_state = "ano00"
|
||||
var/icon_num = 0
|
||||
density = 1
|
||||
var/datum/artifact_effect/my_effect
|
||||
var/datum/artifact_effect/secondary_effect
|
||||
var/being_used = 0
|
||||
|
||||
/obj/machinery/artifact/New()
|
||||
..()
|
||||
|
||||
//setup primary effect - these are the main ones (mixed)
|
||||
var/effecttype = pick(typesof(/datum/artifact_effect) - /datum/artifact_effect)
|
||||
my_effect = new effecttype(src)
|
||||
|
||||
//75% chance to have a secondary stealthy (and mostly bad) effect
|
||||
if(prob(75))
|
||||
effecttype = pick(typesof(/datum/artifact_effect) - /datum/artifact_effect)
|
||||
secondary_effect = new effecttype(src)
|
||||
if(prob(75))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
icon_num = rand(0,11)
|
||||
icon_state = "ano[icon_num]0"
|
||||
if(icon_num == 7 || icon_num == 8)
|
||||
name = "large crystal"
|
||||
desc = pick("It shines faintly as it catches the light.",\
|
||||
"It appears to have a faint inner glow.",\
|
||||
"It seems to draw you inward as you look it at.",\
|
||||
"Something twinkles faintly as you look at it.",\
|
||||
"It's mesmerizing to behold.")
|
||||
if(prob(50))
|
||||
my_effect.trigger = TRIGGER_ENERGY
|
||||
else if(icon_num == 9)
|
||||
name = "alien computer"
|
||||
desc = "It is covered in strange markings."
|
||||
if(prob(75))
|
||||
my_effect.trigger = TRIGGER_TOUCH
|
||||
else if(icon_num == 10)
|
||||
desc = "A large alien device, there appear to be some kind of vents in the side."
|
||||
if(prob(50))
|
||||
my_effect.trigger = rand(6,12)
|
||||
else if(icon_num == 11)
|
||||
name = "sealed alien pod"
|
||||
desc = "A strange alien device."
|
||||
if(prob(25))
|
||||
my_effect.trigger = rand(1,4)
|
||||
|
||||
#define TRIGGER_PLASMA 9
|
||||
#define TRIGGER_OXY 10
|
||||
#define TRIGGER_CO2 11
|
||||
#define TRIGGER_NITRO 12
|
||||
|
||||
/obj/machinery/artifact/process()
|
||||
if(my_effect)
|
||||
my_effect.process()
|
||||
if(secondary_effect)
|
||||
secondary_effect.process()
|
||||
|
||||
if(pulledby)
|
||||
Bumped(pulledby)
|
||||
|
||||
//if either of our effects rely on environmental factors, work that out
|
||||
var/trigger_cold = 0
|
||||
var/trigger_hot = 0
|
||||
var/trigger_plasma = 0
|
||||
var/trigger_oxy = 0
|
||||
var/trigger_co2 = 0
|
||||
var/trigger_nitro = 0
|
||||
if( (my_effect.trigger >= TRIGGER_HEAT && my_effect.trigger <= TRIGGER_NITRO) || (my_effect.trigger >= TRIGGER_HEAT && my_effect.trigger <= TRIGGER_NITRO) )
|
||||
var/turf/T = get_turf(src)
|
||||
var/datum/gas_mixture/env = T.return_air()
|
||||
if(env)
|
||||
if(env.temperature < 225)
|
||||
trigger_cold = 1
|
||||
else if(env.temperature > 375)
|
||||
trigger_hot = 1
|
||||
|
||||
if(env.toxins >= 10)
|
||||
trigger_plasma = 1
|
||||
if(env.oxygen >= 10)
|
||||
trigger_oxy = 1
|
||||
if(env.carbon_dioxide >= 10)
|
||||
trigger_co2 = 1
|
||||
if(env.nitrogen >= 10)
|
||||
trigger_nitro = 1
|
||||
|
||||
//COLD ACTIVATION
|
||||
if(trigger_cold)
|
||||
if(my_effect.trigger == TRIGGER_COLD && !my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_COLD && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else
|
||||
if(my_effect.trigger == TRIGGER_COLD && my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_COLD && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
//HEAT ACTIVATION
|
||||
if(trigger_hot)
|
||||
if(my_effect.trigger == TRIGGER_HEAT && !my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_HEAT && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else
|
||||
if(my_effect.trigger == TRIGGER_HEAT && my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_HEAT && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
//PLASMA GAS ACTIVATION
|
||||
if(trigger_plasma)
|
||||
if(my_effect.trigger == TRIGGER_PLASMA && !my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_PLASMA && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else
|
||||
if(my_effect.trigger == TRIGGER_PLASMA && my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_PLASMA && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
//OXYGEN GAS ACTIVATION
|
||||
if(trigger_oxy)
|
||||
if(my_effect.trigger == TRIGGER_OXY && !my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_OXY && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else
|
||||
if(my_effect.trigger == TRIGGER_OXY && my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_OXY && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
//CO2 GAS ACTIVATION
|
||||
if(trigger_co2)
|
||||
if(my_effect.trigger == TRIGGER_CO2 && !my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_CO2 && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else
|
||||
if(my_effect.trigger == TRIGGER_CO2 && my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_CO2 && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
//NITROGEN GAS ACTIVATION
|
||||
if(trigger_nitro)
|
||||
if(my_effect.trigger == TRIGGER_NITRO && !my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_NITRO && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else
|
||||
if(my_effect.trigger == TRIGGER_NITRO && my_effect.activated)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_NITRO && !secondary_effect.activated)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
/obj/machinery/artifact/attack_hand(var/mob/user as mob)
|
||||
if (get_dist(user, src) > 1)
|
||||
user << "\red You can't reach [src] from here."
|
||||
return
|
||||
if(ishuman(user) && user:gloves)
|
||||
user << "<b>You touch [src]</b> with your gloved hands, [pick("but nothing of note happens","but nothing happens","but nothing interesting happens","but you notice nothing different","but nothing seems to have happened")]."
|
||||
return
|
||||
|
||||
src.add_fingerprint(user)
|
||||
|
||||
if(my_effect.trigger == TRIGGER_TOUCH)
|
||||
user << "<b>You touch [src].<b>"
|
||||
my_effect.ToggleActivate()
|
||||
else
|
||||
user << "<b>You touch [src],</b> [pick("but nothing of note happens","but nothing happens","but nothing interesting happens","but you notice nothing different","but nothing seems to have happened")]."
|
||||
|
||||
if(prob(25) && secondary_effect && secondary_effect.trigger == TRIGGER_TOUCH)
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
if (my_effect.effect == EFFECT_TOUCH)
|
||||
my_effect.DoEffectTouch(user)
|
||||
|
||||
if(secondary_effect && secondary_effect.effect == EFFECT_TOUCH && secondary_effect.activated)
|
||||
secondary_effect.DoEffectTouch(user)
|
||||
|
||||
/obj/machinery/artifact/attackby(obj/item/weapon/W as obj, mob/living/user as mob)
|
||||
|
||||
if (istype(W, /obj/item/weapon/reagent_containers/))
|
||||
if(W.reagents.has_reagent("hydrogen", 1) || W.reagents.has_reagent("water", 1))
|
||||
if(my_effect.trigger == TRIGGER_WATER)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_WATER && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else if(W.reagents.has_reagent("acid", 1) || W.reagents.has_reagent("pacid", 1) || W.reagents.has_reagent("diethylamine", 1))
|
||||
if(my_effect.trigger == TRIGGER_ACID)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_ACID && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else if(W.reagents.has_reagent("plasma", 1) || W.reagents.has_reagent("thermite", 1))
|
||||
if(my_effect.trigger == TRIGGER_VOLATILE)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_VOLATILE && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else if(W.reagents.has_reagent("toxin", 1) || W.reagents.has_reagent("cyanide", 1) || W.reagents.has_reagent("amanitin", 1) || W.reagents.has_reagent("neurotoxin", 1))
|
||||
if(my_effect.trigger == TRIGGER_TOXIN)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_TOXIN && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else if(istype(W,/obj/item/weapon/melee/baton) && W:status ||\
|
||||
istype(W,/obj/item/weapon/melee/energy) ||\
|
||||
istype(W,/obj/item/weapon/melee/cultblade) ||\
|
||||
istype(W,/obj/item/weapon/card/emag) ||\
|
||||
istype(W,/obj/item/device/multitool))
|
||||
if (my_effect.trigger == TRIGGER_ENERGY)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_ENERGY && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
else if (istype(W,/obj/item/weapon/match) && W:lit ||\
|
||||
istype(W,/obj/item/weapon/weldingtool) && W:welding ||\
|
||||
istype(W,/obj/item/weapon/lighter) && W:lit)
|
||||
if(my_effect.trigger == TRIGGER_HEAT)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_HEAT && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else
|
||||
..()
|
||||
if (my_effect.trigger == TRIGGER_FORCE && W.force >= 10)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_FORCE && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
/obj/machinery/artifact/Bumped(M as mob|obj)
|
||||
..()
|
||||
if(istype(M,/obj))
|
||||
if(M:throwforce >= 10)
|
||||
if(my_effect.trigger == TRIGGER_FORCE)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_FORCE && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
else if(ishuman(M) && !istype(M:gloves,/obj/item/clothing/gloves))
|
||||
var/warn = 0
|
||||
|
||||
if (my_effect.trigger == TRIGGER_TOUCH && prob(50))
|
||||
my_effect.ToggleActivate()
|
||||
warn = 1
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_TOUCH && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
warn = 1
|
||||
|
||||
if (my_effect.effect == EFFECT_TOUCH && prob(50))
|
||||
my_effect.DoEffectTouch(M)
|
||||
warn = 1
|
||||
if(secondary_effect && secondary_effect.effect == EFFECT_TOUCH && secondary_effect.activated && prob(50))
|
||||
secondary_effect.DoEffectTouch(M)
|
||||
warn = 1
|
||||
|
||||
if(warn)
|
||||
M << "<b>You accidentally touch [src].<b>"
|
||||
..()
|
||||
|
||||
/obj/machinery/artifact/bullet_act(var/obj/item/projectile/P)
|
||||
if(istype(P,/obj/item/projectile/bullet) ||\
|
||||
istype(P,/obj/item/projectile/hivebotbullet))
|
||||
if(my_effect.trigger == TRIGGER_FORCE)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_FORCE && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
else if(istype(P,/obj/item/projectile/beam) ||\
|
||||
istype(P,/obj/item/projectile/ion) ||\
|
||||
istype(P,/obj/item/projectile/energy))
|
||||
if(my_effect.trigger == TRIGGER_ENERGY)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && secondary_effect.trigger == TRIGGER_ENERGY && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
|
||||
/obj/machinery/artifact/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0) del src
|
||||
if(2.0)
|
||||
if (prob(50))
|
||||
del src
|
||||
else
|
||||
if(my_effect.trigger == TRIGGER_FORCE || my_effect.trigger == TRIGGER_HEAT)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && (secondary_effect.trigger == TRIGGER_FORCE || secondary_effect.trigger == TRIGGER_HEAT) && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
if(3.0)
|
||||
if (my_effect.trigger == TRIGGER_FORCE || my_effect.trigger == TRIGGER_HEAT)
|
||||
my_effect.ToggleActivate()
|
||||
if(secondary_effect && (secondary_effect.trigger == TRIGGER_FORCE || secondary_effect.trigger == TRIGGER_HEAT) && prob(25))
|
||||
secondary_effect.ToggleActivate(0)
|
||||
return
|
||||
|
||||
/obj/machinery/artifact/Move()
|
||||
..()
|
||||
if(my_effect)
|
||||
my_effect.UpdateMove()
|
||||
if(secondary_effect)
|
||||
secondary_effect.UpdateMove()
|
||||
@@ -1,10 +1,18 @@
|
||||
//Part of ISaidNo's public release around July 2011(ish), multiple changes
|
||||
//many thanks
|
||||
|
||||
#define PLASMA_SPAWN 1
|
||||
#define N2_SPAWN 2
|
||||
#define CO2_SPAWN 3
|
||||
#define RADIATE 4
|
||||
#define VIRUS 5
|
||||
#define HEAT 6
|
||||
#define COLD 7
|
||||
|
||||
/obj/machinery/artifact
|
||||
name = "alien artifact"
|
||||
desc = "A large alien device."
|
||||
icon = 'anomaly.dmi'
|
||||
icon = 'xenoarchaeology.dmi'
|
||||
icon_state = "ano00"
|
||||
var/icon_num = 0
|
||||
anchored = 0
|
||||
@@ -21,55 +29,51 @@
|
||||
/obj/machinery/artifact/New()
|
||||
..()
|
||||
// Origin and appearance randomisation
|
||||
// cael - need some more icons
|
||||
|
||||
my_effect = new()
|
||||
|
||||
src.origin = pick("ancient","martian","wizard","eldritch","precursor")
|
||||
switch(src.origin)
|
||||
if("ancient") icon_num = pick(2)//src.icon_state = pick("ano2")
|
||||
if("martian") icon_num = pick(4)//src.icon_state = pick("ano4")
|
||||
if("wizard") icon_num = pick(0,1)//src.icon_state = pick("ano0","ano1")
|
||||
if("eldritch") icon_num = pick(3)//src.icon_state = pick("ano3")
|
||||
if("precursor") icon_num = pick(5)//src.icon_state = pick("ano5")
|
||||
|
||||
icon_num = rand(0,5)
|
||||
icon_state = "ano[icon_num]0"
|
||||
|
||||
// Low-ish random chance to not look like it's origin
|
||||
if(prob(20)) src.icon_state = pick("ano00","ano10","ano20","ano30","ano40","ano50")
|
||||
|
||||
// Power randomisation
|
||||
my_effect.trigger = pick("force","energy","chemical","heat","touch")
|
||||
if (my_effect.trigger == "chemical") my_effect.triggerX = pick("hydrogen","corrosive","volatile","toxic")
|
||||
my_effect.trigger = pick("force","energy","chemical","heat","touch","presence")
|
||||
if (my_effect.trigger == "chemical")
|
||||
my_effect.triggerX = pick("hydrogen","corrosive","volatile","toxic")
|
||||
|
||||
// Ancient Artifacts focus on robotic/technological effects
|
||||
// Martian Artifacts focus on biological effects
|
||||
// Wizard Artifacts focus on weird shit
|
||||
// Eldritch Artifacts are 100% bad news
|
||||
// Precursor Artifacts do everything
|
||||
switch(src.origin)
|
||||
if("ancient") my_effect.effecttype = pick("roboheal","robohurt","cellcharge","celldrain")
|
||||
if("martian") my_effect.effecttype = pick("healing","injure"/*,"stun"*/,"planthelper")
|
||||
if("wizard") my_effect.effecttype = pick(/*"stun",*/"forcefield","teleport")
|
||||
if("eldritch") my_effect.effecttype = pick("injure",/*"stun",*/"robohurt","celldrain")
|
||||
if("precursor") my_effect.effecttype = pick("healing","injure",/*"stun",*/"roboheal","robohurt","cellcharge","celldrain","planthelper","forcefield","teleport")
|
||||
my_effect.effecttype = pick("healing","injure","stun","roboheal","robohurt","cellcharge","celldrain","planthelper","forcefield","teleport","dnaswitch","emp","sleepy")
|
||||
|
||||
// Select range based on the power
|
||||
var/canworldpulse = 1
|
||||
switch(my_effect.effecttype)
|
||||
if("healing") my_effect.effectmode = pick("aura","pulse","contact")
|
||||
if("injure") my_effect.effectmode = pick("aura","pulse","contact")
|
||||
// if("stun") my_effect.effectmode = pick("aura","pulse","contact")
|
||||
if("roboheal") my_effect.effectmode = pick("aura","pulse","contact")
|
||||
if("robohurt") my_effect.effectmode = pick("aura","pulse","contact")
|
||||
if("cellcharge") my_effect.effectmode = pick("aura","pulse")
|
||||
if("celldrain") my_effect.effectmode = pick("aura","pulse")
|
||||
if("healing")
|
||||
my_effect.effectmode = pick("aura","pulse","contact")
|
||||
if("injure")
|
||||
my_effect.effectmode = pick("aura","pulse","contact")
|
||||
if("stun")
|
||||
my_effect.effectmode = pick("aura","pulse","contact")
|
||||
if("roboheal")
|
||||
my_effect.effectmode = pick("aura","pulse","contact")
|
||||
if("robohurt")
|
||||
my_effect.effectmode = pick("aura","pulse","contact")
|
||||
if("sleepy")
|
||||
my_effect.effectmode = pick("aura","pulse","contact")
|
||||
if("cellcharge")
|
||||
my_effect.effectmode = pick("aura","pulse")
|
||||
if("celldrain")
|
||||
my_effect.effectmode = pick("aura","pulse")
|
||||
if("planthelper")
|
||||
my_effect.effectmode = pick("aura","pulse")
|
||||
canworldpulse = 0
|
||||
if("forcefield")
|
||||
my_effect.effectmode = "contact"
|
||||
canworldpulse = 0
|
||||
if("teleport") my_effect.effectmode = pick("pulse","contact")
|
||||
if("teleport")
|
||||
my_effect.effectmode = pick("pulse","contact")
|
||||
if("genderswitch")
|
||||
my_effect.effectmode = pick("pulse","contact")
|
||||
if("emp")
|
||||
my_effect.effectmode = pick("pulse","contact")
|
||||
|
||||
// Recharge timer & range setup
|
||||
if (my_effect.effectmode == "aura")
|
||||
@@ -83,9 +87,11 @@
|
||||
my_effect.effectmode = "worldpulse"
|
||||
src.recharge = rand(40,120)
|
||||
|
||||
/*
|
||||
display_id += pick("kappa","sigma","antaeres","beta","lorard","omicron","iota","upsilon","omega","gamma","delta")
|
||||
display_id += "-"
|
||||
display_id += num2text(rand(100,999))
|
||||
*/
|
||||
|
||||
/obj/machinery/artifact/Del()
|
||||
..()
|
||||
@@ -191,26 +197,28 @@
|
||||
src.activated = !src.activated
|
||||
var/display_msg = ""
|
||||
if(activated)
|
||||
switch(rand(4))
|
||||
if(0)
|
||||
display_msg = "momentarily glows brightly!"
|
||||
if(1)
|
||||
display_msg = "distorts slightly for a moment!"
|
||||
if(2)
|
||||
display_msg = "makes a slightly clicking noise!"
|
||||
if(3)
|
||||
display_msg = "flickers slightly!"
|
||||
if(4)
|
||||
display_msg = "vibrates!"
|
||||
if(prob(30))
|
||||
switch(rand(4))
|
||||
if(0)
|
||||
display_msg = "momentarily glows brightly!"
|
||||
if(1)
|
||||
display_msg = "distorts slightly for a moment!"
|
||||
if(2)
|
||||
display_msg = "makes a slightly clicking noise!"
|
||||
if(3)
|
||||
display_msg = "flickers slightly!"
|
||||
if(4)
|
||||
display_msg = "vibrates!"
|
||||
else
|
||||
my_effect.HaltEffect()
|
||||
switch(rand(2))
|
||||
if(0)
|
||||
display_msg = "grows dull!"
|
||||
if(1)
|
||||
display_msg = "fades in intensity!"
|
||||
if(2)
|
||||
display_msg = "suddenly becomes very quiet!"
|
||||
if(prob(30))
|
||||
switch(rand(2))
|
||||
if(0)
|
||||
display_msg = "grows dull!"
|
||||
if(1)
|
||||
display_msg = "fades in intensity!"
|
||||
if(2)
|
||||
display_msg = "suddenly becomes very quiet!"
|
||||
|
||||
icon_state = "ano[icon_num][activated]"
|
||||
for(var/mob/O in viewers(src, null))
|
||||
@@ -232,17 +240,3 @@
|
||||
/obj/machinery/artifact/Move()
|
||||
..()
|
||||
my_effect.update_move(src, src.loc)
|
||||
|
||||
|
||||
/proc/artifact_checkgood(var/datum/artifact_effect/A)
|
||||
switch(A.effecttype)
|
||||
if("healing") return 1
|
||||
if("injure") return 0
|
||||
// if("stun") return 0
|
||||
if("roboheal") return 1
|
||||
if("robohurt") return 0
|
||||
if("cellcharge") return 1
|
||||
if("celldrain") return 1
|
||||
if("planthelper") return 1
|
||||
if("forcefield") return 1
|
||||
if("teleport") return 0
|
||||
110
code/modules/research/xenoarchaeology/artifact/effect.dm
Normal file
110
code/modules/research/xenoarchaeology/artifact/effect.dm
Normal file
@@ -0,0 +1,110 @@
|
||||
|
||||
//override procs in children as necessary
|
||||
/datum/artifact_effect
|
||||
var/effecttype = "unknown" //purely used for admin checks ingame, not needed any more
|
||||
var/effect = EFFECT_TOUCH
|
||||
var/effectrange = 4
|
||||
var/trigger = TRIGGER_TOUCH
|
||||
var/atom/holder
|
||||
var/activated = 0
|
||||
var/chargelevel = 0
|
||||
var/chargelevelmax = 10
|
||||
var/artifact_id = ""
|
||||
var/effect_type = 0
|
||||
|
||||
//0 = Unknown / none detectable
|
||||
//1 = Concentrated energy
|
||||
//2 = Intermittent psionic wavefront
|
||||
//3 = Electromagnetic energy
|
||||
//4 = Particle field
|
||||
//5 = Organically reactive exotic particles
|
||||
//6 = Interdimensional/bluespace? phasing
|
||||
//7 = Atomic synthesis
|
||||
|
||||
/datum/artifact_effect/New(var/atom/location)
|
||||
..()
|
||||
holder = location
|
||||
effect = rand(0,MAX_EFFECT)
|
||||
trigger = rand(0,MAX_TRIGGER)
|
||||
|
||||
//this will be replaced by the excavation code later, but it's here just in case
|
||||
artifact_id = "[pick("kappa","sigma","antaeres","beta","omicron","iota","epsilon","omega","gamma","delta","tau","alpha")]-[rand(100,999)]"
|
||||
|
||||
//random charge time and distance
|
||||
switch(pick(100;1, 50;2, 25;3))
|
||||
if(1)
|
||||
//short range, short charge time
|
||||
chargelevelmax = rand(3, 20)
|
||||
effectrange = rand(1, 3)
|
||||
if(2)
|
||||
//medium range, medium charge time
|
||||
chargelevelmax = rand(15, 40)
|
||||
effectrange = rand(5, 15)
|
||||
if(3)
|
||||
//large range, long charge time
|
||||
chargelevelmax = rand(20, 120)
|
||||
effectrange = rand(20, 200)
|
||||
|
||||
/datum/artifact_effect/proc/ToggleActivate(var/reveal_toggle = 1)
|
||||
//so that other stuff happens first
|
||||
spawn(0)
|
||||
if(activated)
|
||||
activated = 0
|
||||
else
|
||||
activated = 1
|
||||
if(reveal_toggle && holder)
|
||||
if(istype(holder, /obj/machinery/artifact))
|
||||
var/obj/machinery/artifact/A = holder
|
||||
A.icon_state = "ano[A.icon_num][activated]"
|
||||
var/display_msg
|
||||
if(activated)
|
||||
display_msg = pick("momentarily glows brightly!","distorts slightly for a moment!","flickers slightly!","vibrates!","shimmers slightly for a moment!")
|
||||
else
|
||||
display_msg = pick("grows dull!","fades in intensity!","suddenly becomes very still!","suddenly becomes very quiet!")
|
||||
var/atom/toplevelholder = holder
|
||||
while(!istype(toplevelholder.loc, /turf))
|
||||
toplevelholder = toplevelholder.loc
|
||||
toplevelholder.visible_message("\red \icon[toplevelholder] [toplevelholder] [display_msg]")
|
||||
|
||||
/datum/artifact_effect/proc/DoEffectTouch(var/mob/user)
|
||||
/datum/artifact_effect/proc/DoEffectAura(var/atom/holder)
|
||||
/datum/artifact_effect/proc/DoEffectPulse(var/atom/holder)
|
||||
/datum/artifact_effect/proc/UpdateMove()
|
||||
|
||||
/datum/artifact_effect/proc/process()
|
||||
if(chargelevel < chargelevelmax)
|
||||
chargelevel++
|
||||
|
||||
if(activated)
|
||||
if(effect == EFFECT_AURA)
|
||||
DoEffectAura()
|
||||
else if(effect == EFFECT_PULSE && chargelevel >= chargelevelmax)
|
||||
chargelevel = 0
|
||||
DoEffectPulse()
|
||||
|
||||
//returns 0..1, with 1 being no protection and 0 being fully protected
|
||||
proc/GetAnomalySusceptibility(var/mob/living/carbon/human/H)
|
||||
if(!H || !istype(H))
|
||||
return 1
|
||||
|
||||
var/protected = 0
|
||||
|
||||
//anomaly suits give best protection, but excavation suits are almost as good
|
||||
if(istype(H.wear_suit,/obj/item/clothing/suit/bio_suit/anomaly))
|
||||
protected += 0.6
|
||||
else if(istype(H.wear_suit,/obj/item/clothing/suit/space/anomaly))
|
||||
protected += 0.5
|
||||
|
||||
if(istype(H.head,/obj/item/clothing/head/bio_hood/anomaly))
|
||||
protected += 0.3
|
||||
else if(istype(H.head,/obj/item/clothing/head/helmet/space/anomaly))
|
||||
protected += 0.2
|
||||
|
||||
//latex gloves and science goggles also give a bit of bonus protection
|
||||
if(istype(H.gloves,/obj/item/clothing/gloves/latex))
|
||||
protected += 0.1
|
||||
|
||||
if(istype(H.glasses,/obj/item/clothing/glasses/science))
|
||||
protected += 0.1
|
||||
|
||||
return 1 - protected
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
|
||||
//inverse of /datum/artifact_effect/heat, the two effects split up for neatness' sake
|
||||
/datum/artifact_effect/cold
|
||||
effecttype = "cold"
|
||||
var/target_temp
|
||||
|
||||
/datum/artifact_effect/cold/New()
|
||||
..()
|
||||
target_temp = rand(0, 250)
|
||||
effect = pick(EFFECT_TOUCH, EFFECT_AURA)
|
||||
effect_type = pick(5,6,7)
|
||||
|
||||
/datum/artifact_effect/cold/DoEffectTouch(var/mob/user)
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env)
|
||||
env.temperature = max(env.temperature - rand(5,50), 0)
|
||||
|
||||
/datum/artifact_effect/cold/DoEffectAura()
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env && env.temperature > target_temp)
|
||||
env.temperature -= pick(0, 0, 1)
|
||||
@@ -0,0 +1,68 @@
|
||||
|
||||
/datum/artifact_effect/badfeeling
|
||||
effecttype = "badfeeling"
|
||||
effect_type = 2
|
||||
var/list/messages = list("You feel worried.",\
|
||||
"Something doesn't feel right.",\
|
||||
"You get a strange feeling in your gut.",\
|
||||
"Your instincts are trying to warn you about something.",\
|
||||
"Someone just walked over your grave.",\
|
||||
"There's a strange feeling in the air.",\
|
||||
"There's a strange smell in the air.",\
|
||||
"The tips of your fingers feel tingly.",\
|
||||
"You feel witchy.",\
|
||||
"You have a terrible sense of foreboding.",\
|
||||
"You've got a bad feeling about this.",\
|
||||
"Your scalp prickles.",\
|
||||
"The light seems to flicker.",\
|
||||
"The shadows seem to lengthen.",\
|
||||
"The walls are getting closer.",\
|
||||
"Something is wrong")
|
||||
|
||||
var/list/drastic_messages = list("You've got to get out of here!",\
|
||||
"Someone's trying to kill you!",\
|
||||
"There's something out there!",\
|
||||
"What's happening to you?",\
|
||||
"OH GOD!",\
|
||||
"HELP ME!")
|
||||
|
||||
/datum/artifact_effect/badfeeling/DoEffectTouch(var/mob/user)
|
||||
if(user)
|
||||
if (istype(user, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(prob(50))
|
||||
if(prob(75))
|
||||
H << "<b><font color='red' size='[num2text(rand(1,5))]'><b>[pick(drastic_messages)]</b></font>"
|
||||
else
|
||||
H << "<font color='red'>[pick(messages)]</font>"
|
||||
|
||||
if(prob(50))
|
||||
H.dizziness += rand(3,5)
|
||||
|
||||
/datum/artifact_effect/badfeeling/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
|
||||
if(prob(5))
|
||||
if(prob(75))
|
||||
H << "<font color='red'>[pick(messages)]</font>"
|
||||
else
|
||||
H << "<font color='red' size='[num2text(rand(1,5))]'><b>[pick(drastic_messages)]</b></font>"
|
||||
|
||||
if(prob(10))
|
||||
H.dizziness += rand(3,5)
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/badfeeling/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
|
||||
if(prob(50))
|
||||
if(prob(95))
|
||||
H << "<font color='red' size='[num2text(rand(1,5))]'><b>[pick(drastic_messages)]</b></font>"
|
||||
else
|
||||
H << "<font color='red'>[pick(messages)]</font>"
|
||||
|
||||
if(prob(50))
|
||||
H.dizziness += rand(3,5)
|
||||
else if(prob(25))
|
||||
H.dizziness += rand(5,15)
|
||||
return 1
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
//todo
|
||||
/datum/artifact_effect/cellcharge
|
||||
effecttype = "cellcharge"
|
||||
effect_type = 3
|
||||
|
||||
/datum/artifact_effect/cellcharge/DoEffectTouch(var/mob/user)
|
||||
if(user)
|
||||
if(istype(user, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = user
|
||||
for (var/obj/item/weapon/cell/D in R.contents)
|
||||
D.charge += rand() * 100 + 50
|
||||
R << "\blue SYSTEM ALERT: Large energy boost detected!"
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/cellcharge/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/obj/machinery/power/apc/C in range(200, holder))
|
||||
for (var/obj/item/weapon/cell/B in C.contents)
|
||||
B.charge += 25
|
||||
for (var/obj/machinery/power/smes/S in range (src.effectrange,src))
|
||||
S.charge += 25
|
||||
for (var/mob/living/silicon/robot/M in world)
|
||||
for (var/obj/item/weapon/cell/D in M.contents)
|
||||
D.charge += 25
|
||||
M << "\blue SYSTEM ALERT: Energy boost detected!"
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/cellcharge/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/obj/machinery/power/apc/C in range(200, holder))
|
||||
for (var/obj/item/weapon/cell/B in C.contents)
|
||||
B.charge += rand() * 100
|
||||
for (var/obj/machinery/power/smes/S in range (src.effectrange,src))
|
||||
S.charge += 250
|
||||
for (var/mob/living/silicon/robot/M in world)
|
||||
for (var/obj/item/weapon/cell/D in M.contents)
|
||||
D.charge += rand() * 100
|
||||
M << "\blue SYSTEM ALERT: Energy boost detected!"
|
||||
return 1
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
//todo
|
||||
/datum/artifact_effect/celldrain
|
||||
effecttype = "celldrain"
|
||||
effect_type = 3
|
||||
|
||||
/datum/artifact_effect/celldrain/DoEffectTouch(var/mob/user)
|
||||
if(user)
|
||||
if(istype(user, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = user
|
||||
for (var/obj/item/weapon/cell/D in R.contents)
|
||||
D.charge = max(D.charge - rand() * 100, 0)
|
||||
R << "\blue SYSTEM ALERT: Energy drain detected!"
|
||||
return 1
|
||||
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/celldrain/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/obj/machinery/power/apc/C in range(200, holder))
|
||||
for (var/obj/item/weapon/cell/B in C.contents)
|
||||
B.charge = max(B.charge - 50,0)
|
||||
for (var/obj/machinery/power/smes/S in range (src.effectrange,src))
|
||||
S.charge = max(S.charge - 100,0)
|
||||
for (var/mob/living/silicon/robot/M in world)
|
||||
for (var/obj/item/weapon/cell/D in M.contents)
|
||||
D.charge = max(D.charge - 50,0)
|
||||
M << "\red SYSTEM ALERT: Energy drain detected!"
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/celldrain/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/obj/machinery/power/apc/C in range(200, holder))
|
||||
for (var/obj/item/weapon/cell/B in C.contents)
|
||||
B.charge = max(B.charge - rand() * 150,0)
|
||||
for (var/obj/machinery/power/smes/S in range (src.effectrange,src))
|
||||
S.charge = max(S.charge - 250,0)
|
||||
for (var/mob/living/silicon/robot/M in world)
|
||||
for (var/obj/item/weapon/cell/D in M.contents)
|
||||
D.charge = max(D.charge - rand() * 150,0)
|
||||
M << "\red SYSTEM ALERT: Energy drain detected!"
|
||||
return 1
|
||||
@@ -0,0 +1,66 @@
|
||||
|
||||
//todo
|
||||
/datum/artifact_effect/dnaswitch
|
||||
effecttype = "dnaswitch"
|
||||
effect_type = 5
|
||||
var/severity
|
||||
|
||||
/datum/artifact_effect/dnaswitch/New()
|
||||
..()
|
||||
if(effect == EFFECT_AURA)
|
||||
severity = rand(5,30)
|
||||
else
|
||||
severity = rand(25,95)
|
||||
|
||||
/datum/artifact_effect/dnaswitch/DoEffectTouch(var/mob/toucher)
|
||||
var/weakness = GetAnomalySusceptibility(toucher)
|
||||
if(ishuman(toucher) && prob(weakness * 100))
|
||||
toucher << pick("\green You feel a little different.",\
|
||||
"\green You feel very strange.",\
|
||||
"\green Your stomach churns.",\
|
||||
"\green Your skin feels loose.",\
|
||||
"\green You feel a stabbing pain in your head.",\
|
||||
"\green You feel a tingling sensation in your chest.",\
|
||||
"\green Your entire body vibrates.")
|
||||
if(prob(75))
|
||||
scramble(1, toucher, weakness * severity)
|
||||
else
|
||||
scramble(0, toucher, weakness * severity)
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/dnaswitch/DoEffectAura()
|
||||
if(holder)
|
||||
for(var/mob/living/carbon/human/H in range(src.effectrange,holder))
|
||||
var/weakness = GetAnomalySusceptibility(H)
|
||||
if(prob(weakness * 100))
|
||||
if(prob(30))
|
||||
H << pick("\green You feel a little different.",\
|
||||
"\green You feel very strange.",\
|
||||
"\green Your stomach churns.",\
|
||||
"\green Your skin feels loose.",\
|
||||
"\green You feel a stabbing pain in your head.",\
|
||||
"\green You feel a tingling sensation in your chest.",\
|
||||
"\green Your entire body vibrates.")
|
||||
if(prob(50))
|
||||
scramble(1, H, weakness * severity)
|
||||
else
|
||||
scramble(0, H, weakness * severity)
|
||||
|
||||
/datum/artifact_effect/dnaswitch/DoEffectPulse()
|
||||
if(holder)
|
||||
for(var/mob/living/carbon/human/H in range(200, holder))
|
||||
var/weakness = GetAnomalySusceptibility(H)
|
||||
if(prob(weakness * 100))
|
||||
if(prob(75))
|
||||
H << pick("\green You feel a little different.",\
|
||||
"\green You feel very strange.",\
|
||||
"\green Your stomach churns.",\
|
||||
"\green Your skin feels loose.",\
|
||||
"\green You feel a stabbing pain in your head.",\
|
||||
"\green You feel a tingling sensation in your chest.",\
|
||||
"\green Your entire body vibrates.")
|
||||
if(prob(25))
|
||||
if(prob(75))
|
||||
scramble(1, H, weakness * severity)
|
||||
else
|
||||
scramble(0, H, weakness * severity)
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
/datum/artifact_effect/emp
|
||||
effecttype = "emp"
|
||||
effect_type = 3
|
||||
|
||||
/datum/artifact_effect/emp/New()
|
||||
..()
|
||||
effect = EFFECT_PULSE
|
||||
|
||||
/datum/artifact_effect/emp/DoEffectPulse()
|
||||
if(holder)
|
||||
empulse(get_turf(holder), effectrange/2, effectrange)
|
||||
return 1
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
/datum/artifact_effect/forcefield
|
||||
effecttype = "forcefield"
|
||||
var/list/created_field = list()
|
||||
effect_type = 4
|
||||
|
||||
/datum/artifact_effect/forcefield/New()
|
||||
..()
|
||||
trigger = TRIGGER_TOUCH
|
||||
|
||||
/datum/artifact_effect/forcefield/ToggleActivate()
|
||||
..()
|
||||
if(created_field.len)
|
||||
for(var/obj/effect/energy_field/F in created_field)
|
||||
created_field.Remove(F)
|
||||
del F
|
||||
else if(holder)
|
||||
var/turf/T = get_turf(holder)
|
||||
while(created_field.len < 16)
|
||||
var/obj/effect/energy_field/E = new (locate(T.x,T.y,T.z))
|
||||
created_field.Add(E)
|
||||
E.strength = 1
|
||||
E.density = 1
|
||||
E.anchored = 1
|
||||
E.invisibility = 0
|
||||
spawn(10)
|
||||
UpdateMove()
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/forcefield/process()
|
||||
..()
|
||||
for(var/obj/effect/energy_field/E in created_field)
|
||||
if(E.strength < 1)
|
||||
E.Strengthen(0.15)
|
||||
else if(E.strength < 5)
|
||||
E.Strengthen(0.25)
|
||||
|
||||
/datum/artifact_effect/forcefield/UpdateMove()
|
||||
if(created_field.len && holder)
|
||||
var/turf/T = get_turf(holder)
|
||||
while(created_field.len < 16)
|
||||
//for now, just instantly respawn the fields when they get destroyed
|
||||
var/obj/effect/energy_field/E = new (locate(T.x,T.y,T))
|
||||
created_field.Add(E)
|
||||
E.anchored = 1
|
||||
E.density = 1
|
||||
E.invisibility = 0
|
||||
|
||||
var/obj/effect/energy_field/E = created_field[1]
|
||||
E.loc = locate(T.x + 2,T.y + 2,T.z)
|
||||
E = created_field[2]
|
||||
E.loc = locate(T.x + 2,T.y + 1,T.z)
|
||||
E = created_field[3]
|
||||
E.loc = locate(T.x + 2,T.y,T.z)
|
||||
E = created_field[4]
|
||||
E.loc = locate(T.x + 2,T.y - 1,T.z)
|
||||
E = created_field[5]
|
||||
E.loc = locate(T.x + 2,T.y - 2,T.z)
|
||||
E = created_field[6]
|
||||
E.loc = locate(T.x + 1,T.y + 2,T.z)
|
||||
E = created_field[7]
|
||||
E.loc = locate(T.x + 1,T.y - 2,T.z)
|
||||
E = created_field[8]
|
||||
E.loc = locate(T.x,T.y + 2,T.z)
|
||||
E = created_field[9]
|
||||
E.loc = locate(T.x,T.y - 2,T.z)
|
||||
E = created_field[10]
|
||||
E.loc = locate(T.x - 1,T.y + 2,T.z)
|
||||
E = created_field[11]
|
||||
E.loc = locate(T.x - 1,T.y - 2,T.z)
|
||||
E = created_field[12]
|
||||
E.loc = locate(T.x - 2,T.y + 2,T.z)
|
||||
E = created_field[13]
|
||||
E.loc = locate(T.x - 2,T.y + 1,T.z)
|
||||
E = created_field[14]
|
||||
E.loc = locate(T.x - 2,T.y,T.z)
|
||||
E = created_field[15]
|
||||
E.loc = locate(T.x - 2,T.y - 1,T.z)
|
||||
E = created_field[16]
|
||||
E.loc = locate(T.x - 2,T.y - 2,T.z)
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
/datum/artifact_effect/gasco2
|
||||
effecttype = "gasco2"
|
||||
var/max_pressure
|
||||
var/target_percentage
|
||||
|
||||
/datum/artifact_effect/heat/New()
|
||||
..()
|
||||
effect_type = pick(6,7)
|
||||
|
||||
/datum/artifact_effect/gasco2/New()
|
||||
..()
|
||||
effect = pick(EFFECT_TOUCH, EFFECT_AURA)
|
||||
max_pressure = rand(115,1000)
|
||||
|
||||
/datum/artifact_effect/gasco2/DoEffectTouch(var/mob/user)
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env)
|
||||
env.carbon_dioxide += rand(2,15)
|
||||
|
||||
/datum/artifact_effect/gasco2/DoEffectAura()
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env && env.total_moles < max_pressure)
|
||||
env.carbon_dioxide += pick(0, 0, 0.1, rand())
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
/datum/artifact_effect/gasnitro
|
||||
effecttype = "gasnitro"
|
||||
var/max_pressure
|
||||
var/target_percentage
|
||||
|
||||
/datum/artifact_effect/gasnitro/New()
|
||||
..()
|
||||
effect = pick(EFFECT_TOUCH, EFFECT_AURA)
|
||||
effect_type = pick(6,7)
|
||||
max_pressure = rand(115,1000)
|
||||
|
||||
/datum/artifact_effect/gasnitro/DoEffectTouch(var/mob/user)
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env)
|
||||
env.nitrogen += rand(2,15)
|
||||
|
||||
/datum/artifact_effect/gasnitro/DoEffectAura()
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env && env.total_moles < max_pressure)
|
||||
env.nitrogen += pick(0, 0, 0.1, rand())
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
/datum/artifact_effect/gasoxy
|
||||
effecttype = "gasoxy"
|
||||
var/max_pressure
|
||||
|
||||
/datum/artifact_effect/gasoxy/New()
|
||||
..()
|
||||
effect = pick(EFFECT_TOUCH, EFFECT_AURA)
|
||||
max_pressure = rand(115,1000)
|
||||
effect_type = pick(6,7)
|
||||
|
||||
|
||||
/datum/artifact_effect/gasoxy/DoEffectTouch(var/mob/user)
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env)
|
||||
env.oxygen += rand(2,15)
|
||||
|
||||
/datum/artifact_effect/gasoxy/DoEffectAura()
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env && env.total_moles < max_pressure)
|
||||
env.oxygen += pick(0, 0, 0.1, rand())
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
/datum/artifact_effect/gasplasma
|
||||
effecttype = "gasplasma"
|
||||
var/max_pressure
|
||||
var/target_percentage
|
||||
|
||||
/datum/artifact_effect/gasplasma/New()
|
||||
..()
|
||||
effect = pick(EFFECT_TOUCH, EFFECT_AURA)
|
||||
max_pressure = rand(115,1000)
|
||||
effect_type = pick(6,7)
|
||||
|
||||
/datum/artifact_effect/gasplasma/DoEffectTouch(var/mob/user)
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env)
|
||||
env.toxins += rand(2,15)
|
||||
|
||||
/datum/artifact_effect/gasplasma/DoEffectAura()
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env && env.total_moles < max_pressure)
|
||||
env.toxins += pick(0, 0, 0.1, rand())
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
/datum/artifact_effect/gassleeping
|
||||
effecttype = "gassleeping"
|
||||
var/max_pressure
|
||||
var/target_percentage
|
||||
|
||||
/datum/artifact_effect/gassleeping/New()
|
||||
..()
|
||||
effect = pick(EFFECT_TOUCH, EFFECT_AURA)
|
||||
max_pressure = rand(115,1000)
|
||||
effect_type = pick(6,7)
|
||||
|
||||
/datum/artifact_effect/gassleeping/DoEffectTouch(var/mob/user)
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env)
|
||||
var/datum/gas/sleeping_agent/trace_gas = new
|
||||
env.trace_gases += trace_gas
|
||||
trace_gas.moles = rand(2,15)
|
||||
env.update_values()
|
||||
|
||||
|
||||
/datum/artifact_effect/gassleeping/DoEffectAura()
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env && env.total_moles < max_pressure)
|
||||
var/datum/gas/sleeping_agent/trace_gas = new
|
||||
env.trace_gases += trace_gas
|
||||
trace_gas.moles = pick(0, 0, 0.1, rand())
|
||||
env.update_values()
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
|
||||
/datum/artifact_effect/goodfeeling
|
||||
effecttype = "goodfeeling"
|
||||
effect_type = 2
|
||||
var/list/messages = list("You feel good.",\
|
||||
"Everything seems to be going alright",\
|
||||
"You've got a good feeling about this",\
|
||||
"Your instincts tell you everything is going to be getting better.",\
|
||||
"There's a good feeling in the air.",\
|
||||
"Something smells... good.",\
|
||||
"The tips of your fingers feel tingly.",\
|
||||
"You've got a good feeling about this.",\
|
||||
"You feel happy.",\
|
||||
"You fight the urge to smile.",\
|
||||
"Your scalp prickles.",\
|
||||
"All the colours seem a bit more vibrant.",\
|
||||
"Everything seems a little lighter.",\
|
||||
"The troubles of the world seem to fade away.")
|
||||
|
||||
var/list/drastic_messages = list("You want to hug everyone you meet!",\
|
||||
"Everything is going so well!",\
|
||||
"You feel euphoric.",\
|
||||
"You feel giddy.",\
|
||||
"You're so happy suddenly, you almost want to dance and sing.",\
|
||||
"You feel like the world is out to help you.")
|
||||
|
||||
/datum/artifact_effect/goodfeeling/DoEffectTouch(var/mob/user)
|
||||
if(user)
|
||||
if (istype(user, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(prob(50))
|
||||
if(prob(75))
|
||||
H << "<b><font color='blue' size='[num2text(rand(1,5))]'><b>[pick(drastic_messages)]</b></font>"
|
||||
else
|
||||
H << "<font color='blue'>[pick(messages)]</font>"
|
||||
|
||||
if(prob(50))
|
||||
H.dizziness += rand(3,5)
|
||||
|
||||
/datum/artifact_effect/goodfeeling/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
|
||||
if(prob(5))
|
||||
if(prob(75))
|
||||
H << "<font color='blue'>[pick(messages)]</font>"
|
||||
else
|
||||
H << "<font color='blue' size='[num2text(rand(1,5))]'><b>[pick(drastic_messages)]</b></font>"
|
||||
|
||||
if(prob(5))
|
||||
H.dizziness += rand(3,5)
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/goodfeeling/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
|
||||
if(prob(50))
|
||||
if(prob(95))
|
||||
H << "<font color='blue' size='[num2text(rand(1,5))]'><b>[pick(drastic_messages)]</b></font>"
|
||||
else
|
||||
H << "<font color='blue'>[pick(messages)]</font>"
|
||||
|
||||
if(prob(50))
|
||||
H.dizziness += rand(3,5)
|
||||
else if(prob(25))
|
||||
H.dizziness += rand(5,15)
|
||||
return 1
|
||||
@@ -0,0 +1,63 @@
|
||||
|
||||
/datum/artifact_effect/heal
|
||||
effecttype = "heal"
|
||||
effect_type = 5
|
||||
|
||||
/datum/artifact_effect/heal/DoEffectTouch(var/mob/toucher)
|
||||
//todo: check over this properly
|
||||
if(toucher && iscarbon(toucher))
|
||||
var/weakness = GetAnomalySusceptibility(toucher)
|
||||
if(prob(weakness * 100))
|
||||
var/mob/living/carbon/C = toucher
|
||||
C << "\blue You feel a soothing energy invigorate you."
|
||||
|
||||
if(ishuman(toucher))
|
||||
var/mob/living/carbon/human/H = toucher
|
||||
for(var/datum/organ/external/affecting in H.organs)
|
||||
if(affecting && istype(affecting))
|
||||
affecting.heal_damage(25 * weakness, 25 * weakness)
|
||||
//H:heal_organ_damage(25, 25)
|
||||
H.vessel.add_reagent("blood",5)
|
||||
H.nutrition += 50 * weakness
|
||||
H.adjustBrainLoss(-25 * weakness)
|
||||
H.radiation -= min(H.radiation, 25 * weakness)
|
||||
H.bodytemperature = initial(H.bodytemperature)
|
||||
spawn(1)
|
||||
H.fixblood()
|
||||
//
|
||||
C.adjustOxyLoss(-25 * weakness)
|
||||
C.adjustToxLoss(-25 * weakness)
|
||||
C.adjustBruteLoss(-25 * weakness)
|
||||
C.adjustFireLoss(-25 * weakness)
|
||||
//
|
||||
C.regenerate_icons()
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/heal/DoEffectAura()
|
||||
//todo: check over this properly
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/C in range(src.effectrange,holder))
|
||||
var/weakness = GetAnomalySusceptibility(C)
|
||||
if(prob(weakness * 100))
|
||||
if(prob(10))
|
||||
C << "\blue You feel a soothing energy radiating from something nearby."
|
||||
C.adjustBruteLoss(-1 * weakness)
|
||||
C.adjustFireLoss(-1 * weakness)
|
||||
C.adjustToxLoss(-1 * weakness)
|
||||
C.adjustOxyLoss(-1 * weakness)
|
||||
C.adjustBrainLoss(-1 * weakness)
|
||||
C.updatehealth()
|
||||
|
||||
/datum/artifact_effect/heal/DoEffectPulse()
|
||||
//todo: check over this properly
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/C in range(src.effectrange,holder))
|
||||
var/weakness = GetAnomalySusceptibility(C)
|
||||
if(prob(weakness * 100))
|
||||
C << "\blue A wave of energy invigorates you."
|
||||
C.adjustBruteLoss(-5 * weakness)
|
||||
C.adjustFireLoss(-5 * weakness)
|
||||
C.adjustToxLoss(-5 * weakness)
|
||||
C.adjustOxyLoss(-5 * weakness)
|
||||
C.adjustBrainLoss(-5 * weakness)
|
||||
C.updatehealth()
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
//inverse of /datum/artifact_effect/cold, the two effects split up for neatness' sake
|
||||
/datum/artifact_effect/heat
|
||||
effecttype = "heat"
|
||||
var/target_temp
|
||||
|
||||
/datum/artifact_effect/heat/New()
|
||||
..()
|
||||
effect_type = pick(5,6,7)
|
||||
|
||||
/datum/artifact_effect/heat/New()
|
||||
..()
|
||||
target_temp = rand(300,600)
|
||||
effect = pick(EFFECT_TOUCH, EFFECT_AURA)
|
||||
|
||||
/datum/artifact_effect/heat/DoEffectTouch(var/mob/user)
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env)
|
||||
env.temperature += rand(5,50)
|
||||
|
||||
/datum/artifact_effect/heat/DoEffectAura()
|
||||
if(holder)
|
||||
var/datum/gas_mixture/env = holder.loc.return_air()
|
||||
if(env && env.temperature < target_temp)
|
||||
env.temperature += pick(0, 0, 1)
|
||||
@@ -0,0 +1,47 @@
|
||||
|
||||
/datum/artifact_effect/hurt
|
||||
effecttype = "hurt"
|
||||
effect_type = 5
|
||||
|
||||
/datum/artifact_effect/hurt/DoEffectTouch(var/mob/toucher)
|
||||
if(toucher)
|
||||
var/weakness = GetAnomalySusceptibility(toucher)
|
||||
if(iscarbon(toucher) && prob(weakness * 100))
|
||||
var/mob/living/carbon/C = toucher
|
||||
C << "\red A painful discharge of energy strikes you!"
|
||||
C.adjustOxyLoss(rand(5,25) * weakness)
|
||||
C.adjustToxLoss(rand(5,25) * weakness)
|
||||
C.adjustBruteLoss(rand(5,25) * weakness)
|
||||
C.adjustFireLoss(rand(5,25) * weakness)
|
||||
C.adjustBrainLoss(rand(5,25) * weakness)
|
||||
C.radiation += 25 * weakness
|
||||
C.nutrition -= min(50 * weakness, C.nutrition)
|
||||
C.make_dizzy(6 * weakness)
|
||||
C.weakened += 6 * weakness
|
||||
|
||||
/datum/artifact_effect/hurt/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/C in range(src.effectrange,holder))
|
||||
var/weakness = GetAnomalySusceptibility(C)
|
||||
if(prob(weakness * 100))
|
||||
if(prob(10))
|
||||
C << "\red You feel a painful force radiating from something nearby."
|
||||
C.adjustBruteLoss(1 * weakness)
|
||||
C.adjustFireLoss(1 * weakness)
|
||||
C.adjustToxLoss(1 * weakness)
|
||||
C.adjustOxyLoss(1 * weakness)
|
||||
C.adjustBrainLoss(1 * weakness)
|
||||
C.updatehealth()
|
||||
|
||||
/datum/artifact_effect/hurt/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/C in range(effectrange, holder))
|
||||
var/weakness = GetAnomalySusceptibility(C)
|
||||
if(prob(weakness * 100))
|
||||
C << "\red A wave of painful energy strikes you!"
|
||||
C.adjustBruteLoss(3 * weakness)
|
||||
C.adjustFireLoss(3 * weakness)
|
||||
C.adjustToxLoss(3 * weakness)
|
||||
C.adjustOxyLoss(3 * weakness)
|
||||
C.adjustBrainLoss(3 * weakness)
|
||||
C.updatehealth()
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
/datum/artifact_effect/radiate
|
||||
effecttype = "radiate"
|
||||
var/radiation_amount
|
||||
|
||||
/datum/artifact_effect/radiate/New()
|
||||
..()
|
||||
radiation_amount = rand(1, 10)
|
||||
effect_type = pick(4,5)
|
||||
|
||||
/datum/artifact_effect/radiate/DoEffectTouch(var/mob/living/user)
|
||||
if(user)
|
||||
user.apply_effect(radiation_amount * 5,IRRADIATE,0)
|
||||
user.updatehealth()
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/radiate/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/M in range(src.effectrange,holder))
|
||||
M.apply_effect(radiation_amount,IRRADIATE,0)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/radiate/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/mob/living/M in range(src.effectrange,holder))
|
||||
M.apply_effect(radiation_amount * 25,IRRADIATE,0)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
@@ -0,0 +1,35 @@
|
||||
|
||||
/datum/artifact_effect/roboheal
|
||||
effecttype = "roboheal"
|
||||
|
||||
/datum/artifact_effect/roboheal/New()
|
||||
..()
|
||||
effect_type = pick(3,4)
|
||||
|
||||
/datum/artifact_effect/roboheal/DoEffectTouch(var/mob/user)
|
||||
if(user)
|
||||
if (istype(user, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = user
|
||||
R << "\blue Your systems report damaged components mending by themselves!"
|
||||
R.adjustBruteLoss(rand(-10,-30))
|
||||
R.adjustFireLoss(rand(-10,-30))
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/roboheal/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/silicon/robot/M in range(src.effectrange,holder))
|
||||
if(prob(10))
|
||||
M << "\blue SYSTEM ALERT: Beneficial energy field detected!"
|
||||
M.adjustBruteLoss(-1)
|
||||
M.adjustFireLoss(-1)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/roboheal/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/mob/living/silicon/robot/M in range(src.effectrange,holder))
|
||||
M << "\blue SYSTEM ALERT: Structural damage has been repaired by energy pulse!"
|
||||
M.adjustBruteLoss(-10)
|
||||
M.adjustFireLoss(-10)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
/datum/artifact_effect/robohurt
|
||||
effecttype = "robohurt"
|
||||
|
||||
/datum/artifact_effect/robohurt/New()
|
||||
..()
|
||||
effect_type = pick(3,4)
|
||||
|
||||
/datum/artifact_effect/robohurt/DoEffectTouch(var/mob/user)
|
||||
if(user)
|
||||
if (istype(user, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/R = user
|
||||
R << "\red Your systems report severe damage has been inflicted!"
|
||||
R.adjustBruteLoss(rand(10,50))
|
||||
R.adjustFireLoss(rand(10,50))
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/robohurt/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/silicon/robot/M in range(src.effectrange,holder))
|
||||
if(prob(10)) M << "\red SYSTEM ALERT: Harmful energy field detected!"
|
||||
M.adjustBruteLoss(1)
|
||||
M.adjustFireLoss(1)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/robohurt/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/mob/living/silicon/robot/M in range(src.effectrange,holder))
|
||||
M << "\red SYSTEM ALERT: Structural damage inflicted by energy pulse!"
|
||||
M.adjustBruteLoss(10)
|
||||
M.adjustFireLoss(10)
|
||||
M.updatehealth()
|
||||
return 1
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
//todo
|
||||
/datum/artifact_effect/sleepy
|
||||
effecttype = "sleepy"
|
||||
|
||||
/datum/artifact_effect/sleepy/New()
|
||||
..()
|
||||
effect_type = pick(5,2)
|
||||
|
||||
/datum/artifact_effect/sleepy/DoEffectTouch(var/mob/toucher)
|
||||
if(toucher)
|
||||
var/weakness = GetAnomalySusceptibility(toucher)
|
||||
if(ishuman(toucher) && prob(weakness * 100))
|
||||
var/mob/living/carbon/human/H = toucher
|
||||
H << pick("\blue You feel like taking a nap.","\blue You feel a yawn coming on.","\blue You feel a little tired.")
|
||||
H.drowsyness = min(H.drowsyness + rand(5,25) * weakness, 50 * weakness)
|
||||
H.eye_blurry = min(H.eye_blurry + rand(1,3) * weakness, 50 * weakness)
|
||||
return 1
|
||||
else if(isrobot(toucher))
|
||||
toucher << "\red SYSTEM ALERT: CPU cycles slowing down."
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/sleepy/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
|
||||
var/weakness = GetAnomalySusceptibility(H)
|
||||
if(prob(weakness * 100))
|
||||
if(prob(10))
|
||||
H << pick("\blue You feel like taking a nap.","\blue You feel a yawn coming on.","\blue You feel a little tired.")
|
||||
H.drowsyness = min(H.drowsyness + 1 * weakness, 25 * weakness)
|
||||
H.eye_blurry = min(H.eye_blurry + 1 * weakness, 25 * weakness)
|
||||
for (var/mob/living/silicon/robot/R in range(src.effectrange,holder))
|
||||
R << "\red SYSTEM ALERT: CPU cycles slowing down."
|
||||
return 1
|
||||
|
||||
/datum/artifact_effect/sleepy/DoEffectPulse()
|
||||
if(holder)
|
||||
for(var/mob/living/carbon/human/H in range(src.effectrange, holder))
|
||||
var/weakness = GetAnomalySusceptibility(H)
|
||||
if(prob(weakness * 100))
|
||||
H << pick("\blue You feel like taking a nap.","\blue You feel a yawn coming on.","\blue You feel a little tired.")
|
||||
H.drowsyness = min(H.drowsyness + rand(5,15) * weakness, 50 * weakness)
|
||||
H.eye_blurry = min(H.eye_blurry + rand(5,15) * weakness, 50 * weakness)
|
||||
for (var/mob/living/silicon/robot/R in range(src.effectrange,holder))
|
||||
R << "\red SYSTEM ALERT: CPU cycles slowing down."
|
||||
return 1
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
/datum/artifact_effect/stun
|
||||
effecttype = "stun"
|
||||
|
||||
/datum/artifact_effect/stun/New()
|
||||
..()
|
||||
effect_type = pick(2,5)
|
||||
|
||||
/datum/artifact_effect/stun/DoEffectTouch(var/mob/toucher)
|
||||
if(toucher && iscarbon(toucher))
|
||||
var/mob/living/carbon/C = toucher
|
||||
var/weakness = GetAnomalySusceptibility(C)
|
||||
if(prob(weakness * 100))
|
||||
C << "\red A powerful force overwhelms your consciousness."
|
||||
C.weakened += 45 * weakness
|
||||
C.stuttering += 45 * weakness
|
||||
C.stunned += rand(1,10) * weakness
|
||||
|
||||
/datum/artifact_effect/stun/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/C in range(src.effectrange,holder))
|
||||
var/weakness = GetAnomalySusceptibility(C)
|
||||
if(prob(10 * weakness))
|
||||
C << "\red Your body goes numb for a moment."
|
||||
C.weakened += 2
|
||||
C.stuttering += 2
|
||||
if(prob(10))
|
||||
C.stunned += 1
|
||||
else if(prob(10))
|
||||
C << "\red You feel numb."
|
||||
|
||||
/datum/artifact_effect/stun/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/mob/living/carbon/C in range(src.effectrange,holder))
|
||||
var/weakness = GetAnomalySusceptibility(C)
|
||||
if(prob(100 * weakness))
|
||||
C << "\red A wave of energy overwhelms your senses!"
|
||||
C.weakened += 4 * weakness
|
||||
C.stuttering += 4 * weakness
|
||||
if(prob(10))
|
||||
C.stunned += 1 * weakness
|
||||
@@ -0,0 +1,65 @@
|
||||
|
||||
/datum/artifact_effect/teleport
|
||||
effecttype = "teleport"
|
||||
effect_type = 6
|
||||
|
||||
/datum/artifact_effect/teleport/DoEffectTouch(var/mob/user)
|
||||
var/weakness = GetAnomalySusceptibility(user)
|
||||
if(prob(100 * weakness))
|
||||
var/list/randomturfs = new/list()
|
||||
for(var/turf/simulated/floor/T in orange(user, 50))
|
||||
randomturfs.Add(T)
|
||||
if(randomturfs.len > 0)
|
||||
user << "\red You are suddenly zapped away elsewhere!"
|
||||
if (user.buckled)
|
||||
user.buckled.unbuckle()
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(3, 0, get_turf(user))
|
||||
sparks.start()
|
||||
user.loc = pick(randomturfs)
|
||||
sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(3, 0, get_turf(user))
|
||||
sparks.start()
|
||||
|
||||
/datum/artifact_effect/teleport/DoEffectAura()
|
||||
if(holder)
|
||||
for (var/mob/living/M in range(src.effectrange,holder))
|
||||
var/weakness = GetAnomalySusceptibility(M)
|
||||
if(prob(100 * weakness))
|
||||
var/list/randomturfs = new/list()
|
||||
for(var/turf/simulated/floor/T in orange(M, 30))
|
||||
randomturfs.Add(T)
|
||||
if(randomturfs.len > 0)
|
||||
M << "\red You are displaced by a strange force!"
|
||||
if(M.buckled)
|
||||
M.buckled.unbuckle()
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(3, 0, get_turf(M))
|
||||
sparks.start()
|
||||
M.loc = pick(randomturfs)
|
||||
sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(3, 0, get_turf(M))
|
||||
sparks.start()
|
||||
|
||||
/datum/artifact_effect/teleport/DoEffectPulse()
|
||||
if(holder)
|
||||
for (var/mob/living/M in range(src.effectrange, holder))
|
||||
var/weakness = GetAnomalySusceptibility(M)
|
||||
if(prob(100 * weakness))
|
||||
var/list/randomturfs = new/list()
|
||||
for(var/turf/simulated/floor/T in orange(M, 15))
|
||||
randomturfs.Add(T)
|
||||
if(randomturfs.len > 0)
|
||||
M << "\red You are displaced by a strange force!"
|
||||
|
||||
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(3, 0, get_turf(M))
|
||||
sparks.start()
|
||||
if(M.buckled)
|
||||
M.buckled.unbuckle()
|
||||
M.loc = pick(randomturfs)
|
||||
sparks = new /datum/effect/effect/system/spark_spread()
|
||||
sparks.set_up(3, 0, get_turf(M))
|
||||
sparks.start()
|
||||
@@ -1,150 +0,0 @@
|
||||
|
||||
/obj/machinery/artifact_harvester
|
||||
name = "Anomaly Power Collector"
|
||||
icon = 'virology.dmi'
|
||||
icon_state = "incubator" //incubator_on
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/harvesting = 0
|
||||
var/obj/item/weapon/anobattery/inserted_battery
|
||||
var/obj/machinery/artifact/cur_artifact
|
||||
var/obj/machinery/analyser_pad/owned_pad = null
|
||||
|
||||
/obj/machinery/artifact_harvester/New()
|
||||
..()
|
||||
spawn(10)
|
||||
owned_pad = locate() in orange(1, src)
|
||||
|
||||
/obj/machinery/artifact_harvester/attackby(var/obj/I as obj, var/mob/user as mob)
|
||||
if(istype(I,/obj/item/weapon/anobattery))
|
||||
if(!inserted_battery)
|
||||
user << "You insert the battery."
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
src.inserted_battery = I
|
||||
return
|
||||
else
|
||||
return..()
|
||||
|
||||
/obj/machinery/artifact_harvester/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
use_power(350)
|
||||
|
||||
if(harvesting)
|
||||
use_power(250)
|
||||
inserted_battery.stored_charge += 10
|
||||
if(inserted_battery.stored_charge >= inserted_battery.capacity)
|
||||
inserted_battery.stored_charge = inserted_battery.capacity
|
||||
harvesting = 0
|
||||
cur_artifact.anchored = 0
|
||||
cur_artifact.being_used = 0
|
||||
src.visible_message("<b>[name]</b> states, \"Battery is full.\"")
|
||||
icon_state = "incubator"
|
||||
return
|
||||
|
||||
/obj/machinery/artifact_harvester/interact(var/mob/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
user.machine = src
|
||||
var/dat = "<B>Artifact Power Harvester</B><BR>"
|
||||
dat += "<HR><BR>"
|
||||
//
|
||||
if(owned_pad)
|
||||
if(harvesting)
|
||||
dat += "Please wait. Harvesting in progress ([(inserted_battery.stored_charge/inserted_battery.capacity)*100]%).<br>"
|
||||
dat += "<A href='?src=\ref[src];stopharvest=1'>Halt early</A><BR>"
|
||||
else
|
||||
if(inserted_battery)
|
||||
dat += "<b>[inserted_battery.name]</b> inserted, charge level: [inserted_battery.stored_charge]/[inserted_battery.capacity] ([(inserted_battery.stored_charge/inserted_battery.capacity)*100]%)<BR>"
|
||||
dat += "<b>Energy signature ID:</b>[inserted_battery.battery_effect.artifact_id == "" ? "???" : "[inserted_battery.battery_effect.artifact_id]"]<BR>"
|
||||
dat += "<A href='?src=\ref[src];ejectbattery=1'>Eject battery</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];drainbattery=1'>Drain battery of all charge</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];harvest=1'>Begin harvesting</a><BR>"
|
||||
|
||||
else
|
||||
dat += "No battery inserted.<BR>"
|
||||
else
|
||||
dat += "<B><font color=red>Unable to locate analysis pad.</font><BR></b>"
|
||||
//
|
||||
dat += "<HR>"
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>Refresh</A> <A href='?src=\ref[src];close=1'>Close<BR>"
|
||||
user << browse(dat, "window=artharvester;size=450x500")
|
||||
onclose(user, "artharvester")
|
||||
|
||||
/obj/machinery/artifact_harvester/Topic(href, href_list)
|
||||
|
||||
if (href_list["harvest"])
|
||||
//locate artifact on analysis pad
|
||||
cur_artifact = null
|
||||
var/articount = 0
|
||||
var/obj/machinery/artifact/analysed
|
||||
for(var/obj/machinery/artifact/A in get_turf(owned_pad))
|
||||
analysed = A
|
||||
articount++
|
||||
|
||||
var/mundane = 0
|
||||
for(var/obj/O in get_turf(owned_pad))
|
||||
if(!istype(O, /obj/machinery/artifact) && !istype(O, /obj/machinery/analyser_pad))
|
||||
mundane++
|
||||
break
|
||||
for(var/mob/O in get_turf(owned_pad))
|
||||
if(!istype(O, /obj/machinery/artifact))
|
||||
mundane++
|
||||
break
|
||||
|
||||
if(articount == 1 && !mundane)
|
||||
cur_artifact = analysed
|
||||
//check to see if the battery is compatible
|
||||
if(inserted_battery)
|
||||
if(inserted_battery.battery_effect.artifact_id == cur_artifact.my_effect.artifact_id || inserted_battery.stored_charge == 0)
|
||||
harvesting = 1
|
||||
cur_artifact.anchored = 1
|
||||
cur_artifact.being_used = 1
|
||||
icon_state = "incubator_on"
|
||||
var/message = "<b>[src]</b> states, \"Beginning artifact energy harvesting.\""
|
||||
src.visible_message(message, message)
|
||||
//
|
||||
inserted_battery.battery_effect = cur_artifact.my_effect
|
||||
else
|
||||
var/message = "<b>[src]</b> states, \"Cannot harvest. Incompatible energy signatures detected.\""
|
||||
src.visible_message(message, message)
|
||||
else if(cur_artifact)
|
||||
var/message = "<b>[src]</b> states, \"Cannot harvest. No battery inserted.\""
|
||||
src.visible_message(message, message)
|
||||
else if(articount > 1 || mundane)
|
||||
var/message = "<b>[src]</b> states, \"Cannot harvest. Error isolating energy signature.\""
|
||||
src.visible_message(message, message)
|
||||
else if(!articount)
|
||||
var/message = "<b>[src]</b> states, \"Cannot harvest. No noteworthy energy signature isolated.\""
|
||||
src.visible_message(message, message)
|
||||
else if (cur_artifact.being_used)
|
||||
var/message = "<b>[src]</b> states, \"Cannot harvest. Too much interferance from energy scan.\""
|
||||
src.visible_message(message, message)
|
||||
|
||||
if (href_list["stopharvest"])
|
||||
if(harvesting)
|
||||
harvesting = 0
|
||||
cur_artifact.anchored = 0
|
||||
cur_artifact.being_used = 0
|
||||
src.visible_message("<b>[name]</b> states, \"Harvesting interrupted.\"")
|
||||
icon_state = "incubator"
|
||||
|
||||
|
||||
if (href_list["ejectbattery"])
|
||||
src.inserted_battery.loc = src.loc
|
||||
src.inserted_battery = null
|
||||
|
||||
if (href_list["drainbattery"])
|
||||
use_power(100)
|
||||
src.inserted_battery.battery_effect.artifact_id = ""
|
||||
src.inserted_battery.stored_charge = 0
|
||||
var/message = "<b>[src]</b> states, \"Battery drained of all charge.\""
|
||||
src.visible_message(message, message)
|
||||
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=artharvester")
|
||||
usr.machine = null
|
||||
|
||||
src.updateDialog()
|
||||
return
|
||||
@@ -1,67 +0,0 @@
|
||||
|
||||
/obj/item/clothing/suit/bio_suit/anomaly
|
||||
name = "Anomaly Suit"
|
||||
desc = "A sealed bio suit capable of resisting exotic alien energies and low pressure environments."
|
||||
icon_state = "engspace_suit"
|
||||
item_state = "engspace_suit"
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen)
|
||||
|
||||
/obj/item/clothing/head/bio_hood/anomaly
|
||||
name = "Anomaly Hood"
|
||||
desc = "A sealed bio hood capable of resisting exotic alien energies and low pressure environments."
|
||||
icon_state = "engspace_helmet"
|
||||
item_state = "engspace_helmet"
|
||||
|
||||
/obj/structure/noticeboard/anomaly/New()
|
||||
notices = 5
|
||||
icon_state = "nboard05"
|
||||
|
||||
//add some memos
|
||||
var/obj/item/weapon/paper/P = new()
|
||||
P.name = "Memo RE: proper analysis procedure"
|
||||
P.info = "Rose,<br>activate <i>then</i> analyse the anomalies, your results will come so much quicker. Remember to employ basic quasi-elemental forces such as heat, energy, force and various chemical mixes - who knows why those ancient aliens made such obscure activation indices.<br><br>And don't forget your suit this time, I can't afford to have any researchers out of commision for as long as that again!.<br>Ward"
|
||||
P.stamped = list(/obj/item/weapon/stamp/rd)
|
||||
P.overlays = list("paper_stamped_rd")
|
||||
src.contents += P
|
||||
|
||||
P = new()
|
||||
P.name = "Memo RE: materials gathering"
|
||||
P.info = "Corasang,<br>the hands-on approach to gathering our samples may very well be slow at times, but it's safer than allowing the blundering miners to roll willy-nilly over our dig sites in their mechs, destroying everything in the process. And don't forget the escavation tools on your way out there!<br>- R.W"
|
||||
P.stamped = list(/obj/item/weapon/stamp/rd)
|
||||
P.overlays = list("paper_stamped_rd")
|
||||
src.contents += P
|
||||
|
||||
P = new()
|
||||
P.name = "Memo RE: ethical quandaries"
|
||||
P.info = "Darion-<br><br>I don't care what his rank is, our business is that of science and knowledge - questions of moral application do not come into this. Sure, so there are those who would employ the energy-wave particles my modified device has managed to abscond for their own personal gain, but I can hardly see the practical benefits of some of those things our benefactors left behind. Ward--"
|
||||
P.stamped = list(/obj/item/weapon/stamp/rd)
|
||||
P.overlays = list("paper_stamped_rd")
|
||||
src.contents += P
|
||||
|
||||
P = new()
|
||||
P.name = "READ ME! Before you people destroy any more samples"
|
||||
P.info = "how many times do i have to tell you people, these xeno-arch samples are del-i-cate, and should be handled so! careful application of a focussed, ceoncentrated heat or some corrosive liquids should clear away the extraneous carbon matter, while application of an energy beam will most decidedly destroy it entirely! W, <b>the one who signs your paychecks</b>"
|
||||
P.stamped = list(/obj/item/weapon/stamp/rd)
|
||||
P.overlays = list("paper_stamped_rd")
|
||||
src.contents += P
|
||||
|
||||
P = new()
|
||||
P.name = "Reminder regarding the anomalous material suits"
|
||||
P.info = "Do you people think the anomaly suits are cheap to come by? I'm about a hair trigger away from instituting a log book for the damn things. Only wear them if you're going out for a dig, and for god's sake don't go tramping around the station in them unless you're field testing something, R"
|
||||
P.stamped = list(/obj/item/weapon/stamp/rd)
|
||||
P.overlays = list("paper_stamped_rd")
|
||||
src.contents += P
|
||||
|
||||
//Anomaly
|
||||
|
||||
/area/anomaly
|
||||
icon_state = "anomaly"
|
||||
|
||||
/area/anomaly/hallway
|
||||
name = "Anomaly Hallway"
|
||||
|
||||
/area/anomaly/lab
|
||||
name = "Anomaly Lab"
|
||||
|
||||
/area/anomaly/outpost
|
||||
name = "Research Outpost"
|
||||
@@ -1,144 +0,0 @@
|
||||
|
||||
/obj/item/weapon/anobattery
|
||||
name = "Anomaly power battery"
|
||||
icon = 'anomaly.dmi'
|
||||
icon_state = "anobattery0"
|
||||
var/datum/artifact_effect/battery_effect
|
||||
var/capacity = 200
|
||||
var/stored_charge = 0
|
||||
|
||||
/obj/item/weapon/anobattery/New()
|
||||
battery_effect = new()
|
||||
|
||||
/obj/item/weapon/anobattery/proc/UpdateSprite()
|
||||
var/p = (stored_charge/capacity)*100
|
||||
icon_state = "anobattery[round(p,25)]"
|
||||
|
||||
/obj/item/weapon/anodevice
|
||||
name = "Anomaly power utilizer"
|
||||
icon = 'anomaly.dmi'
|
||||
icon_state = "anodev"
|
||||
var/cooldown = 0
|
||||
var/activated = 0
|
||||
var/time = 50
|
||||
var/obj/item/weapon/anobattery/inserted_battery
|
||||
|
||||
/obj/item/weapon/anodevice/New()
|
||||
spawn(10)
|
||||
pulse()
|
||||
|
||||
/obj/item/weapon/anodevice/proc/UpdateSprite()
|
||||
if(!inserted_battery)
|
||||
icon_state = "anodev"
|
||||
return
|
||||
var/p = (inserted_battery.stored_charge/inserted_battery.capacity)*100
|
||||
var/s = round(p,25)
|
||||
icon_state = "anodev[s]"
|
||||
|
||||
/obj/item/weapon/anodevice/interact(var/mob/user)
|
||||
user.machine = src
|
||||
var/dat = "<b>Anomalous Materials Energy Utiliser</b><br>"
|
||||
if(activated)
|
||||
dat += "Device active, stand by.<BR>"
|
||||
else if(cooldown)
|
||||
dat += "Cooldown in progress, please wait.<BR>"
|
||||
else
|
||||
if(!inserted_battery)
|
||||
dat += "Please insert battery<BR>"
|
||||
else
|
||||
dat += "[inserted_battery] inserted, anomaly ID: [inserted_battery.battery_effect.artifact_id == "" ? "???" : "[inserted_battery.battery_effect.artifact_id]"]<BR>"
|
||||
dat += "<b>Total Power:</b> [inserted_battery.stored_charge]/[inserted_battery.capacity]<BR><BR>"
|
||||
dat += "<b>Timed activation:</b> <A href='?src=\ref[src];neg_changetime_max=-100'>--</a> <A href='?src=\ref[src];neg_changetime=-10'>-</a> [time >= 1000 ? "[time/10]" : time >= 100 ? " [time/10]" : " [time/10]" ] <A href='?src=\ref[src];changetime=10'>+</a> <A href='?src=\ref[src];changetime_max=100'>++</a><BR>"
|
||||
if(cooldown && !activated)
|
||||
dat += "<font color=red>Cooldown in progress.</font><BR>"
|
||||
else if(activated)
|
||||
dat += "<A href='?src=\ref[src];stoptimer=1'>Stop timer</a><BR>"
|
||||
else
|
||||
dat += "<A href='?src=\ref[src];starttimer=1'>Start timer</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];ejectbattery=1'>Eject battery</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>Refresh</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close</a><BR>"
|
||||
|
||||
user << browse(dat, "window=anodevice;size=400x500")
|
||||
onclose(user, "anodevice")
|
||||
return
|
||||
|
||||
/obj/item/weapon/anodevice/attackby(var/obj/I as obj, var/mob/user as mob)
|
||||
if(istype(I, /obj/item/weapon/anobattery))
|
||||
if(!inserted_battery)
|
||||
user << "\blue You insert the battery."
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
inserted_battery = I
|
||||
UpdateSprite()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/anodevice/attack_self(var/mob/user as mob)
|
||||
return src.interact(user)
|
||||
|
||||
/obj/item/weapon/anodevice/proc/pulse()
|
||||
if(activated)
|
||||
if(time <= 0 || !inserted_battery)
|
||||
time = 0
|
||||
activated = 0
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("\icon[src]\blue The utiliser device buzzes.", "\icon[src]\blue You hear something buzz.")
|
||||
else
|
||||
inserted_battery.battery_effect.DoEffect(src)
|
||||
time -= 10
|
||||
inserted_battery.stored_charge -= 10 + rand(-1,1)
|
||||
cooldown += 10
|
||||
else if(cooldown > 0)
|
||||
cooldown -= 10
|
||||
if(cooldown <= 0)
|
||||
cooldown = 0
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("\icon[src]\blue The utiliser device chimes.", "\icon[src]\blue You hear something chime.")
|
||||
|
||||
spawn(10)
|
||||
pulse()
|
||||
|
||||
/obj/item/weapon/anodevice/Topic(href, href_list)
|
||||
|
||||
if(href_list["neg_changetime_max"])
|
||||
time += -100
|
||||
if(time > inserted_battery.capacity)
|
||||
time = inserted_battery.capacity
|
||||
else if (time < 0)
|
||||
time = 0
|
||||
if(href_list["neg_changetime"])
|
||||
time += -10
|
||||
if(time > inserted_battery.capacity)
|
||||
time = inserted_battery.capacity
|
||||
else if (time < 0)
|
||||
time = 0
|
||||
if(href_list["changetime"])
|
||||
time += 10
|
||||
if(time > inserted_battery.capacity)
|
||||
time = inserted_battery.capacity
|
||||
else if (time < 0)
|
||||
time = 0
|
||||
if(href_list["changetime_max"])
|
||||
time += 100
|
||||
if(time > inserted_battery.capacity)
|
||||
time = inserted_battery.capacity
|
||||
else if (time < 0)
|
||||
time = 0
|
||||
|
||||
if(href_list["stoptimer"])
|
||||
activated = 0
|
||||
|
||||
if(href_list["starttimer"])
|
||||
activated = 1
|
||||
|
||||
if(href_list["ejectbattery"])
|
||||
inserted_battery.loc = get_turf(src)
|
||||
inserted_battery = null
|
||||
UpdateSprite()
|
||||
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=anodevice")
|
||||
usr.machine = null
|
||||
else if(usr)
|
||||
src.interact(usr)
|
||||
166
code/modules/research/xenoarchaeology/chemistry.dm
Normal file
166
code/modules/research/xenoarchaeology/chemistry.dm
Normal file
@@ -0,0 +1,166 @@
|
||||
|
||||
//chemistry stuff here so that it can be easily viewed/modified
|
||||
datum
|
||||
reagent
|
||||
tungsten
|
||||
name = "Tungsten"
|
||||
id = "tungsten"
|
||||
description = "A chemical element, and a strong oxidising agent."
|
||||
reagent_state = SOLID
|
||||
color = "#808080" // rgb: 128, 128, 128
|
||||
//todo: make this silvery grey
|
||||
|
||||
lithiumsodiumtungstate
|
||||
name = "Lithium Sodium Tungstate"
|
||||
id = "lithiumsodiumtungstate"
|
||||
description = "A reducing agent for geological compounds."
|
||||
reagent_state = LIQUID
|
||||
color = "#808080" // rgb: 128, 128, 128
|
||||
//todo: make this silvery grey
|
||||
|
||||
ground_rock
|
||||
name = "Ground Rock"
|
||||
id = "ground_rock"
|
||||
description = "A fine dust made of ground up rock."
|
||||
reagent_state = SOLID
|
||||
color = "#C81040" //rgb: 200, 16, 64
|
||||
//todo: make this brown
|
||||
|
||||
density_separated_sample
|
||||
name = "Density separated sample"
|
||||
id = "density_separated_sample"
|
||||
description = "A watery paste used in chemical analysis, there are some chunks floating in it."
|
||||
reagent_state = LIQUID
|
||||
color = "#C81040" //rgb: 200, 16, 64
|
||||
//todo: make this browny-white
|
||||
|
||||
analysis_sample
|
||||
name = "Analysis liquid"
|
||||
id = "analysis_sample"
|
||||
description = "A watery paste used in chemical analysis."
|
||||
reagent_state = LIQUID
|
||||
color = "#C81040" //rgb: 200, 16, 64
|
||||
//todo: make this white
|
||||
|
||||
chemical_waste
|
||||
name = "Chemical Waste"
|
||||
id = "chemical_waste"
|
||||
description = "A viscous, toxic liquid left over from many chemical processes."
|
||||
reagent_state = LIQUID
|
||||
color = "#C81040" //rgb: 200, 16, 64
|
||||
//todo: make this fluoro/bright green
|
||||
|
||||
datum
|
||||
chemical_reaction
|
||||
lithiumsodiumtungstate //LiNa2WO4, not the easiest chem to mix
|
||||
name = "Lithium Sodium Tungstate"
|
||||
id = "lithiumsodiumtungstate"
|
||||
result = "lithiumsodiumtungstate"
|
||||
required_reagents = list("lithium" = 1, "sodium" = 2, "tungsten" = 1, "oxygen" = 4)
|
||||
result_amount = 8
|
||||
|
||||
density_separated_liquid
|
||||
name = "Density separated sample"
|
||||
id = "density_separated_sample"
|
||||
result = "density_separated_sample"
|
||||
secondary_results = list("chemical_waste" = 1)
|
||||
required_reagents = list("ground_rock" = 1, "lithiumsodiumtungstate" = 2)
|
||||
result_amount = 2
|
||||
|
||||
analysis_liquid
|
||||
name = "Analysis sample"
|
||||
id = "analysis_sample"
|
||||
result = "analysis_sample"
|
||||
secondary_results = list("chemical_waste" = 1)
|
||||
required_reagents = list("density_separated_sample" = 5)
|
||||
result_amount = 4
|
||||
requires_heating = 1
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/solution_tray
|
||||
name = "solution tray"
|
||||
desc = "A small, open-topped glass container for delicate research samples. It sports a re-useable strip for labelling with a pen."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "solution_tray"
|
||||
m_amt = 0
|
||||
g_amt = 5
|
||||
w_class = 1.0
|
||||
amount_per_transfer_from_this = 1
|
||||
possible_transfer_amounts = list(1, 2)
|
||||
volume = 2
|
||||
flags = FPRINT | OPENCONTAINER
|
||||
|
||||
obj/item/weapon/reagent_containers/glass/solution_tray/attackby(obj/item/weapon/W as obj, mob/living/user as mob)
|
||||
if(istype(W, /obj/item/weapon/pen))
|
||||
var/new_label = input("What should the new label be?","Label solution tray")
|
||||
if(new_label)
|
||||
name = "solution tray ([new_label])"
|
||||
user << "\blue You write on the label of the solution tray."
|
||||
else
|
||||
..(W, user)
|
||||
|
||||
/obj/item/weapon/storage/box/solution_trays
|
||||
name = "solution tray box"
|
||||
icon_state = "solution_trays"
|
||||
|
||||
New()
|
||||
..()
|
||||
new /obj/item/weapon/reagent_containers/glass/solution_tray( src )
|
||||
new /obj/item/weapon/reagent_containers/glass/solution_tray( src )
|
||||
new /obj/item/weapon/reagent_containers/glass/solution_tray( src )
|
||||
new /obj/item/weapon/reagent_containers/glass/solution_tray( src )
|
||||
new /obj/item/weapon/reagent_containers/glass/solution_tray( src )
|
||||
new /obj/item/weapon/reagent_containers/glass/solution_tray( src )
|
||||
new /obj/item/weapon/reagent_containers/glass/solution_tray( src )
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/tungsten
|
||||
name = "beaker 'tungsten'"
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("tungsten",50)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/oxygen
|
||||
name = "beaker 'oxygen'"
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("oxygen",50)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/sodium
|
||||
name = "beaker 'sodium'"
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("sodium",50)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/lithium
|
||||
name = "beaker 'lithium'"
|
||||
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("lithium",50)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/water
|
||||
name = "beaker 'water'"
|
||||
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("water",50)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/water
|
||||
name = "beaker 'water'"
|
||||
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("water",50)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/fuel
|
||||
name = "beaker 'fuel'"
|
||||
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("fuel",50)
|
||||
update_icon()
|
||||
@@ -1,69 +0,0 @@
|
||||
//device to take core samples from mineral turfs - used for various types of analysis
|
||||
|
||||
/obj/item/weapon/storage/samplebag
|
||||
name = "sample bag"
|
||||
desc = "A geological sample bag."
|
||||
icon_state = "evidenceobj"
|
||||
w_class = 1
|
||||
max_w_class = 1
|
||||
max_combined_w_class = 7
|
||||
storage_slots = 7
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
/turf/simulated/mineral
|
||||
var/datum/geosample/geological_data
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/device/core_sampler
|
||||
name = "core sampler"
|
||||
desc = "Used to extract geological core samples."
|
||||
icon = 'device.dmi'
|
||||
icon_state = "sampler0"
|
||||
item_state = "screwdriver_brown"
|
||||
w_class = 1.0
|
||||
flags = FPRINT | TABLEPASS
|
||||
//slot_flags = SLOT_BELT
|
||||
var/sampled_turf = ""
|
||||
var/num_stored_bags = 10
|
||||
var/obj/item/weapon/storage/samplebag/filled_bag
|
||||
|
||||
/obj/item/device/core_sampler/attack_hand(var/mob/user)
|
||||
user << "\blue The core sampler is [sampled_turf ? "full" : "empty"], and has [num_stored_bags] sample bag[num_stored_bags != 1] remaining."
|
||||
|
||||
/obj/item/device/core_sampler/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/weapon/storage/samplebag))
|
||||
if(num_stored_bags < 10)
|
||||
del(W)
|
||||
num_stored_bags += 1
|
||||
user << "\blue You insert the sample bag into the core sampler."
|
||||
else
|
||||
user << "\red The core sampler can not fit any more sample bags!"
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/device/core_sampler/proc/sample_turf(var/turf/simulated/mineral/T, var/mob/user as mob)
|
||||
if(filled_bag)
|
||||
user << "\red The core sampler is full!"
|
||||
else if(num_stored_bags < 1)
|
||||
user << "\red The core sampler is out of sample bags!"
|
||||
else
|
||||
filled_bag = new /obj/item/weapon/storage/samplebag(src)
|
||||
icon_state = "sampler1"
|
||||
|
||||
for(var/i=0, i<7, i++)
|
||||
var/obj/item/weapon/rocksliver/R = new(filled_bag)
|
||||
R.source_rock = T.type
|
||||
R.geological_data = T.geological_data
|
||||
|
||||
user << "\blue You take a core sample of the [T]."
|
||||
|
||||
/obj/item/device/core_sampler/examine()
|
||||
if (!( usr ))
|
||||
return
|
||||
if(get_dist(src, usr) < 2)
|
||||
usr << "That's \a [src]."
|
||||
usr << "\blue Used to extract geological core samples - this one is [sampled_turf ? "full" : "empty"], and has [num_stored_bags] sample bag[num_stored_bags != 1] remaining."
|
||||
else
|
||||
return ..()
|
||||
@@ -1,364 +0,0 @@
|
||||
//original code and idea from Alfie275 (luna) and ISaidNo (goon) - with thanks
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// samples
|
||||
|
||||
/obj/item/weapon/rocksliver
|
||||
name = "rock sliver"
|
||||
desc = "It looks extremely delicate."
|
||||
icon = 'mining.dmi'
|
||||
icon_state = "sliver0" //0-4
|
||||
//item_state = "electronic"
|
||||
var/source_rock = "/turf/simulated/mineral/archaeo"
|
||||
item_state = ""
|
||||
var/datum/geosample/geological_data
|
||||
|
||||
/obj/item/weapon/rocksliver/New()
|
||||
icon_state = "sliver[rand(0,4)]"
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// strange rocks
|
||||
|
||||
/obj/item/weapon/ore/strangerock
|
||||
var/datum/geosample/geological_data
|
||||
var/source_rock = "/turf/simulated/mineral"
|
||||
|
||||
/obj/item/weapon/ore/strangerock/New()
|
||||
..()
|
||||
//var/datum/reagents/r = new/datum/reagents(50)
|
||||
//src.reagents = r
|
||||
if(rand(3))
|
||||
method = 0 // 0 = fire, 1+ = acid
|
||||
else
|
||||
method = 0 //currently always fire
|
||||
// method = 1 //removed due to acid melting strange rocks to gooey grey -Mij
|
||||
inside = pick(150;"", 50;"/obj/item/weapon/crystal", 25;"/obj/item/weapon/talkingcrystal", "/obj/item/weapon/fossil/base")
|
||||
|
||||
/obj/item/weapon/ore/strangerock/bullet_act(var/obj/item/projectile/P)
|
||||
|
||||
/obj/item/weapon/ore/strangerock/ex_act(var/severity)
|
||||
src.visible_message("The [src] crumbles away, leaving some dust and gravel behind.")
|
||||
|
||||
/obj/item/weapon/ore/strangerock/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
|
||||
if(istype(W,/obj/item/weapon/weldingtool/))
|
||||
var/obj/item/weapon/weldingtool/w = W
|
||||
if(w.isOn() && (w.get_fuel() > 3))
|
||||
if(!src.method) //0 = fire, 1+ = acid
|
||||
if(inside)
|
||||
var/obj/A = new src.inside(get_turf(src))
|
||||
for(var/mob/M in viewers(world.view, user))
|
||||
M.show_message("\blue The rock burns away revealing a [A.name].",1)
|
||||
else
|
||||
for(var/mob/M in viewers(world.view, user))
|
||||
M.show_message("\blue The rock burns away into nothing.",1)
|
||||
del src
|
||||
else
|
||||
for(var/mob/M in viewers(world.view, user))
|
||||
M.show_message("\blue A few sparks fly off the rock, but otherwise nothing else happens.",1)
|
||||
w.remove_fuel(4)
|
||||
|
||||
else if(istype(W,/obj/item/device/core_sampler/))
|
||||
var/obj/item/device/core_sampler/S = W
|
||||
if(S.filled_bag)
|
||||
user << "\red The core sampler is full!"
|
||||
else if(S.num_stored_bags < 1)
|
||||
user << "\red The core sampler is out of sample bags!"
|
||||
else
|
||||
S.filled_bag = new /obj/item/weapon/storage/samplebag(S)
|
||||
S.icon_state = "sampler1"
|
||||
|
||||
for(var/i=0, i<7, i++)
|
||||
var/obj/item/weapon/rocksliver/R = new /obj/item/weapon/rocksliver(S.filled_bag)
|
||||
R.source_rock = src.source_rock
|
||||
R.geological_data = src.geological_data
|
||||
user << "\blue You take a core sample of the [src]."
|
||||
else
|
||||
..()
|
||||
|
||||
/*Code does not work, likely due to removal/change of acid_act proc
|
||||
//Strange rocks currently melt to gooey grey w/ acid application (see reactions)
|
||||
//will fix when I get a chance to fiddle with it -Mij
|
||||
/obj/item/weapon/ore/strangerock/acid_act(var/datum/reagent/R)
|
||||
if(src.method)
|
||||
if(inside)
|
||||
var/obj/A = new src.inside(get_turf(src))
|
||||
for(var/mob/M in viewers(world.view, get_turf(src)))
|
||||
M.show_message("\blue The rock fizzes away revealing a [A.name].",1)
|
||||
else
|
||||
for(var/mob/M in viewers(world.view, get_turf(src)))
|
||||
M.show_message("\blue The rock fizzes away into nothing.",1)
|
||||
del src
|
||||
else
|
||||
for(var/mob/M in viewers(world.view, get_turf(src)))
|
||||
M.show_message("\blue The acid splashes harmlessly off the rock, nothing else interesting happens.",1)
|
||||
return 1
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// crystals
|
||||
|
||||
/obj/item/weapon/crystal
|
||||
name = "Crystal"
|
||||
icon = 'mining.dmi'
|
||||
icon_state = "crystal"
|
||||
|
||||
/obj/item/weapon/crystal/bullet_act(var/obj/item/projectile/P)
|
||||
if(istype(P,/obj/item/projectile/beam/emitter))
|
||||
switch(rand(0,3))
|
||||
if(0)
|
||||
var/obj/item/projectile/beam/emitter/A = new /obj/item/projectile/beam/emitter( src.loc )
|
||||
A.dir = 1
|
||||
A.yo = 20
|
||||
A.xo = 0
|
||||
if(0)
|
||||
var/obj/item/projectile/beam/emitter/A = new /obj/item/projectile/beam/emitter( src.loc )
|
||||
A.dir = 2
|
||||
A.yo = -20
|
||||
A.xo = 0
|
||||
if(0)
|
||||
var/obj/item/projectile/beam/emitter/A = new /obj/item/projectile/beam/emitter( src.loc )
|
||||
A.dir = 4
|
||||
A.yo = 0
|
||||
A.xo = 20
|
||||
if(0)
|
||||
var/obj/item/projectile/beam/emitter/A = new /obj/item/projectile/beam/emitter( src.loc )
|
||||
A.dir = 8
|
||||
A.yo = 0
|
||||
A.xo = -20
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/weapon/talkingcrystal
|
||||
name = "Crystal"
|
||||
icon = 'mining.dmi'
|
||||
icon_state = "crystal2"
|
||||
var/list/list/words = list()
|
||||
var/lastsaid
|
||||
|
||||
/obj/item/weapon/talkingcrystal/New()
|
||||
spawn(100)
|
||||
process()
|
||||
|
||||
/obj/item/weapon/talkingcrystal/bullet_act(var/obj/item/projectile/P)
|
||||
if(istype(P,/obj/item/projectile/beam))
|
||||
switch(rand(0,3))
|
||||
if(0)
|
||||
var/obj/item/projectile/beam/A = new /obj/item/projectile/beam( src.loc )
|
||||
A.dir = pick(alldirs)
|
||||
A.yo = 20
|
||||
A.xo = 0
|
||||
if(0)
|
||||
var/obj/item/projectile/beam/A = new /obj/item/projectile/beam( src.loc )
|
||||
A.dir = pick(alldirs)
|
||||
A.yo = -20
|
||||
A.xo = 0
|
||||
if(0)
|
||||
var/obj/item/projectile/beam/A = new /obj/item/projectile/beam( src.loc )
|
||||
A.dir = pick(alldirs)
|
||||
A.yo = 0
|
||||
A.xo = 20
|
||||
if(0)
|
||||
var/obj/item/projectile/beam/A = new /obj/item/projectile/beam( src.loc )
|
||||
A.dir = pick(alldirs)
|
||||
A.yo = 0
|
||||
A.xo = -20
|
||||
var/word = pick("pain","hurt","masochism","sadist","rage","repressed","ouch","evil","void","kill","destroy")
|
||||
SaySomething(word)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/weapon/talkingcrystal/proc/catchMessage(var/msg, var/mob/source)
|
||||
var/list/seperate = list()
|
||||
if(findtext(msg,"(("))
|
||||
return
|
||||
else if(findtext(msg,"))"))
|
||||
return
|
||||
else if(findtext(msg," ")==0)
|
||||
return
|
||||
else
|
||||
/*var/l = lentext(msg)
|
||||
if(findtext(msg," ",l,l+1)==0)
|
||||
msg+=" "*/
|
||||
seperate = stringsplit(msg, " ")
|
||||
|
||||
var/addressing_crystal = 0
|
||||
if("crystal" in seperate || "gem" in seperate)
|
||||
addressing_crystal = 1
|
||||
|
||||
for(var/Xa = 1,Xa<seperate.len,Xa++)
|
||||
var/next = Xa + 1
|
||||
if(words.len > 20 + rand(10,20))
|
||||
words.Remove(words[1])
|
||||
if(!words["[lowertext(seperate[Xa])]"])
|
||||
words["[lowertext(seperate[Xa])]"] = list()
|
||||
var/list/w = words["[lowertext(seperate[Xa])]"]
|
||||
if(w)
|
||||
w.Add("[lowertext(seperate[next])]")
|
||||
//world << "Adding [lowertext(seperate[next])] to [lowertext(seperate[Xa])]"
|
||||
|
||||
for(var/mob/O in viewers(src))
|
||||
O.show_message("\blue The crystal hums for bit then stops...", 1)
|
||||
if(!rand(0, 5 - addressing_crystal * 3))
|
||||
spawn(2) SaySomething(pick(seperate))
|
||||
|
||||
/obj/item/weapon/talkingcrystal/proc/debug()
|
||||
//set src in view()
|
||||
for(var/v in words)
|
||||
world << "[uppertext(v)]"
|
||||
var/list/d = words["[v]"]
|
||||
for(var/X in d)
|
||||
world << "[X]"
|
||||
|
||||
/obj/item/weapon/talkingcrystal/proc/SaySomething(var/word = null)
|
||||
|
||||
var/msg
|
||||
var/limit = rand(max(5,words.len/2))+3
|
||||
var/text
|
||||
if(!word)
|
||||
text = "[pick(words)]"
|
||||
else
|
||||
text = pick(stringsplit(word, " "))
|
||||
if(lentext(text)==1)
|
||||
text=uppertext(text)
|
||||
else
|
||||
var/cap = copytext(text,1,2)
|
||||
cap = uppertext(cap)
|
||||
cap += copytext(text,2,lentext(text)+1)
|
||||
text=cap
|
||||
var/q = 0
|
||||
msg+=text
|
||||
if(msg=="What" | msg == "Who" | msg == "How" | msg == "Why" | msg == "Are")
|
||||
q=1
|
||||
|
||||
text=lowertext(text)
|
||||
for(var/ya,ya <= limit,ya++)
|
||||
|
||||
if(words.Find("[text]"))
|
||||
var/list/w = words["[text]"]
|
||||
text=pick(w)
|
||||
else
|
||||
text = "[pick(words)]"
|
||||
msg+=" [text]"
|
||||
if(q)
|
||||
msg+="?"
|
||||
else
|
||||
if(rand(0,10))
|
||||
msg+="."
|
||||
else
|
||||
msg+="!"
|
||||
|
||||
var/list/listening = viewers(src)
|
||||
for(var/mob/M in world)
|
||||
if (!M.client)
|
||||
continue //skip monkeys and leavers
|
||||
if (istype(M, /mob/new_player))
|
||||
continue
|
||||
if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS)
|
||||
listening |= M
|
||||
|
||||
for(var/mob/M in listening)
|
||||
M << "<b>The crystal</b> reverberates, \blue\"[msg]\""
|
||||
lastsaid = world.timeofday + rand(300,800)
|
||||
|
||||
/obj/item/weapon/talkingcrystal/process()
|
||||
if(prob(25) && world.timeofday >= lastsaid && words.len >= 1)
|
||||
SaySomething()
|
||||
spawn(100)
|
||||
process()
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// fossils
|
||||
|
||||
/obj/item/weapon/fossil
|
||||
name = "Fossil"
|
||||
icon = 'fossil.dmi'
|
||||
icon_state = "bone"
|
||||
desc = "It's a fossil."
|
||||
|
||||
/obj/item/weapon/fossil/base/New()
|
||||
spawn(0)
|
||||
var/list/l = list("/obj/item/weapon/fossil/bone"=8,"/obj/item/weapon/fossil/skull"=2,
|
||||
"/obj/item/weapon/fossil/skull/horned"=2,"/obj/item/weapon/fossil/shell"=1)
|
||||
var/t = pickweight(l)
|
||||
new t(src.loc)
|
||||
del src
|
||||
|
||||
/obj/item/weapon/fossil/bone
|
||||
name = "Fossilised bone"
|
||||
icon_state = "bone"
|
||||
desc = "It's a fossilised bone."
|
||||
|
||||
/obj/item/weapon/fossil/shell
|
||||
name = "Fossilised shell"
|
||||
icon_state = "shell"
|
||||
desc = "It's a fossilised shell."
|
||||
|
||||
/obj/item/weapon/fossil/skull/horned
|
||||
icon_state = "hskull"
|
||||
desc = "It's a fossilised, horned skull."
|
||||
|
||||
/obj/item/weapon/fossil/skull
|
||||
name = "Fossilised skull"
|
||||
icon_state = "skull"
|
||||
desc = "It's a fossilised skull."
|
||||
|
||||
/obj/item/weapon/fossil/skull/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/weapon/fossil/bone))
|
||||
var/obj/o = new /obj/skeleton(get_turf(src))
|
||||
var/a = new /obj/item/weapon/fossil/bone
|
||||
var/b = new src.type
|
||||
o.contents.Add(a)
|
||||
o.contents.Add(b)
|
||||
del W
|
||||
del src
|
||||
|
||||
/obj/skeleton
|
||||
name = "Incomplete skeleton"
|
||||
icon = 'fossil.dmi'
|
||||
icon_state = "uskel"
|
||||
desc = "Incomplete skeleton."
|
||||
var/bnum = 1
|
||||
var/breq
|
||||
var/bstate = 0
|
||||
|
||||
/obj/skeleton/New()
|
||||
src.breq = rand(6)+3
|
||||
src.desc = "An incomplete skeleton, looks like it could use [src.breq-src.bnum] more bones."
|
||||
|
||||
/obj/skeleton/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/weapon/fossil/bone))
|
||||
if(!bstate)
|
||||
bnum++
|
||||
src.contents.Add(new/obj/item/weapon/fossil/bone)
|
||||
del W
|
||||
if(bnum==breq)
|
||||
usr = user
|
||||
icon_state = "skel"
|
||||
var/creaturename = input("Input a name for your discovery:","Name your discovery","Spaceosaurus")
|
||||
src.bstate = 1
|
||||
src.density = 1
|
||||
src.name = "[creaturename] skeleton"
|
||||
if(src.contents.Find(/obj/item/weapon/fossil/skull/horned))
|
||||
src.desc = "A creature made of [src.contents.len-1] assorted bones and a horned skull, the plaque reads [creaturename]."
|
||||
else
|
||||
src.desc = "A creature made of [src.contents.len-1] assorted bones and a skull, the plaque reads [creaturename]."
|
||||
else
|
||||
src.desc = "Incomplete skeleton, looks like it could use [src.breq-src.bnum] more bones."
|
||||
user << "Looks like it could use [src.breq-src.bnum] more bones."
|
||||
else
|
||||
..()
|
||||
else
|
||||
..()
|
||||
532
code/modules/research/xenoarchaeology/finds/finds.dm
Normal file
532
code/modules/research/xenoarchaeology/finds/finds.dm
Normal file
@@ -0,0 +1,532 @@
|
||||
//original code and idea from Alfie275 (luna era) and ISaidNo (goonservers) - with thanks
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Xenoarchaeological finds
|
||||
|
||||
/datum/find
|
||||
var/find_type = 0 //random according to the digsite type
|
||||
var/excavation_required = 0 //random 5-95%
|
||||
var/view_range = 20 //how close excavation has to come to show an overlay on the turf
|
||||
var/clearance_range = 3 //how close excavation has to come to extract the item
|
||||
//if excavation hits var/excavation_required exactly, it's contained find is extracted cleanly without the ore
|
||||
var/prob_delicate = 75 //probability it requires an active suspension field to not insta-crumble
|
||||
var/dissonance_spread = 1 //proportion of the tile that is affected by this find
|
||||
//used in conjunction with analysis machines to determine correct suspension field type
|
||||
|
||||
/datum/find/New(var/digsite, var/exc_req)
|
||||
excavation_required = exc_req
|
||||
find_type = get_random_find_type(digsite)
|
||||
clearance_range = rand(2,6)
|
||||
dissonance_spread = rand(1500,2500) / 100
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Strange rocks
|
||||
|
||||
//have all strange rocks be cleared away using welders for now
|
||||
/obj/item/weapon/ore/strangerock
|
||||
name = "Strange rock"
|
||||
desc = "Seems to have some unusal strata evident throughout it."
|
||||
icon = 'xenoarchaeology.dmi'
|
||||
icon_state = "strange"
|
||||
var/obj/item/weapon/inside
|
||||
var/method = 0// 0 = fire, 1 = brush, 2 = pick
|
||||
origin_tech = "materials=5"
|
||||
|
||||
/obj/item/weapon/ore/strangerock/New(loc, var/inside_item_type = 0)
|
||||
..(loc)
|
||||
|
||||
//method = rand(0,2)
|
||||
if(inside_item_type)
|
||||
inside = new/obj/item/weapon/archaeological_find(src, new_item_type = inside_item_type)
|
||||
if(!inside)
|
||||
inside = locate() in contents
|
||||
|
||||
/*/obj/item/weapon/ore/strangerock/ex_act(var/severity)
|
||||
if(severity && prob(30))
|
||||
src.visible_message("The [src] crumbles away, leaving some dust and gravel behind.")*/
|
||||
|
||||
/obj/item/weapon/ore/strangerock/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/weapon/weldingtool/))
|
||||
var/obj/item/weapon/weldingtool/w = W
|
||||
if(w.isOn())
|
||||
if(w.get_fuel() >= 4 && !src.method)
|
||||
if(inside)
|
||||
inside.loc = src.loc
|
||||
for(var/mob/M in viewers(world.view, user))
|
||||
M.show_message("<span class='info'>[src] burns away revealing [inside].</span>",1)
|
||||
else
|
||||
for(var/mob/M in viewers(world.view, user))
|
||||
M.show_message("<span class='info'>[src] burns away into nothing.</span>",1)
|
||||
del(src)
|
||||
w.remove_fuel(4)
|
||||
else
|
||||
for(var/mob/M in viewers(world.view, user))
|
||||
M.show_message("<span class='info'>A few sparks fly off [src], but nothing else happens.</span>",1)
|
||||
w.remove_fuel(1)
|
||||
return
|
||||
|
||||
else if(istype(W,/obj/item/device/core_sampler/))
|
||||
var/obj/item/device/core_sampler/S = W
|
||||
S.sample_item(src, user)
|
||||
return
|
||||
|
||||
..()
|
||||
if(prob(33))
|
||||
src.visible_message("<span class='warning'>[src] crumbles away, leaving some dust and gravel behind.</span>")
|
||||
del(src)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Archaeological finds
|
||||
|
||||
/obj/item/weapon/archaeological_find
|
||||
name = "object"
|
||||
icon = 'xenoarchaeology.dmi'
|
||||
icon_state = "ano01"
|
||||
var/find_type = 0
|
||||
|
||||
/obj/item/weapon/archaeological_find/New(loc, var/new_item_type)
|
||||
if(new_item_type)
|
||||
find_type = new_item_type
|
||||
else
|
||||
find_type = rand(1,34) //update this when you add new find types
|
||||
|
||||
var/item_type = "object"
|
||||
icon_state = "unknown[rand(1,4)]"
|
||||
var/additional_desc = ""
|
||||
var/obj/item/weapon/new_item
|
||||
var/source_material = ""
|
||||
var/apply_material_decorations = 1
|
||||
var/apply_image_decorations = 0
|
||||
var/material_descriptor = ""
|
||||
var/apply_prefix = 1
|
||||
if(prob(40))
|
||||
material_descriptor = pick("rusted ","dusty ","archaic ","fragile ")
|
||||
source_material = pick("cordite","quadrinium","steel","titanium","aluminium","ferritic-alloy","plasteel","duranium")
|
||||
|
||||
var/talkative = 0
|
||||
if(prob(5))
|
||||
talkative = 1
|
||||
|
||||
//for all items here:
|
||||
//icon_state
|
||||
//item_state
|
||||
switch(find_type)
|
||||
if(1)
|
||||
item_type = "bowl"
|
||||
new_item = new /obj/item/weapon/reagent_containers/glass(src.loc)
|
||||
new_item.icon = 'xenoarchaeology.dmi'
|
||||
new_item.icon_state = "bowl"
|
||||
apply_image_decorations = 1
|
||||
if(prob(20))
|
||||
additional_desc = "There appear to be [pick("dark","faintly glowing","pungent","bright")] [pick("red","purple","green","blue")] stains inside."
|
||||
if(2)
|
||||
item_type = "urn"
|
||||
new_item = new /obj/item/weapon/reagent_containers/glass(src.loc)
|
||||
new_item.icon = 'xenoarchaeology.dmi'
|
||||
new_item.icon_state = "urn"
|
||||
apply_image_decorations = 1
|
||||
if(prob(20))
|
||||
additional_desc = "It [pick("whispers faintly","makes a quiet roaring sound","whistles softly","thrums quietly","throbs")] if you put it to your ear."
|
||||
if(3)
|
||||
item_type = "[pick("fork","spoon","knife")]"
|
||||
if(prob(25))
|
||||
new_item = new /obj/item/weapon/kitchen/utensil/fork(src.loc)
|
||||
else if(prob(50))
|
||||
new_item = new /obj/item/weapon/kitchen/utensil/knife(src.loc)
|
||||
else
|
||||
new_item = new /obj/item/weapon/kitchen/utensil/spoon(src.loc)
|
||||
additional_desc = "[pick("It's like no [item_type] you've ever seen before",\
|
||||
"It's a mystery how anyone is supposed to eat with this",\
|
||||
"You wonder what the creator's mouth was shaped like")]."
|
||||
if(4)
|
||||
item_type = "statuette"
|
||||
icon_state = "statuette"
|
||||
additional_desc = "It depicts a [pick("small","ferocious","wild","pleasing","hulking")] \
|
||||
[pick("alien figure","rodent-like creature","reptilian alien","primate","unidentifiable object")] \
|
||||
[pick("performing unspeakable acts","posing heroically","in a feotal position","cheering","sobbing","making a plaintive gesture","making a rude gesture")]."
|
||||
if(5)
|
||||
item_type = "instrument"
|
||||
icon_state = "instrument"
|
||||
if(prob(30))
|
||||
apply_image_decorations = 1
|
||||
additional_desc = "[pick("You're not sure how anyone could have played this",\
|
||||
"You wonder how many mouths the creator had",\
|
||||
"You wonder what it sounds like",\
|
||||
"You wonder what kind of music was made with it")]."
|
||||
if(6)
|
||||
item_type = "[pick("bladed knife","serrated blade","sharp cutting implement")]"
|
||||
new_item = new /obj/item/weapon/kitchenknife(src.loc)
|
||||
additional_desc = "[pick("It doesn't look safe.",\
|
||||
"It looks wickedly jagged",\
|
||||
"There appear to be [pick("dark red","dark purple","dark green","dark blue")] stains along the edges")]."
|
||||
if(7)
|
||||
//assuming there are 10 types of coins
|
||||
var/chance = 10
|
||||
for(var/type in typesof(/obj/item/weapon/coin))
|
||||
if(prob(chance))
|
||||
new_item = new type(src.loc)
|
||||
break
|
||||
chance += 10
|
||||
|
||||
item_type = new_item.name
|
||||
apply_prefix = 0
|
||||
apply_material_decorations = 0
|
||||
apply_image_decorations = 1
|
||||
if(8)
|
||||
item_type = "handcuffs"
|
||||
new_item = new /obj/item/weapon/handcuffs(src.loc)
|
||||
additional_desc = "[pick("They appear to be for securing two things together","Looks kinky","Doesn't seem like a children's toy")]."
|
||||
if(9)
|
||||
item_type = "[pick("wicked","evil","byzantine","dangerous")] looking [pick("device","contraption","thing","trap")]"
|
||||
apply_prefix = 0
|
||||
new_item = new /obj/item/weapon/legcuffs/beartrap(src.loc)
|
||||
additional_desc = "[pick("It looks like it could take a limb off",\
|
||||
"Could be some kind of animal trap",\
|
||||
"There appear to be [pick("dark red","dark purple","dark green","dark blue")] stains along part of it")]."
|
||||
if(10)
|
||||
item_type = "[pick("cylinder","tank","chamber")]"
|
||||
new_item = new /obj/item/weapon/lighter(src.loc)
|
||||
additional_desc = "There is a tiny device attached."
|
||||
if(prob(30))
|
||||
apply_image_decorations = 1
|
||||
if(11)
|
||||
item_type = "box"
|
||||
new_item = new /obj/item/weapon/storage/box(src.loc)
|
||||
new_item.icon = 'xenoarchaeology.dmi'
|
||||
new_item.icon_state = "box"
|
||||
if(prob(30))
|
||||
apply_image_decorations = 1
|
||||
if(12)
|
||||
item_type = "[pick("cylinder","tank","chamber")]"
|
||||
if(prob(25))
|
||||
new_item = new /obj/item/weapon/tank/air(src.loc)
|
||||
else if(prob(50))
|
||||
new_item = new /obj/item/weapon/tank/anesthetic(src.loc)
|
||||
else
|
||||
new_item = new /obj/item/weapon/tank/plasma(src.loc)
|
||||
icon_state = pick("oxygen","oxygen_fr","oxygen_f","plasma","anesthetic")
|
||||
additional_desc = "It [pick("gloops","sloshes")] slightly when you shake it."
|
||||
if(13)
|
||||
item_type = "tool"
|
||||
if(prob(25))
|
||||
new_item = new /obj/item/weapon/wrench(src.loc)
|
||||
else if(prob(25))
|
||||
new_item = new /obj/item/weapon/crowbar(src.loc)
|
||||
else
|
||||
new_item = new /obj/item/weapon/screwdriver(src.loc)
|
||||
additional_desc = "[pick("It doesn't look safe.",\
|
||||
"You wonder what it was used for",\
|
||||
"There appear to be [pick("dark red","dark purple","dark green","dark blue")] stains on it")]."
|
||||
if(14)
|
||||
apply_material_decorations = 0
|
||||
var/list/possible_spawns = list()
|
||||
possible_spawns += /obj/item/stack/sheet/metal
|
||||
possible_spawns += /obj/item/stack/sheet/plasteel
|
||||
possible_spawns += /obj/item/stack/sheet/glass
|
||||
possible_spawns += /obj/item/stack/sheet/rglass
|
||||
possible_spawns += /obj/item/stack/sheet/mineral/plasma
|
||||
possible_spawns += /obj/item/stack/sheet/mineral/mythril
|
||||
possible_spawns += /obj/item/stack/sheet/mineral/gold
|
||||
possible_spawns += /obj/item/stack/sheet/mineral/silver
|
||||
possible_spawns += /obj/item/stack/sheet/mineral/enruranium
|
||||
possible_spawns += /obj/item/stack/sheet/mineral/sandstone
|
||||
possible_spawns += /obj/item/stack/sheet/mineral/silver
|
||||
|
||||
var/new_type = pick(possible_spawns)
|
||||
new_item = new new_type(src.loc)
|
||||
new_item:amount = rand(5,45)
|
||||
if(15)
|
||||
if(prob(75))
|
||||
new_item = new /obj/item/weapon/pen(src.loc)
|
||||
else
|
||||
new_item = new /obj/item/weapon/pen/sleepypen(src.loc)
|
||||
if(prob(30))
|
||||
apply_image_decorations = 1
|
||||
if(16)
|
||||
apply_prefix = 0
|
||||
if(prob(25))
|
||||
item_type = "smooth green crystal"
|
||||
icon_state = "Green lump"
|
||||
else if(prob(33))
|
||||
item_type = "irregular purple crystal"
|
||||
icon_state = "Phazon"
|
||||
else if(prob(50))
|
||||
item_type = "rough red crystal"
|
||||
icon_state = "changerock"
|
||||
else
|
||||
item_type = "smooth red crystal"
|
||||
icon_state = "ore"
|
||||
additional_desc = pick("It shines faintly as it catches the light.","It appears to have a faint inner glow.","It seems to draw you inward as you look it at.","Something twinkles faintly as you look at it.","It's mesmerizing to behold.")
|
||||
|
||||
apply_material_decorations = 0
|
||||
if(prob(10))
|
||||
apply_image_decorations = 1
|
||||
if(17)
|
||||
//cultblade
|
||||
apply_prefix = 0
|
||||
new_item = new /obj/item/weapon/melee/cultblade(src.loc)
|
||||
apply_material_decorations = 0
|
||||
apply_image_decorations = 0
|
||||
if(18)
|
||||
new_item = new /obj/item/device/radio/beacon(src.loc)
|
||||
talkative = 0
|
||||
new_item.icon_state = "unknown[rand(1,4)]"
|
||||
new_item.icon = 'xenoarchaeology.dmi'
|
||||
new_item.desc = ""
|
||||
if(19)
|
||||
apply_prefix = 0
|
||||
new_item = new /obj/item/weapon/claymore(src.loc)
|
||||
item_type = new_item.name
|
||||
if(20)
|
||||
//arcane clothing
|
||||
apply_prefix = 0
|
||||
var/list/possible_spawns = list(/obj/item/clothing/head/culthood,
|
||||
/obj/item/clothing/head/magus,
|
||||
/obj/item/clothing/head/culthood/alt,
|
||||
/obj/item/clothing/head/helmet/space/cult)
|
||||
|
||||
var/new_type = pick(possible_spawns)
|
||||
new_item = new new_type(src.loc)
|
||||
if(21)
|
||||
//soulstone
|
||||
apply_prefix = 0
|
||||
new_item = new /obj/item/device/soulstone(src.loc)
|
||||
item_type = new_item.name
|
||||
apply_material_decorations = 0
|
||||
if(22)
|
||||
if(prob(50))
|
||||
new_item = new /obj/item/weapon/shard(src.loc)
|
||||
else
|
||||
new_item = new /obj/item/weapon/shard/plasma(src.loc)
|
||||
apply_prefix = 0
|
||||
apply_image_decorations = 0
|
||||
apply_material_decorations = 0
|
||||
if(23)
|
||||
apply_prefix = 0
|
||||
new_item = new /obj/item/stack/rods(src.loc)
|
||||
apply_image_decorations = 0
|
||||
apply_material_decorations = 0
|
||||
if(24)
|
||||
var/list/possible_spawns = typesof(/obj/item/weapon/stock_parts)
|
||||
possible_spawns -= /obj/item/weapon/stock_parts
|
||||
possible_spawns -= /obj/item/weapon/stock_parts/subspace
|
||||
|
||||
var/new_type = pick(possible_spawns)
|
||||
new_item = new new_type(src.loc)
|
||||
item_type = new_item.name
|
||||
apply_material_decorations = 0
|
||||
if(25)
|
||||
apply_prefix = 0
|
||||
new_item = new /obj/item/weapon/katana(src.loc)
|
||||
item_type = new_item.name
|
||||
if(26)
|
||||
//energy gun
|
||||
var/spawn_type = pick(\
|
||||
/obj/item/weapon/gun/energy/laser/practice;100,\
|
||||
/obj/item/weapon/gun/energy/laser;75,\
|
||||
/obj/item/weapon/gun/energy/xray;50,\
|
||||
/obj/item/weapon/gun/energy/laser/captain;25,\
|
||||
)
|
||||
var/obj/item/weapon/gun/energy/new_gun = new spawn_type(src.loc)
|
||||
new_item = new_gun
|
||||
new_item.icon_state = "egun[rand(1,6)]"
|
||||
|
||||
//5% chance to explode when first fired
|
||||
//10% chance to have an unchargeable cell
|
||||
//15% chance to gain a random amount of starting energy, otherwise start with an empty cell
|
||||
if(prob(5))
|
||||
new_gun.power_supply.rigged = 1
|
||||
if(prob(10))
|
||||
new_gun.power_supply.maxcharge = 0
|
||||
if(prob(15))
|
||||
new_gun.power_supply.charge = rand(0, new_gun.power_supply.maxcharge)
|
||||
else
|
||||
new_gun.power_supply.charge = 0
|
||||
|
||||
item_type = "gun"
|
||||
if(27)
|
||||
//revolver
|
||||
var/obj/item/weapon/gun/projectile/new_gun = new /obj/item/weapon/gun/projectile(src.loc)
|
||||
new_item = new_gun
|
||||
new_item.icon_state = "gun[rand(1,4)]"
|
||||
|
||||
//33% chance to be able to reload the gun with human ammunition
|
||||
if(prob(66))
|
||||
new_gun.caliber = "999"
|
||||
|
||||
//33% chance to fill it with a random amount of bullets
|
||||
new_gun.max_shells = rand(1,12)
|
||||
if(prob(33))
|
||||
var/num_bullets = rand(1,new_gun.max_shells)
|
||||
if(num_bullets < new_gun.loaded.len)
|
||||
for(var/i = num_bullets, i <= new_gun.loaded.len, i++)
|
||||
new_gun.loaded += new new_gun.ammo_type(src)
|
||||
else
|
||||
for(var/obj/item/I in new_gun)
|
||||
if(new_gun.loaded.len > num_bullets)
|
||||
if(I in new_gun.loaded)
|
||||
new_gun.loaded.Remove(I)
|
||||
I.loc = null
|
||||
else
|
||||
break
|
||||
else
|
||||
for(var/obj/item/I in new_gun)
|
||||
if(I in new_gun.loaded)
|
||||
new_gun.loaded.Remove(I)
|
||||
I.loc = null
|
||||
|
||||
item_type = "gun"
|
||||
if(28)
|
||||
//completely unknown alien device
|
||||
if(prob(50))
|
||||
apply_image_decorations = 0
|
||||
if(29)
|
||||
//fossil bone/skull
|
||||
//new_item = new /obj/item/weapon/fossil/base(src.loc)
|
||||
|
||||
//the replacement item propogation isn't working, and it's messy code anyway so just do it here
|
||||
var/list/candidates = list("/obj/item/weapon/fossil/bone"=9,"/obj/item/weapon/fossil/skull"=3,
|
||||
"/obj/item/weapon/fossil/skull/horned"=2)
|
||||
var/spawn_type = pickweight(candidates)
|
||||
new_item = new spawn_type(src.loc)
|
||||
|
||||
apply_prefix = 0
|
||||
additional_desc = "A fossilised part of an alien, long dead."
|
||||
apply_image_decorations = 0
|
||||
apply_material_decorations = 0
|
||||
if(30)
|
||||
//fossil shell
|
||||
new_item = new /obj/item/weapon/fossil/shell(src.loc)
|
||||
apply_prefix = 0
|
||||
additional_desc = "A fossilised, pre-Stygian alien crustacean."
|
||||
apply_image_decorations = 0
|
||||
apply_material_decorations = 0
|
||||
if(prob(10))
|
||||
apply_image_decorations = 1
|
||||
if(31)
|
||||
//fossil plant
|
||||
new_item = new /obj/item/weapon/fossil/plant(src.loc)
|
||||
item_type = new_item.name
|
||||
additional_desc = "A fossilised shred of alien plant matter."
|
||||
apply_image_decorations = 0
|
||||
apply_material_decorations = 0
|
||||
apply_prefix = 0
|
||||
if(32)
|
||||
//humanoid remains
|
||||
apply_prefix = 0
|
||||
item_type = "humanoid [pick("remains","skeleton")]"
|
||||
icon = 'blood.dmi'
|
||||
icon_state = "remains"
|
||||
additional_desc = pick("They appear almost human.",\
|
||||
"They are contorted in a most gruesome way.",\
|
||||
"They look almost peaceful.",\
|
||||
"The bones are yellowing and old, but remarkably well preserved.",\
|
||||
"The bones are scored by numerous burns and partially melted.",\
|
||||
"The are battered and broken, in some cases less than splinters are left.",\
|
||||
"The mouth is wide open in a death rictus, the victim would appear to have died screaming.")
|
||||
apply_image_decorations = 0
|
||||
apply_material_decorations = 0
|
||||
if(33)
|
||||
//robot remains
|
||||
apply_prefix = 0
|
||||
item_type = "[pick("mechanical","robotic","cyborg")] [pick("remains","chassis","debris")]"
|
||||
icon = 'blood.dmi'
|
||||
icon_state = "remainsrobot"
|
||||
additional_desc = pick("Almost mistakeable for the remains of a modern cyborg.",\
|
||||
"They are barely recognisable as anything other than a pile of waste metals.",\
|
||||
"It looks like the battered remains of an ancient robot chassis.",\
|
||||
"The chassis is rusting and old, but remarkably well preserved.",\
|
||||
"The chassis is scored by numerous burns and partially melted.",\
|
||||
"The chassis is battered and broken, in some cases only chunks of metal are left.",\
|
||||
"A pile of wires and crap metal that looks vaguely robotic.")
|
||||
apply_image_decorations = 0
|
||||
apply_material_decorations = 0
|
||||
if(34)
|
||||
//xenos remains
|
||||
apply_prefix = 0
|
||||
item_type = "alien [pick("remains","skeleton")]"
|
||||
icon = 'blood.dmi'
|
||||
icon_state = "remainsxeno"
|
||||
additional_desc = pick("It looks vaguely reptilian, but with more teeth.",\
|
||||
"They are faintly unsettling.",\
|
||||
"There is a faint aura of unease about them.",\
|
||||
"The bones are yellowing and old, but remarkably well preserved.",\
|
||||
"The bones are scored by numerous burns and partially melted.",\
|
||||
"The are battered and broken, in some cases less than splinters are left.",\
|
||||
"This creature would have been twisted and monstrous when it was alive.",\
|
||||
"It doesn't look human.")
|
||||
apply_image_decorations = 0
|
||||
apply_material_decorations = 0
|
||||
|
||||
var/decorations = ""
|
||||
if(apply_material_decorations)
|
||||
source_material = pick("cordite","quadrinium","steel","titanium","aluminium","ferritic-alloy","plasteel","duranium")
|
||||
desc = "A [material_descriptor ? "[material_descriptor] " : ""][item_type] made of [source_material], all craftsmanship is of [pick("the lowest","low","average","high","the highest")] quality."
|
||||
|
||||
var/list/descriptors = list()
|
||||
if(prob(30))
|
||||
descriptors.Add("is encrusted with [pick("","synthetic ","multi-faceted ","uncut ","sparkling ") + pick("rubies","emeralds","diamonds","opals","lapiz lazuli")]")
|
||||
if(prob(30))
|
||||
descriptors.Add("is studded with [pick("gold","silver","aluminium","titanium")]")
|
||||
if(prob(30))
|
||||
descriptors.Add("is encircled with bands of [pick("quadrinium","cordite","ferritic-alloy","plasteel","duranium")]")
|
||||
if(prob(30))
|
||||
descriptors.Add("menaces with spikes of [pick("solid plasma","uranium","white pearl","black steel")]")
|
||||
if(descriptors.len > 0)
|
||||
decorations = "It "
|
||||
for(var/index=1, index <= descriptors.len, index++)
|
||||
if(index > 1)
|
||||
if(index == descriptors.len)
|
||||
decorations += " and "
|
||||
else
|
||||
decorations += ", "
|
||||
decorations += descriptors[index]
|
||||
decorations += "."
|
||||
if(decorations)
|
||||
desc += " " + decorations
|
||||
|
||||
var/engravings = ""
|
||||
if(apply_image_decorations)
|
||||
engravings = "[pick("Engraved","Carved","Etched")] on the item is [pick("an image of","a frieze of","a depiction of")] \
|
||||
[pick("an alien humanoid","an amorphic blob","a short, hairy being","a rodent-like creature","a robot","a primate","a reptilian alien","an unidentifiable object","a statue","a starship","unusual devices","a structure")] \
|
||||
[pick("surrounded by","being held aloft by","being struck by","being examined by","communicating with")] \
|
||||
[pick("alien humanoids","amorphic blobs","short, hairy beings","rodent-like creatures","robots","primates","reptilian aliens")]"
|
||||
if(prob(50))
|
||||
engravings += ", [pick("they seem to be enjoying themselves","they seem extremely angry","they look pensive","they are making gestures of supplication","the scene is one of subtle horror","the scene conveys a sense of desperation","the scene is completely bizarre")]"
|
||||
engravings += "."
|
||||
|
||||
if(desc)
|
||||
desc += " "
|
||||
desc += engravings
|
||||
|
||||
if(apply_prefix)
|
||||
name = "[pick("Strange","Ancient","Alien","")] [item_type]"
|
||||
else
|
||||
name = item_type
|
||||
|
||||
if(desc)
|
||||
desc += " "
|
||||
desc += additional_desc
|
||||
if(!desc)
|
||||
desc = "This item is completely [pick("alien","bizarre")]."
|
||||
|
||||
//icon and icon_state should have already been set
|
||||
if(new_item)
|
||||
new_item.name = name
|
||||
new_item.desc = src.desc
|
||||
|
||||
if(talkative)
|
||||
new_item.listening_to_players = 1
|
||||
if(prob(25))
|
||||
new_item.speaking_to_players = 1
|
||||
processing_objects.Add(src)
|
||||
var/turf/T = get_turf(src)
|
||||
if(istype(T, /turf/simulated/mineral))
|
||||
T:last_find = new_item
|
||||
del(src)
|
||||
|
||||
else if(talkative)
|
||||
listening_to_players = 1
|
||||
if(prob(25))
|
||||
speaking_to_players = 1
|
||||
processing_objects.Add(src)
|
||||
249
code/modules/research/xenoarchaeology/finds/finds_defines.dm
Normal file
249
code/modules/research/xenoarchaeology/finds/finds_defines.dm
Normal file
@@ -0,0 +1,249 @@
|
||||
|
||||
#define ARCHAEO_BOWL 1
|
||||
#define ARCHAEO_URN 2
|
||||
#define ARCHAEO_CUTLERY 3
|
||||
#define ARCHAEO_STATUETTE 4
|
||||
#define ARCHAEO_INSTRUMENT 5
|
||||
#define ARCHAEO_KNIFE 6
|
||||
#define ARCHAEO_COIN 7
|
||||
#define ARCHAEO_HANDCUFFS 8
|
||||
#define ARCHAEO_BEARTRAP 9
|
||||
#define ARCHAEO_LIGHTER 10
|
||||
#define ARCHAEO_BOX 11
|
||||
#define ARCHAEO_GASTANK 12
|
||||
#define ARCHAEO_TOOL 13
|
||||
#define ARCHAEO_METAL 14
|
||||
#define ARCHAEO_PEN 15
|
||||
#define ARCHAEO_CRYSTAL 16
|
||||
#define ARCHAEO_CULTBLADE 17
|
||||
#define ARCHAEO_TELEBEACON 18
|
||||
#define ARCHAEO_CLAYMORE 19
|
||||
#define ARCHAEO_CULTROBES 20
|
||||
#define ARCHAEO_SOULSTONE 21
|
||||
#define ARCHAEO_SHARD 22
|
||||
#define ARCHAEO_RODS 23
|
||||
#define ARCHAEO_STOCKPARTS 24
|
||||
#define ARCHAEO_KATANA 25
|
||||
#define ARCHAEO_LASER 26
|
||||
#define ARCHAEO_GUN 27
|
||||
#define ARCHAEO_UNKNOWN 28
|
||||
#define ARCHAEO_FOSSIL 29
|
||||
#define ARCHAEO_SHELL 30
|
||||
#define ARCHAEO_PLANT 31
|
||||
#define ARCHAEO_REMAINS_HUMANOID 32
|
||||
#define ARCHAEO_REMAINS_ROBOT 33
|
||||
#define ARCHAEO_REMAINS_XENO 34
|
||||
#define MAX_ARCHAEO 34
|
||||
//eggs
|
||||
//droppings
|
||||
//footprints
|
||||
//alien clothing
|
||||
|
||||
//DNA sampling from fossils, or a new archaeo type specifically for it?
|
||||
|
||||
//descending order of likeliness to spawn
|
||||
#define DIGSITE_GARDEN 1
|
||||
#define DIGSITE_ANIMAL 2
|
||||
#define DIGSITE_HOUSE 3
|
||||
#define DIGSITE_TECHNICAL 4
|
||||
#define DIGSITE_TEMPLE 5
|
||||
#define DIGSITE_WAR 6
|
||||
|
||||
/proc/get_responsive_reagent(var/find_type)
|
||||
switch(find_type)
|
||||
if(ARCHAEO_BOWL)
|
||||
return "mercury"
|
||||
if(ARCHAEO_URN)
|
||||
return "mercury"
|
||||
if(ARCHAEO_CUTLERY)
|
||||
return "mercury"
|
||||
if(ARCHAEO_STATUETTE)
|
||||
return "mercury"
|
||||
if(ARCHAEO_INSTRUMENT)
|
||||
return "mercury"
|
||||
if(ARCHAEO_COIN)
|
||||
return "iron"
|
||||
if(ARCHAEO_KNIFE)
|
||||
return "iron"
|
||||
if(ARCHAEO_HANDCUFFS)
|
||||
return "mercury"
|
||||
if(ARCHAEO_BEARTRAP)
|
||||
return "mercury"
|
||||
if(ARCHAEO_LIGHTER)
|
||||
return "mercury"
|
||||
if(ARCHAEO_BOX)
|
||||
return "mercury"
|
||||
if(ARCHAEO_GASTANK)
|
||||
return "mercury"
|
||||
if(ARCHAEO_TOOL)
|
||||
return "iron"
|
||||
if(ARCHAEO_METAL)
|
||||
return "iron"
|
||||
if(ARCHAEO_PEN)
|
||||
return "mercury"
|
||||
if(ARCHAEO_CRYSTAL)
|
||||
return "nitrogen"
|
||||
if(ARCHAEO_CULTBLADE)
|
||||
return "potassium"
|
||||
if(ARCHAEO_TELEBEACON)
|
||||
return "potassium"
|
||||
if(ARCHAEO_CLAYMORE)
|
||||
return "iron"
|
||||
if(ARCHAEO_CULTROBES)
|
||||
return "potassium"
|
||||
if(ARCHAEO_SOULSTONE)
|
||||
return "nitrogen"
|
||||
if(ARCHAEO_SHARD)
|
||||
return "nitrogen"
|
||||
if(ARCHAEO_RODS)
|
||||
return "iron"
|
||||
if(ARCHAEO_STOCKPARTS)
|
||||
return "potassium"
|
||||
if(ARCHAEO_KATANA)
|
||||
return "iron"
|
||||
if(ARCHAEO_LASER)
|
||||
return "iron"
|
||||
if(ARCHAEO_GUN)
|
||||
return "iron"
|
||||
if(ARCHAEO_UNKNOWN)
|
||||
return "mercury"
|
||||
if(ARCHAEO_FOSSIL)
|
||||
return "carbon"
|
||||
if(ARCHAEO_SHELL)
|
||||
return "carbon"
|
||||
if(ARCHAEO_PLANT)
|
||||
return "carbon"
|
||||
if(ARCHAEO_REMAINS_HUMANOID)
|
||||
return "carbon"
|
||||
if(ARCHAEO_REMAINS_ROBOT)
|
||||
return "carbon"
|
||||
if(ARCHAEO_REMAINS_XENO)
|
||||
return "carbon"
|
||||
return "plasma"
|
||||
|
||||
//see /turf/simulated/mineral/New() in code/modules/mining/mine_turfs.dm
|
||||
/proc/get_random_digsite_type()
|
||||
return pick(100;DIGSITE_GARDEN,95;DIGSITE_ANIMAL,90;DIGSITE_HOUSE,85;DIGSITE_TECHNICAL,80;DIGSITE_TEMPLE,75;DIGSITE_WAR)
|
||||
|
||||
/proc/get_random_find_type(var/digsite)
|
||||
|
||||
var/find_type = 0
|
||||
switch(digsite)
|
||||
if(DIGSITE_GARDEN)
|
||||
find_type = pick(\
|
||||
100;ARCHAEO_PLANT,\
|
||||
25;ARCHAEO_SHELL,\
|
||||
25;ARCHAEO_FOSSIL,\
|
||||
5;ARCHAEO_BEARTRAP\
|
||||
)
|
||||
if(DIGSITE_ANIMAL)
|
||||
find_type = pick(\
|
||||
100;ARCHAEO_FOSSIL,\
|
||||
50;ARCHAEO_SHELL,\
|
||||
50;ARCHAEO_PLANT,\
|
||||
25;ARCHAEO_BEARTRAP\
|
||||
)
|
||||
if(DIGSITE_HOUSE)
|
||||
find_type = pick(\
|
||||
100;ARCHAEO_BOWL,\
|
||||
100;ARCHAEO_URN,\
|
||||
100;ARCHAEO_CUTLERY,\
|
||||
100;ARCHAEO_STATUETTE,\
|
||||
100;ARCHAEO_INSTRUMENT,\
|
||||
100;ARCHAEO_PEN,\
|
||||
100;ARCHAEO_LIGHTER,\
|
||||
100;ARCHAEO_BOX,\
|
||||
75;ARCHAEO_COIN,\
|
||||
75;ARCHAEO_UNKNOWN,\
|
||||
50;ARCHAEO_SHARD,\
|
||||
50;ARCHAEO_RODS,\
|
||||
25;ARCHAEO_METAL\
|
||||
)
|
||||
if(DIGSITE_TECHNICAL)
|
||||
find_type = pick(\
|
||||
100;ARCHAEO_METAL,\
|
||||
100;ARCHAEO_GASTANK,\
|
||||
100;ARCHAEO_TELEBEACON,\
|
||||
100;ARCHAEO_TOOL,\
|
||||
100;ARCHAEO_STOCKPARTS,\
|
||||
75;ARCHAEO_SHARD,\
|
||||
75;ARCHAEO_RODS,\
|
||||
75;ARCHAEO_UNKNOWN,\
|
||||
50;ARCHAEO_HANDCUFFS,\
|
||||
50;ARCHAEO_BEARTRAP,\
|
||||
)
|
||||
if(DIGSITE_TEMPLE)
|
||||
find_type = pick(\
|
||||
200;ARCHAEO_CULTROBES,\
|
||||
100;ARCHAEO_URN,\
|
||||
100;ARCHAEO_BOWL,\
|
||||
100;ARCHAEO_KNIFE,\
|
||||
100;ARCHAEO_CRYSTAL,\
|
||||
75;ARCHAEO_CULTBLADE,\
|
||||
50;ARCHAEO_SOULSTONE,\
|
||||
50;ARCHAEO_UNKNOWN,\
|
||||
25;ARCHAEO_HANDCUFFS,\
|
||||
25;ARCHAEO_BEARTRAP,\
|
||||
10;ARCHAEO_KATANA,\
|
||||
10;ARCHAEO_CLAYMORE,\
|
||||
10;ARCHAEO_SHARD,\
|
||||
10;ARCHAEO_RODS,\
|
||||
10;ARCHAEO_METAL\
|
||||
)
|
||||
if(DIGSITE_WAR)
|
||||
find_type = pick(\
|
||||
100;ARCHAEO_GUN,\
|
||||
100;ARCHAEO_KNIFE,\
|
||||
75;ARCHAEO_LASER,\
|
||||
75;ARCHAEO_KATANA,\
|
||||
75;ARCHAEO_CLAYMORE,\
|
||||
50;ARCHAEO_UNKNOWN,\
|
||||
50;ARCHAEO_CULTROBES,\
|
||||
50;ARCHAEO_CULTBLADE,\
|
||||
25;ARCHAEO_HANDCUFFS,\
|
||||
25;ARCHAEO_BEARTRAP,\
|
||||
25;ARCHAEO_TOOL\
|
||||
)
|
||||
return find_type
|
||||
|
||||
#undef ARCHAEO_BOWL
|
||||
#undef ARCHAEO_URN
|
||||
#undef ARCHAEO_CUTLERY
|
||||
#undef ARCHAEO_STATUETTE
|
||||
#undef ARCHAEO_INSTRUMENT
|
||||
#undef ARCHAEO_KNIFE
|
||||
#undef ARCHAEO_COIN
|
||||
#undef ARCHAEO_HANDCUFFS
|
||||
#undef ARCHAEO_BEARTRAP
|
||||
#undef ARCHAEO_LIGHTER
|
||||
#undef ARCHAEO_BOX
|
||||
#undef ARCHAEO_GASTANK
|
||||
#undef ARCHAEO_TOOL
|
||||
#undef ARCHAEO_METAL
|
||||
#undef ARCHAEO_PEN
|
||||
#undef ARCHAEO_CRYSTAL
|
||||
#undef ARCHAEO_CULTBLADE
|
||||
#undef ARCHAEO_TELEBEACON
|
||||
#undef ARCHAEO_CLAYMORE
|
||||
#undef ARCHAEO_CULTROBES
|
||||
#undef ARCHAEO_SOULSTONE
|
||||
#undef ARCHAEO_SHARD
|
||||
#undef ARCHAEO_RODS
|
||||
#undef ARCHAEO_STOCKPARTS
|
||||
#undef ARCHAEO_KATANA
|
||||
#undef ARCHAEO_LASER
|
||||
#undef ARCHAEO_GUN
|
||||
#undef ARCHAEO_UNKNOWN
|
||||
#undef ARCHAEO_FOSSIL
|
||||
#undef ARCHAEO_SHELL
|
||||
#undef ARCHAEO_PLANT
|
||||
#undef ARCHAEO_REMAINS_HUMANOID
|
||||
#undef ARCHAEO_REMAINS_ROBOT
|
||||
#undef ARCHAEO_REMAINS_XENO
|
||||
|
||||
#undef DIGSITE_GARDEN
|
||||
#undef DIGSITE_ANIMAL
|
||||
#undef DIGSITE_HOUSE
|
||||
#undef DIGSITE_TECHNICAL
|
||||
#undef DIGSITE_TEMPLE
|
||||
#undef DIGSITE_WAR
|
||||
102
code/modules/research/xenoarchaeology/finds/finds_fossils.dm
Normal file
102
code/modules/research/xenoarchaeology/finds/finds_fossils.dm
Normal file
@@ -0,0 +1,102 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// fossils
|
||||
|
||||
/obj/item/weapon/fossil
|
||||
name = "Fossil"
|
||||
icon = 'xenoarchaeology.dmi'
|
||||
icon_state = "bone"
|
||||
desc = "It's a fossil."
|
||||
|
||||
/obj/item/weapon/fossil/base/New()
|
||||
var/list/l = list("/obj/item/weapon/fossil/bone"=9,"/obj/item/weapon/fossil/skull"=3,
|
||||
"/obj/item/weapon/fossil/skull/horned"=2)
|
||||
var/t = pickweight(l)
|
||||
var/obj/item/weapon/W = new t(src.loc)
|
||||
var/turf/T = get_turf(src)
|
||||
if(istype(T, /turf/simulated/mineral))
|
||||
T:last_find = W
|
||||
del src
|
||||
|
||||
/obj/item/weapon/fossil/bone
|
||||
name = "Fossilised bone"
|
||||
icon_state = "bone"
|
||||
desc = "It's a fossilised bone."
|
||||
|
||||
/obj/item/weapon/fossil/skull
|
||||
name = "Fossilised skull"
|
||||
icon_state = "skull"
|
||||
desc = "It's a fossilised skull."
|
||||
|
||||
/obj/item/weapon/fossil/skull/horned
|
||||
icon_state = "hskull"
|
||||
desc = "It's a fossilised, horned skull."
|
||||
|
||||
/obj/item/weapon/fossil/skull/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/weapon/fossil/bone))
|
||||
var/obj/o = new /obj/skeleton(get_turf(src))
|
||||
var/a = new /obj/item/weapon/fossil/bone
|
||||
var/b = new src.type
|
||||
o.contents.Add(a)
|
||||
o.contents.Add(b)
|
||||
del W
|
||||
del src
|
||||
|
||||
/obj/skeleton
|
||||
name = "Incomplete skeleton"
|
||||
icon = 'xenoarchaeology.dmi'
|
||||
icon_state = "uskel"
|
||||
desc = "Incomplete skeleton."
|
||||
var/bnum = 1
|
||||
var/breq
|
||||
var/bstate = 0
|
||||
var/plaque_contents = "Unnamed alien creature"
|
||||
|
||||
/obj/skeleton/New()
|
||||
src.breq = rand(6)+3
|
||||
src.desc = "An incomplete skeleton, looks like it could use [src.breq-src.bnum] more bones."
|
||||
|
||||
/obj/skeleton/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/weapon/fossil/bone))
|
||||
if(!bstate)
|
||||
bnum++
|
||||
src.contents.Add(new/obj/item/weapon/fossil/bone)
|
||||
del W
|
||||
if(bnum==breq)
|
||||
usr = user
|
||||
icon_state = "skel"
|
||||
src.bstate = 1
|
||||
src.density = 1
|
||||
src.name = "alien skeleton display"
|
||||
if(src.contents.Find(/obj/item/weapon/fossil/skull/horned))
|
||||
src.desc = "A creature made of [src.contents.len-1] assorted bones and a horned skull. The plaque reads \'[plaque_contents]\'."
|
||||
else
|
||||
src.desc = "A creature made of [src.contents.len-1] assorted bones and a skull. The plaque reads \'[plaque_contents]\'."
|
||||
else
|
||||
src.desc = "Incomplete skeleton, looks like it could use [src.breq-src.bnum] more bones."
|
||||
user << "Looks like it could use [src.breq-src.bnum] more bones."
|
||||
else
|
||||
..()
|
||||
else if(istype(W,/obj/item/weapon/pen))
|
||||
plaque_contents = input("What would you like to write on the plaque:","Skeleton plaque","")
|
||||
user.visible_message("[user] writes something on the base of [src].","You relabel the plaque on the base of \icon[src] [src].")
|
||||
if(src.contents.Find(/obj/item/weapon/fossil/skull/horned))
|
||||
src.desc = "A creature made of [src.contents.len-1] assorted bones and a horned skull. The plaque reads \'[plaque_contents]\'."
|
||||
else
|
||||
src.desc = "A creature made of [src.contents.len-1] assorted bones and a skull. The plaque reads \'[plaque_contents]\'."
|
||||
else
|
||||
..()
|
||||
|
||||
//shells and plants do not make skeletons
|
||||
/obj/item/weapon/fossil/shell
|
||||
name = "Fossilised shell"
|
||||
icon_state = "shell"
|
||||
desc = "It's a fossilised shell."
|
||||
|
||||
/obj/item/weapon/fossil/plant
|
||||
name = "Fossilised plant"
|
||||
icon_state = "plant1"
|
||||
desc = "It's fossilised plant remains."
|
||||
|
||||
/obj/item/weapon/fossil/plant/New()
|
||||
icon_state = "plant[rand(1,4)]"
|
||||
69
code/modules/research/xenoarchaeology/finds/finds_misc.dm
Normal file
69
code/modules/research/xenoarchaeology/finds/finds_misc.dm
Normal file
@@ -0,0 +1,69 @@
|
||||
|
||||
/obj/item/weapon/shard/plasma
|
||||
name = "plasma shard"
|
||||
icon_state = "plasmalarge"
|
||||
|
||||
/obj/item/weapon/shard/plasma/New()
|
||||
|
||||
src.icon_state = pick("plasmalarge", "plasmamedium", "plasmasmall")
|
||||
switch(src.icon_state)
|
||||
if("plasmasmall")
|
||||
src.pixel_x = rand(-12, 12)
|
||||
src.pixel_y = rand(-12, 12)
|
||||
if("plasmamedium")
|
||||
src.pixel_x = rand(-8, 8)
|
||||
src.pixel_y = rand(-8, 8)
|
||||
if("plasmalarge")
|
||||
src.pixel_x = rand(-5, 5)
|
||||
src.pixel_y = rand(-5, 5)
|
||||
else
|
||||
return
|
||||
|
||||
/obj/item/weapon/shard/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
..()
|
||||
if ( istype(W, /obj/item/weapon/weldingtool))
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if(WT.remove_fuel(0, user))
|
||||
var/obj/item/stack/sheet/mineral/plasma/NG = new (user.loc)
|
||||
for (var/obj/item/stack/sheet/mineral/plasma/G in user.loc)
|
||||
if(G==NG)
|
||||
continue
|
||||
if(G.amount>=G.max_amount)
|
||||
continue
|
||||
G.attackby(NG, user)
|
||||
usr << "You add the newly-formed plasma to the stack. It now contains [NG.amount] sheets."
|
||||
//SN src = null
|
||||
del(src)
|
||||
return
|
||||
return ..()
|
||||
|
||||
//legacy crystal
|
||||
/obj/machinery/crystal
|
||||
name = "Crystal"
|
||||
icon = 'mining.dmi'
|
||||
icon_state = "crystal"
|
||||
|
||||
/obj/machinery/crystal/New()
|
||||
if(prob(50))
|
||||
icon_state = "crystal2"
|
||||
|
||||
//large finds
|
||||
/*
|
||||
/obj/machinery/syndicate_beacon
|
||||
/obj/machinery/wish_granter
|
||||
if(18)
|
||||
item_type = "jagged green crystal"
|
||||
additional_desc = pick("It shines faintly as it catches the light.","It appears to have a faint inner glow.","It seems to draw you inward as you look it at.","Something twinkles faintly as you look at it.","It's mesmerizing to behold.")
|
||||
icon_state = "crystal"
|
||||
apply_material_decorations = 0
|
||||
if(prob(10))
|
||||
apply_image_decorations = 1
|
||||
if(19)
|
||||
item_type = "jagged pink crystal"
|
||||
additional_desc = pick("It shines faintly as it catches the light.","It appears to have a faint inner glow.","It seems to draw you inward as you look it at.","Something twinkles faintly as you look at it.","It's mesmerizing to behold.")
|
||||
icon_state = "crystal2"
|
||||
apply_material_decorations = 0
|
||||
if(prob(10))
|
||||
apply_image_decorations = 1
|
||||
*/
|
||||
//machinery type artifacts?
|
||||
109
code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm
Normal file
109
code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm
Normal file
@@ -0,0 +1,109 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Formerly talking crystals - these procs are now modular so that you can make any /obj/item/weapon 'parrot' player speech back to them
|
||||
// This could be extended to atoms, but it's bad enough as is
|
||||
// I genuinely tried to Add and Remove them from var and proc lists, but just couldn't get it working
|
||||
|
||||
/obj/item/weapon
|
||||
var/list/heard_words = list()
|
||||
var/lastsaid
|
||||
var/listening_to_players = 0
|
||||
var/speaking_to_players = 0
|
||||
|
||||
/obj/item/weapon/process()
|
||||
if(!speaking_to_players)
|
||||
processing_objects.Remove(src)
|
||||
return
|
||||
if(prob(10) && world.timeofday >= lastsaid && heard_words.len >= 1)
|
||||
SaySomething()
|
||||
|
||||
/obj/item/weapon/proc/catchMessage(var/msg, var/mob/source)
|
||||
if(speaking_to_players)
|
||||
var/list/seperate = list()
|
||||
if(findtext(msg,"(("))
|
||||
return
|
||||
else if(findtext(msg,"))"))
|
||||
return
|
||||
else if(findtext(msg," ")==0)
|
||||
return
|
||||
else
|
||||
/*var/l = lentext(msg)
|
||||
if(findtext(msg," ",l,l+1)==0)
|
||||
msg+=" "*/
|
||||
seperate = stringsplit(msg, " ")
|
||||
|
||||
for(var/Xa = 1,Xa<seperate.len,Xa++)
|
||||
var/next = Xa + 1
|
||||
if(heard_words.len > 20 + rand(10,20))
|
||||
heard_words.Remove(heard_words[1])
|
||||
if(!heard_words["[lowertext(seperate[Xa])]"])
|
||||
heard_words["[lowertext(seperate[Xa])]"] = list()
|
||||
var/list/w = heard_words["[lowertext(seperate[Xa])]"]
|
||||
if(w)
|
||||
w.Add("[lowertext(seperate[next])]")
|
||||
//world << "Adding [lowertext(seperate[next])] to [lowertext(seperate[Xa])]"
|
||||
|
||||
if(!rand(0, 5))
|
||||
spawn(2) SaySomething(pick(seperate))
|
||||
if(prob(30))
|
||||
for(var/mob/O in viewers(src))
|
||||
O.show_message("\blue [src] hums for bit then stops...", 1)
|
||||
|
||||
/*/obj/item/weapon/talkingcrystal/proc/debug()
|
||||
//set src in view()
|
||||
for(var/v in heard_words)
|
||||
world << "[uppertext(v)]"
|
||||
var/list/d = heard_words["[v]"]
|
||||
for(var/X in d)
|
||||
world << "[X]"*/
|
||||
|
||||
/obj/item/weapon/proc/SaySomething(var/word = null)
|
||||
|
||||
var/msg
|
||||
var/limit = rand(max(5,heard_words.len/2))+3
|
||||
var/text
|
||||
if(!word)
|
||||
text = "[pick(heard_words)]"
|
||||
else
|
||||
text = pick(stringsplit(word, " "))
|
||||
if(lentext(text)==1)
|
||||
text=uppertext(text)
|
||||
else
|
||||
var/cap = copytext(text,1,2)
|
||||
cap = uppertext(cap)
|
||||
cap += copytext(text,2,lentext(text)+1)
|
||||
text=cap
|
||||
var/q = 0
|
||||
msg+=text
|
||||
if(msg=="What" | msg == "Who" | msg == "How" | msg == "Why" | msg == "Are")
|
||||
q=1
|
||||
|
||||
text=lowertext(text)
|
||||
for(var/ya,ya <= limit,ya++)
|
||||
|
||||
if(heard_words.Find("[text]"))
|
||||
var/list/w = heard_words["[text]"]
|
||||
text=pick(w)
|
||||
else
|
||||
text = "[pick(heard_words)]"
|
||||
msg+=" [text]"
|
||||
if(q)
|
||||
msg+="?"
|
||||
else
|
||||
if(rand(0,10))
|
||||
msg+="."
|
||||
else
|
||||
msg+="!"
|
||||
|
||||
var/list/listening = viewers(src)
|
||||
for(var/mob/M in world)
|
||||
if (!M.client)
|
||||
continue //skip monkeys and leavers
|
||||
if (istype(M, /mob/new_player))
|
||||
continue
|
||||
if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS)
|
||||
listening|=M
|
||||
|
||||
for(var/mob/M in listening)
|
||||
M << "<b>[src]</b> reverberates, \blue\"[msg]\""
|
||||
lastsaid = world.timeofday + rand(300,800)
|
||||
@@ -1,42 +1,167 @@
|
||||
/*
|
||||
#define FIND_PLANT 1
|
||||
#define FIND_BIO 2
|
||||
#define FIND_METEORIC 3
|
||||
#define FIND_ICE 4
|
||||
#define FIND_CRYSTALLINE 5
|
||||
#define FIND_METALLIC 6
|
||||
#define FIND_IGNEOUS 7
|
||||
#define FIND_METAMORPHIC 8
|
||||
#define FIND_SEDIMENTARY 9
|
||||
#define FIND_NOTHING 10
|
||||
*/
|
||||
|
||||
datum/geosample
|
||||
var/scrambled = 0 //if this sample has been mixed with other samples
|
||||
//
|
||||
var/age_thousand = 1 //age can correspond to different artifacts
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Rock sliver
|
||||
|
||||
/obj/item/weapon/rocksliver
|
||||
name = "rock sliver"
|
||||
desc = "It looks extremely delicate."
|
||||
icon = 'xenoarchaeology.dmi'
|
||||
icon_state = "sliver1" //0-4
|
||||
w_class = 1
|
||||
//item_state = "electronic"
|
||||
var/source_rock = "/turf/simulated/mineral/"
|
||||
var/datum/geosample/geological_data
|
||||
|
||||
/obj/item/weapon/rocksliver/New()
|
||||
icon_state = "sliver[rand(1,3)]"
|
||||
pixel_x = rand(0,16)-8
|
||||
pixel_y = rand(0,8)-8
|
||||
|
||||
var/list/responsive_carriers = list( \
|
||||
"carbon", \
|
||||
"potassium", \
|
||||
"hydrogen", \
|
||||
"nitrogen", \
|
||||
"mercury", \
|
||||
"iron", \
|
||||
"chlorine", \
|
||||
"phosphorus", \
|
||||
"plasma")
|
||||
|
||||
var/list/finds_as_strings = list( \
|
||||
"Trace organic cells", \
|
||||
"Long exposure particles", \
|
||||
"Trace water particles", \
|
||||
"Crystalline structures", \
|
||||
"Metallic derivative", \
|
||||
"Metallic composite", \
|
||||
"Metamorphic/igneous rock composite", \
|
||||
"Metamorphic/sedimentary rock composite", \
|
||||
"Anomalous material" )
|
||||
|
||||
var/list/artifact_spawning_turfs = list()
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Geosample datum
|
||||
|
||||
/datum/geosample
|
||||
var/age = 0 //age can correspond to different archaeological finds
|
||||
var/age_thousand = 0
|
||||
var/age_million = 0
|
||||
var/age_billion = 0
|
||||
var/artifact_id = "" //id of a nearby artifact, if there is one
|
||||
var/artifact_strength = 0 //proportional to distance
|
||||
var/responsive_reagent = "" ///each reagent corresponds to a different type of find
|
||||
var/reagent_response = "" //likelihood of there being finds there
|
||||
var/artifact_distance = -1 //proportional to distance
|
||||
var/source_mineral = "chlorine" //machines will pop up a warning telling players that the sample may be confused
|
||||
var/total_spread = 0
|
||||
//
|
||||
//var/source_mineral
|
||||
//all potential finds are initialised to null, so nullcheck before you access them
|
||||
var/list/find_presence = list()
|
||||
|
||||
/datum/geosample/New(var/turf/simulated/mineral/container)
|
||||
|
||||
datum/geosample/New(var/turf/simulated/mineral/container)
|
||||
UpdateTurf(container)
|
||||
|
||||
//this function should only be called once. it's here just in case
|
||||
datum/geosample/proc/UpdateTurf(var/turf/simulated/mineral/container)
|
||||
src = null
|
||||
//this should only need to be called once
|
||||
/datum/geosample/proc/UpdateTurf(var/turf/simulated/mineral/container)
|
||||
if(!container || !istype(container))
|
||||
return
|
||||
|
||||
age = rand(1,999)
|
||||
total_spread = 0
|
||||
|
||||
switch(container.mineralName)
|
||||
if("Uranium")
|
||||
age_million = rand(1, 704)
|
||||
age_thousand = rand(1,999)
|
||||
find_presence["potassium"] = rand(1,1000) / 100
|
||||
source_mineral = "potassium"
|
||||
if("Iron")
|
||||
age_thousand = rand(1, 999)
|
||||
age_million = rand(1, 999)
|
||||
find_presence["iron"] = rand(1,1000) / 100
|
||||
source_mineral = "iron"
|
||||
if("Diamond")
|
||||
age_thousand = rand(1,999)
|
||||
age_million = rand(1,999)
|
||||
find_presence["nitrogen"] = rand(1,1000) / 100
|
||||
source_mineral = "nitrogen"
|
||||
if("Gold")
|
||||
age_thousand = rand(1,999)
|
||||
age_million = rand(1,999)
|
||||
age_billion = rand(3,4)
|
||||
find_presence["iron"] = rand(1,1000) / 100
|
||||
source_mineral = "iron"
|
||||
if("Silver")
|
||||
age_thousand = rand(1,999)
|
||||
age_million = rand(1,999)
|
||||
find_presence["iron"] = rand(1,1000) / 100
|
||||
source_mineral = "iron"
|
||||
if("Plasma")
|
||||
age_thousand = rand(1,999)
|
||||
age_million = rand(1,999)
|
||||
age_billion = rand(10, 13)
|
||||
if("Archaeo")
|
||||
//snowflake
|
||||
age_thousand = rand(1,999)
|
||||
find_presence["plasma"] = rand(1,1000) / 100
|
||||
source_mineral = "plasma"
|
||||
if("Clown")
|
||||
age = rand(-1,-999) //thats the joke
|
||||
age_thousand = rand(-1,-999)
|
||||
find_presence["plasma"] = rand(1,1000) / 100
|
||||
source_mineral = "plasma"
|
||||
|
||||
if(prob(75))
|
||||
find_presence["phosphorus"] = rand(1,500) / 100
|
||||
if(prob(25))
|
||||
find_presence["mercury"] = rand(1,500) / 100
|
||||
find_presence["chlorine"] = rand(500,2500) / 100
|
||||
|
||||
//loop over finds, grab any relevant stuff
|
||||
for(var/datum/find/F in container.finds)
|
||||
var/responsive_reagent = get_responsive_reagent(F.find_type)
|
||||
find_presence[responsive_reagent] = F.dissonance_spread
|
||||
|
||||
for(var/entry in find_presence)
|
||||
total_spread += find_presence[entry]
|
||||
|
||||
//have this separate from UpdateTurf() so that we dont have a billion turfs being updated (redundantly) every time an artifact spawns
|
||||
/datum/geosample/proc/UpdateNearbyArtifactInfo(var/turf/simulated/mineral/container)
|
||||
if(!container || !istype(container))
|
||||
return
|
||||
|
||||
if(container.artifact_find)
|
||||
artifact_distance = rand()
|
||||
artifact_id = container.artifact_find.artifact_id
|
||||
else
|
||||
for(var/turf/simulated/mineral/holder in artifact_spawning_turfs)
|
||||
if(holder.artifact_find)
|
||||
var/dist = get_dist(container, holder)
|
||||
if(dist < holder.artifact_find.artifact_detect_range && dist < src.artifact_distance)
|
||||
src.artifact_distance = dist
|
||||
src.artifact_id = holder.artifact_find.artifact_id
|
||||
else
|
||||
artifact_spawning_turfs.Remove(holder)
|
||||
|
||||
/*
|
||||
#undef FIND_PLANT
|
||||
#undef FIND_BIO
|
||||
#undef FIND_METEORIC
|
||||
#undef FIND_ICE
|
||||
#undef FIND_CRYSTALLINE
|
||||
#undef FIND_METALLIC
|
||||
#undef FIND_IGNEOUS
|
||||
#undef FIND_METAMORPHIC
|
||||
#undef FIND_SEDIMENTARY
|
||||
#undef FIND_NOTHING
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
obj/machinery/anomaly/accelerator
|
||||
name = "Accelerator spectrometer"
|
||||
|
||||
obj/machinery/anomaly/accelerator/ScanResults()
|
||||
var/results = "The scan was inconclusive. Check sample integrity and carrier consistency."
|
||||
|
||||
var/datum/geosample/scanned_sample
|
||||
var/carrier_name
|
||||
var/num_reagents = 0
|
||||
|
||||
for(var/datum/reagent/A in held_container.reagents.reagent_list)
|
||||
var/datum/reagent/R = A
|
||||
if(istype(R, /datum/reagent/analysis_sample))
|
||||
scanned_sample = R.data
|
||||
else
|
||||
carrier_name = R.id
|
||||
num_reagents++
|
||||
|
||||
if(num_reagents == 2 && scanned_sample && carrier_name)
|
||||
var/accuracy = GetResultSpecifity(scanned_sample, carrier_name)
|
||||
accuracy += 0.5 * (1 - accuracy) / scanned_sample.total_spread
|
||||
if(!accuracy)
|
||||
accuracy = rand(0.01, 0.5)
|
||||
results = "Kinetic acceleration of carrier ([carrier_name]) indicates age ([100 * accuracy]% accuracy): <br><br>"
|
||||
|
||||
if(scanned_sample.age_billion)
|
||||
var/displayed_age_millions = scanned_sample.age_million + max(scanned_sample.age_million * ((1 - accuracy) * (2 * rand() - 1)), 0)
|
||||
var/displayed_age_billions = scanned_sample.age_billion + max(scanned_sample.age_billion * ((1 - accuracy) * (2 * rand() - 1)), 0)
|
||||
results += "[displayed_age_billions + displayed_age_millions / 1000] billion years.<br>"
|
||||
else if(scanned_sample.age_million)
|
||||
var/displayed_age_thousands = scanned_sample.age_thousand + max(scanned_sample.age_thousand * ((1 - accuracy) * (4 * rand() - 2)), 0)
|
||||
var/displayed_age_millions = scanned_sample.age_million + max(scanned_sample.age_million * ((1 - accuracy) * (2 * rand() - 1)), 0)
|
||||
results += "[displayed_age_millions + displayed_age_thousands / 1000] million years.<br>"
|
||||
else if(scanned_sample.age_thousand)
|
||||
var/displayed_age = scanned_sample.age + max(scanned_sample.age * ((1 - accuracy) * (8 * rand() - 4)), 0)
|
||||
var/displayed_age_thousands = scanned_sample.age_thousand + max(scanned_sample.age * ((1 - accuracy) * (4 * rand() - 2)), 0)
|
||||
results += "[displayed_age_thousands + displayed_age / 1000] thousand years.<br>"
|
||||
else
|
||||
var/displayed_age = scanned_sample.age + max(scanned_sample.age * ((1 - accuracy) * (8 * rand() - 4)), 0)
|
||||
results += "[displayed_age] years.<br>"
|
||||
|
||||
results += "<br>Warning, results only valid for ages on the scale of billions of years."
|
||||
|
||||
return results
|
||||
171
code/modules/research/xenoarchaeology/machinery/analysis_base.dm
Normal file
171
code/modules/research/xenoarchaeology/machinery/analysis_base.dm
Normal file
@@ -0,0 +1,171 @@
|
||||
|
||||
/obj/machinery/anomaly
|
||||
name = "Analysis machine"
|
||||
desc = "A specialised, complex analysis machine."
|
||||
anchored = 1
|
||||
density = 1
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon_state = "analyser"
|
||||
//
|
||||
var/obj/item/weapon/reagent_containers/glass/held_container
|
||||
var/obj/item/weapon/tank/fuel_container
|
||||
var/target_scan_ticks = 60
|
||||
var/report_num = 0
|
||||
var/scan_process = 0
|
||||
var/heat_accumulation_rate = 1
|
||||
var/temperature = 273 //measured in kelvin, if this exceeds 1200, the machine is damaged and requires repairs
|
||||
//if this exceeds 600 and safety is enabled it will shutdown
|
||||
//temp greater than 600 also requires a safety prompt to initiate scanning
|
||||
|
||||
/obj/machinery/anomaly/New()
|
||||
..()
|
||||
|
||||
//for analysis debugging
|
||||
/*var/obj/item/weapon/reagent_containers/glass/solution_tray/S = new(src.loc)
|
||||
var/turf/simulated/mineral/diamond/D
|
||||
for(var/turf/simulated/mineral/diamond/M in world)
|
||||
D = M
|
||||
break
|
||||
S.reagents.add_reagent("analysis_sample", 1, D.geological_data)
|
||||
S.reagents.add_reagent("chlorine", 1, null)*/
|
||||
|
||||
/obj/machinery/anomaly/process()
|
||||
//not sure if everything needs to heat up, or just the GLPC
|
||||
var/datum/gas_mixture/env = loc.return_air()
|
||||
var/environmental_temp = env.temperature
|
||||
if(scan_process)
|
||||
if(scan_process++ > target_scan_ticks)
|
||||
FinishScan()
|
||||
|
||||
//heat up as we go, but if the air is freezing then heat up much slower
|
||||
var/new_heat = heat_accumulation_rate + heat_accumulation_rate * rand(-5,5) / 10
|
||||
temperature += new_heat
|
||||
if(temperature > 350 && prob(10))
|
||||
src.visible_message("\blue \icon[src] bleets plaintively.", 2)
|
||||
if(temperature > 400)
|
||||
scan_process = 0
|
||||
|
||||
//show we're busy
|
||||
if(prob(5))
|
||||
src.visible_message("\blue \icon[src] [pick("whirrs","chuffs","clicks")][pick(" quietly"," softly"," sadly"," excitedly"," energetically"," angrily"," plaintively")].", 2)
|
||||
|
||||
else if(temperature > environmental_temp)
|
||||
//cool down to match the air
|
||||
temperature -= heat_accumulation_rate + heat_accumulation_rate * rand(-5,5) / 10
|
||||
if(temperature < environmental_temp)
|
||||
temperature = environmental_temp
|
||||
if(prob(5))
|
||||
src.visible_message("\blue \icon[src] hisses softly.", 2)
|
||||
|
||||
else if(temperature < environmental_temp)
|
||||
//heat up to match the air
|
||||
temperature += heat_accumulation_rate + rand(-5,5) / 10
|
||||
if(temperature > environmental_temp)
|
||||
temperature = environmental_temp
|
||||
else
|
||||
if(prob(5))
|
||||
src.visible_message("\blue \icon[src] plinks quietly.", 2)
|
||||
|
||||
//warm up the lab slightly
|
||||
if(env.temperature < temperature)
|
||||
env.temperature += (temperature - env.temperature) * 0.1
|
||||
|
||||
//this proc should be overriden by each individual machine
|
||||
/obj/machinery/anomaly/attack_hand(var/mob/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
user.machine = src
|
||||
var/dat = "<B>[src.name]</B><BR>"
|
||||
dat += "Module heat level: [temperature] kelvin<br>"
|
||||
dat += "Safeties set at 300k, shielding failure at 400k. Failure to maintain safe heat levels may result in equipment damage.<br>"
|
||||
dat += "<hr>"
|
||||
if(scan_process)
|
||||
dat += "Scan in progress<br><br><br>"
|
||||
else
|
||||
dat += "[held_container ? "<A href='?src=\ref[src];eject_beaker=1'>Eject beaker</a>" : "No beaker inserted."]<br>"
|
||||
dat += "[fuel_container ? "<A href='?src=\ref[src];eject_fuel=1'>Eject fuel tank</a>" : "No fuel tank inserted."]<br>"
|
||||
dat += "[held_container ? "<A href='?src=\ref[src];begin=1'>Begin scanning</a>" : ""]"
|
||||
dat += "<hr>"
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>Refresh</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close</a><BR>"
|
||||
user << browse(dat, "window=anomaly;size=450x500")
|
||||
onclose(user, "anomaly")
|
||||
|
||||
obj/machinery/anomaly/attackby(obj/item/weapon/W as obj, mob/living/user as mob)
|
||||
if(istype(W, /obj/item/weapon/reagent_containers/glass))
|
||||
//var/obj/item/weapon/reagent_containers/glass/G = W
|
||||
if(held_container)
|
||||
user << "\red You must remove the [held_container] first."
|
||||
else
|
||||
user << "\blue You put the [W] into the [src]."
|
||||
user.drop_item(W)
|
||||
held_container = W
|
||||
held_container.loc = src
|
||||
updateDialog()
|
||||
|
||||
else if(istype(W, /obj/item/weapon/tank))
|
||||
//var/obj/item/weapon/reagent_containers/glass/G = W
|
||||
if(fuel_container)
|
||||
user << "\red You must remove the [fuel_container] first."
|
||||
else
|
||||
user << "\blue You put the [fuel_container] into the [src]."
|
||||
user.drop_item(W)
|
||||
fuel_container.loc = src
|
||||
fuel_container = W
|
||||
updateDialog()
|
||||
else
|
||||
return ..()
|
||||
|
||||
obj/machinery/anomaly/proc/ScanResults()
|
||||
//instantiate in children to produce unique scan behaviour
|
||||
return "\red Error initialising scanning components."
|
||||
|
||||
obj/machinery/anomaly/proc/FinishScan()
|
||||
scan_process = 0
|
||||
updateDialog()
|
||||
|
||||
//determine the results and print a report
|
||||
if(held_container)
|
||||
src.visible_message("\blue \icon[src] makes an insistent chime.", 2)
|
||||
var/obj/item/weapon/paper/P = new(src.loc)
|
||||
P.name = "[src] report #[++report_num]"
|
||||
P.info = "<b>[src] analysis report #[report_num]</b><br><br>" + ScanResults()
|
||||
P.stamped = list(/obj/item/weapon/stamp)
|
||||
P.overlays = list("paper_stamped")
|
||||
else
|
||||
src.visible_message("\blue \icon[src] makes a low buzzing noise.", 2)
|
||||
|
||||
obj/machinery/anomaly/Topic(href, href_list)
|
||||
..()
|
||||
usr.set_machine(src)
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=anomaly")
|
||||
usr.machine = null
|
||||
if(href_list["eject_beaker"])
|
||||
held_container.loc = src.loc
|
||||
held_container = null
|
||||
if(href_list["eject_fuel"])
|
||||
fuel_container.loc = src.loc
|
||||
fuel_container = null
|
||||
if(href_list["begin"])
|
||||
if(temperature >= 300)
|
||||
var/proceed = input("Unsafe internal temperature detected, enter YES below to continue.","Warning")
|
||||
if(proceed == "YES" && get_dist(src, usr) <= 1)
|
||||
scan_process = 1
|
||||
else
|
||||
scan_process = 1
|
||||
|
||||
updateUsrDialog()
|
||||
|
||||
//whether the carrier sample matches the possible finds
|
||||
//results greater than a threshold of 0.6 means a positive result
|
||||
obj/machinery/anomaly/proc/GetResultSpecifity(var/datum/geosample/scanned_sample, var/carrier_name)
|
||||
var/specifity = 0
|
||||
if(scanned_sample && carrier_name)
|
||||
|
||||
if(scanned_sample.find_presence.Find(carrier_name))
|
||||
specifity = 0.75 * (scanned_sample.find_presence[carrier_name] / scanned_sample.total_spread) + 0.25
|
||||
else
|
||||
specifity = rand(0, 0.5)
|
||||
|
||||
return specifity
|
||||
@@ -0,0 +1,37 @@
|
||||
|
||||
obj/machinery/anomaly/fourier_transform
|
||||
name = "Fourier Transform spectroscope"
|
||||
|
||||
obj/machinery/anomaly/fourier_transform/ScanResults()
|
||||
var/results = "The scan was inconclusive. Check sample integrity and carrier consistency."
|
||||
|
||||
var/datum/geosample/scanned_sample
|
||||
var/carrier
|
||||
var/num_reagents = 0
|
||||
|
||||
for(var/datum/reagent/A in held_container.reagents.reagent_list)
|
||||
var/datum/reagent/R = A
|
||||
if(istype(R, /datum/reagent/analysis_sample))
|
||||
scanned_sample = R.data
|
||||
else
|
||||
carrier = R.id
|
||||
num_reagents++
|
||||
|
||||
if(num_reagents == 2 && scanned_sample && carrier)
|
||||
//all necessary components are present
|
||||
var/accuracy = GetResultSpecifity(scanned_sample, carrier)
|
||||
var/distance = scanned_sample.artifact_distance
|
||||
if(distance > 0)
|
||||
if(prob(accuracy))
|
||||
distance += (2 * rand() - 1) * distance * 0.05
|
||||
accuracy = 0.95 + 0.05 * (2 * rand() - 1)
|
||||
else
|
||||
var/offset = 1 - accuracy
|
||||
distance += (2 * rand() - 1) * distance * offset
|
||||
results = "Fourier transform analysis on anomalous energy absorption through carrier ([carrier]) indicates source located inside emission radius ([100 * accuracy]% accuracy): [distance]."
|
||||
else
|
||||
results = "Energy dispersion detected throughout sample consistent with background readings.<br>"
|
||||
if(carrier == scanned_sample.source_mineral)
|
||||
results += "Warning, analysis may be contaminated by high quantities of molecular carrier present throughout sample."
|
||||
|
||||
return results
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
obj/machinery/anomaly/gas_chromatography
|
||||
name = "Gas Chromatography spectrometer"
|
||||
|
||||
obj/machinery/anomaly/gas_chromatography/ScanResults()
|
||||
var/results = "The scan was inconclusive. Check sample integrity and carrier consistency."
|
||||
|
||||
var/datum/geosample/scanned_sample
|
||||
var/carrier
|
||||
var/num_reagents = 0
|
||||
|
||||
for(var/datum/reagent/A in held_container.reagents.reagent_list)
|
||||
var/datum/reagent/R = A
|
||||
if(istype(R, /datum/reagent/analysis_sample))
|
||||
scanned_sample = R.data
|
||||
else
|
||||
carrier = R.id
|
||||
num_reagents++
|
||||
|
||||
if(num_reagents == 2 && scanned_sample)
|
||||
|
||||
var/specifity = 0.15
|
||||
if(carrier)
|
||||
specifity = GetResultSpecifity(scanned_sample, carrier)
|
||||
results = "Chromatography partitioning analysis over carrier ([carrier]) indicates the following elements present ([110 * (specifity / (specifity + 0.1))]% accuracy):<br><br>"
|
||||
|
||||
var/num_found = 0
|
||||
for(var/index=1,index <= scanned_sample.find_presence.len, index++)
|
||||
var/find = scanned_sample.find_presence[index]
|
||||
if(find && prob( 110 * (specifity / (specifity + 0.1)) ))
|
||||
results += " - " + finds_as_strings[index] + "<br>"
|
||||
num_found++
|
||||
|
||||
if(!num_found)
|
||||
results = "Chromatography partitioning results over carrier ([carrier]) to determine elemental makeup were inconclusive.<br>"
|
||||
|
||||
if(!carrier)
|
||||
results += "<br>No carrier detected, scan accuracy affected.<br>"
|
||||
|
||||
return results
|
||||
@@ -0,0 +1,51 @@
|
||||
|
||||
obj/machinery/anomaly/hyperspectral
|
||||
name = "Hyperspectral Imager"
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "scanner"
|
||||
|
||||
obj/machinery/anomaly/hyperspectral/process()
|
||||
..()
|
||||
if(scan_process)
|
||||
icon_state = "scanner_active"
|
||||
else if(prob(10))
|
||||
icon_state = "scanner"
|
||||
flick(src, "scanner_active")
|
||||
|
||||
obj/machinery/anomaly/hyperspectral/ScanResults()
|
||||
var/results = "The scan was inconclusive. Check sample integrity and carrier consistency."
|
||||
|
||||
var/datum/geosample/scanned_sample
|
||||
var/carrier
|
||||
var/num_reagents = 0
|
||||
|
||||
for(var/datum/reagent/A in held_container.reagents.reagent_list)
|
||||
var/datum/reagent/R = A
|
||||
if(istype(R, /datum/reagent/analysis_sample))
|
||||
scanned_sample = R.data
|
||||
else
|
||||
carrier = R.id
|
||||
num_reagents++
|
||||
|
||||
if(num_reagents == 2 && scanned_sample && carrier)
|
||||
//all necessary components are present
|
||||
var/specifity = GetResultSpecifity(scanned_sample, carrier)
|
||||
results = "Spectral signature over carrier ([carrier]):<br>"
|
||||
if(specifity <= 0.25)
|
||||
results += "<img src=\"http://i.imgur.com/TAQHn.jpg\"></img><br>"
|
||||
else if(specifity <= 0.5)
|
||||
results += "<img src=\"http://i.imgur.com/EwOZ7.jpg\"></img><br>"
|
||||
else if(specifity <= 0.75)
|
||||
results += "<img src=\"http://i.imgur.com/1qCae.jpg\"></img><br>"
|
||||
else
|
||||
results += "<img src=\"http://i.imgur.com/9T9nc.jpg\"></img><br>"
|
||||
|
||||
results += "<br>"
|
||||
if(scanned_sample.artifact_id)
|
||||
results += "Detected energy signatures [100 * (1 - specifity)]% consistent with standard background readings.<br>"
|
||||
if(prob( (specifity + 0.5 * (1 - specifity)) * 100))
|
||||
results += "Anomalous exotic energy signature isolated: <font color='red'><b>[scanned_sample.artifact_id].</b></font>"
|
||||
else
|
||||
results += "Detected energy signatures [95 + 5 * (2 * rand() - 1) * (1 - specifity)]% consistent with standard background readings."
|
||||
|
||||
return results
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
obj/machinery/anomaly/ion_mobility
|
||||
name = "Ion Mobility Spectrometer"
|
||||
desc = "A specialised, complex analysis machine."
|
||||
icon = 'virology.dmi'
|
||||
icon_state = "analyser"
|
||||
|
||||
obj/machinery/anomaly/ion_mobility/ScanResults()
|
||||
var/results = "The scan was inconclusive. Check sample integrity and carrier consistency."
|
||||
|
||||
var/datum/geosample/scanned_sample
|
||||
var/carrier
|
||||
var/num_reagents = 0
|
||||
|
||||
for(var/datum/reagent/A in held_container.reagents.reagent_list)
|
||||
var/datum/reagent/R = A
|
||||
if(istype(R, /datum/reagent/analysis_sample))
|
||||
scanned_sample = R.data
|
||||
else
|
||||
carrier = R.id
|
||||
num_reagents++
|
||||
|
||||
if(num_reagents == 2 && scanned_sample && carrier)
|
||||
//all necessary components are present
|
||||
results = "Kinetic analysis on sample's ionic residue in carrier ([carrier]) indicates the dissonance spread:<br><br>"
|
||||
var/found = 0
|
||||
if(scanned_sample.find_presence.Find(carrier))
|
||||
var/dis_ratio = scanned_sample.find_presence[carrier]
|
||||
var/desc_index = responsive_carriers.Find(carrier)
|
||||
results += " - [finds_as_strings[desc_index]]: [dis_ratio]<br>"
|
||||
found++
|
||||
/*
|
||||
for(var/index=1,index <= scanned_sample.find_presence.len, index++)
|
||||
var/find = scanned_sample.find_presence[index]
|
||||
//world << "index: [index], find: [find], response: [responsive_carriers[index]], carrier: [carrier]"
|
||||
if(find && responsive_carriers[index] == carrier)
|
||||
results += " - [finds_as_strings[index]] [find * 100]%<br>"
|
||||
found++
|
||||
*/
|
||||
if(!found)
|
||||
results = "Kinetic analysis on sample's ionic residue in carrier ([carrier]) to determine composition were inconclusive.<br>"
|
||||
if(carrier == scanned_sample.source_mineral)
|
||||
results += "Warning, analysis may be contaminated by high quantities of molecular carrier present throughout sample."
|
||||
|
||||
return results
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
obj/machinery/anomaly/isotope_ratio
|
||||
name = "Isotope ratio spectrometer"
|
||||
desc = "A specialised, complex analysis machine."
|
||||
icon = 'virology.dmi'
|
||||
icon_state = "analyser"
|
||||
|
||||
obj/machinery/anomaly/isotope_ratio/ScanResults()
|
||||
var/results = "The scan was inconclusive. Check sample integrity and carrier consistency."
|
||||
|
||||
var/datum/geosample/scanned_sample
|
||||
var/carrier_name
|
||||
var/num_reagents = 0
|
||||
|
||||
for(var/datum/reagent/A in held_container.reagents.reagent_list)
|
||||
var/datum/reagent/R = A
|
||||
if(istype(R, /datum/reagent/analysis_sample))
|
||||
scanned_sample = R.data
|
||||
else
|
||||
carrier_name = R.id
|
||||
num_reagents++
|
||||
|
||||
if(num_reagents == 2 && scanned_sample && carrier_name)
|
||||
var/accuracy = GetResultSpecifity(scanned_sample, carrier_name)
|
||||
accuracy += 0.5 * (1 - accuracy) / scanned_sample.total_spread
|
||||
if(!accuracy)
|
||||
accuracy = rand(0.01, 0.5)
|
||||
results = "Isotope decay analysis in carrier ([carrier_name]) indicates age ([100 * accuracy]% accuracy): <br><br>"
|
||||
|
||||
if(scanned_sample.age_billion)
|
||||
//scramble the results
|
||||
var/displayed_age_thousands = rand(0, 999)
|
||||
var/displayed_age_millions = rand(0, 999)
|
||||
results += "[displayed_age_millions + displayed_age_thousands / 1000] million years.<br>"
|
||||
else if(scanned_sample.age_million)
|
||||
var/displayed_age_thousands = scanned_sample.age_thousand + max(scanned_sample.age_thousand * ((1 - accuracy) * (2 * rand() - 1)), 0)
|
||||
var/displayed_age_millions = scanned_sample.age_million + max(scanned_sample.age_million * ((1 - accuracy) * (4 * rand() - 2)), 0)
|
||||
results += "[displayed_age_millions + displayed_age_thousands / 1000] million years.<br>"
|
||||
else if(scanned_sample.age_thousand)
|
||||
var/displayed_age = scanned_sample.age + scanned_sample.age * ((1 - accuracy) * (2 * rand() - 1))
|
||||
var/displayed_age_thousands = scanned_sample.age_thousand + max(scanned_sample.age_thousand * ((1 - accuracy) * (2 * rand() - 1)), 0)
|
||||
results += "[displayed_age_thousands + displayed_age / 1000] thousand years.<br>"
|
||||
else
|
||||
var/displayed_age = scanned_sample.age + max(scanned_sample.age * ((1 - accuracy) * (2 * rand() - 1)), 0)
|
||||
results += "[displayed_age] years.<br>"
|
||||
|
||||
results += "<br>Warning, results only valid up to ages of one billion years."
|
||||
|
||||
return results
|
||||
@@ -0,0 +1,251 @@
|
||||
|
||||
/obj/machinery/artifact_analyser
|
||||
name = "Anomaly Analyser"
|
||||
desc = "Studies the emissions of anomalous materials to discover their uses."
|
||||
icon = 'icons/obj/virology.dmi'
|
||||
icon_state = "isolator"
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/scan_in_progress = 0
|
||||
var/scan_num = 0
|
||||
var/obj/scanned_obj
|
||||
var/obj/machinery/artifact_scanpad/owned_scanner = null
|
||||
var/scan_completion_time = 0
|
||||
var/scan_duration = 120
|
||||
var/obj/scanned_object
|
||||
var/report_num = 0
|
||||
|
||||
/obj/machinery/artifact_analyser/New()
|
||||
..()
|
||||
reconnect_scanner()
|
||||
|
||||
/obj/machinery/artifact_analyser/proc/reconnect_scanner()
|
||||
//connect to a nearby scanner pad
|
||||
owned_scanner = locate(/obj/machinery/artifact_scanpad) in get_step(src, dir)
|
||||
if(!owned_scanner)
|
||||
owned_scanner = locate(/obj/machinery/artifact_scanpad) in orange(1, src)
|
||||
|
||||
/obj/machinery/artifact_analyser/attack_hand(var/mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/artifact_analyser/interact(mob/user)
|
||||
if(stat & (NOPOWER|BROKEN) || get_dist(src, user) > 1)
|
||||
user.unset_machine(src)
|
||||
return
|
||||
|
||||
var/dat = "<B>Anomalous material analyser</B><BR>"
|
||||
dat += "<HR>"
|
||||
if(!owned_scanner)
|
||||
owned_scanner = locate() in orange(1, src)
|
||||
|
||||
if(!owned_scanner)
|
||||
dat += "<b><font color=red>Unable to locate analysis pad.</font></b><br>"
|
||||
else if(scan_in_progress)
|
||||
dat += "Please wait. Analysis in progress.<br>"
|
||||
dat += "<a href='?src=\ref[src];halt_scan=1'>Halt scanning.</a><br>"
|
||||
else
|
||||
dat += "Scanner is ready.<br>"
|
||||
dat += "<a href='?src=\ref[src];begin_scan=1'>Begin scanning.</a><br>"
|
||||
|
||||
dat += "<br>"
|
||||
dat += "<hr>"
|
||||
dat += "<a href='?src=\ref[src]'>Refresh</a> <a href='?src=\ref[src];close=1'>Close</a>"
|
||||
user << browse(dat, "window=artanalyser;size=450x500")
|
||||
user.set_machine(src)
|
||||
onclose(user, "artanalyser")
|
||||
|
||||
/obj/machinery/artifact_analyser/process()
|
||||
if(scan_in_progress && world.time > scan_completion_time)
|
||||
//finish scanning
|
||||
scan_in_progress = 0
|
||||
updateDialog()
|
||||
|
||||
//print results
|
||||
var/results = ""
|
||||
if(!owned_scanner)
|
||||
reconnect_scanner()
|
||||
if(!owned_scanner)
|
||||
results = "Error communicating with scanner."
|
||||
else if(!scanned_object || scanned_object.loc != owned_scanner.loc)
|
||||
results = "Unable to locate scanned object. Ensure it was not moved in the process."
|
||||
else
|
||||
results = get_scan_info(scanned_object)
|
||||
|
||||
src.visible_message("<b>[name]</b> states, \"Scanning complete.\"")
|
||||
var/obj/item/weapon/paper/P = new(src.loc)
|
||||
P.name = "[src] report #[++report_num]"
|
||||
P.info = "<b>[src] analysis report #[report_num]</b><br>"
|
||||
P.info += "<br>"
|
||||
P.info += "\icon[scanned_object] [results]"
|
||||
P.stamped = list(/obj/item/weapon/stamp)
|
||||
P.overlays = list("paper_stamped")
|
||||
|
||||
if(scanned_object && istype(scanned_object, /obj/machinery/artifact))
|
||||
var/obj/machinery/artifact/A = scanned_object
|
||||
A.anchored = 0
|
||||
A.being_used = 0
|
||||
|
||||
/obj/machinery/artifact_analyser/Topic(href, href_list)
|
||||
if(href_list["begin_scan"])
|
||||
if(!owned_scanner)
|
||||
reconnect_scanner()
|
||||
if(owned_scanner)
|
||||
var/artifact_in_use = 0
|
||||
for(var/obj/O in owned_scanner.loc)
|
||||
if(O == owned_scanner)
|
||||
continue
|
||||
if(O.invisibility)
|
||||
continue
|
||||
if(istype(scanned_object, /obj/machinery/artifact))
|
||||
var/obj/machinery/artifact/A = scanned_object
|
||||
if(A.being_used)
|
||||
artifact_in_use = 1
|
||||
else
|
||||
A.anchored = 1
|
||||
A.being_used = 1
|
||||
|
||||
if(artifact_in_use)
|
||||
src.visible_message("<b>[name]</b> states, \"Cannot harvest. Too much interference.\"")
|
||||
else
|
||||
scanned_object = O
|
||||
scan_in_progress = 1
|
||||
scan_completion_time = world.time + scan_duration
|
||||
src.visible_message("<b>[name]</b> states, \"Scanning begun.\"")
|
||||
break
|
||||
if(!scanned_object)
|
||||
src.visible_message("<b>[name]</b> states, \"Unable to isolate scan target.\"")
|
||||
if(href_list["halt_scan"])
|
||||
scan_in_progress = 0
|
||||
src.visible_message("<b>[name]</b> states, \"Scanning halted.\"")
|
||||
|
||||
if(href_list["close"])
|
||||
usr.unset_machine(src)
|
||||
usr << browse(null, "window=artanalyser")
|
||||
|
||||
..()
|
||||
updateDialog()
|
||||
|
||||
//hardcoded responses, oh well
|
||||
/obj/machinery/artifact_analyser/proc/get_scan_info(var/obj/scanned_obj)
|
||||
switch(scanned_obj.type)
|
||||
if(/obj/machinery/auto_cloner)
|
||||
return "Automated cloning pod - appears to rely on organic nanomachines with a self perpetuating \
|
||||
ecosystem involving self cannibalism and a symbiotic relationship with the contained liquid.<br><br>\
|
||||
Structure is composed of a carbo-titanium alloy with interlaced reinforcing energy fields, and the contained liquid \
|
||||
resembles proto-plasmic residue supportive of single cellular developmental conditions."
|
||||
if(/obj/machinery/power/supermatter)
|
||||
return "Super dense plasma clump - Appears to have been shaped or hewn, structure is composed of matter 2000% denser than ordinary carbon matter residue.\
|
||||
Potential application as unrefined plasma source."
|
||||
if(/obj/machinery/power/supermatter)
|
||||
return "Super dense plasma clump - Appears to have been shaped or hewn, structure is composed of matter 2000% denser than ordinary carbon matter residue.\
|
||||
Potential application as unrefined plasma source."
|
||||
if(/obj/structure/constructshell)
|
||||
return "Tribal idol - Item resembles statues/emblems built by superstitious pre-warp civilisations to honour their gods. Material appears to be a \
|
||||
rock/plastcrete composite."
|
||||
if(/obj/machinery/giga_drill)
|
||||
return "Automated mining drill - structure composed of titanium-carbide alloy, with tip and drill lines edged in an alloy of diamond and plasma."
|
||||
if(/obj/structure/cult/pylon)
|
||||
return "Tribal pylon - Item resembles statues/emblems built by cargo cult civilisations to honour energy systems from post-warp civilisations."
|
||||
if(/obj/mecha/working/hoverpod)
|
||||
return "Vacuum capable repair pod - Item is a remarkably intact single man repair craft capable of flight in a vacuum. Outer shell composed of primarily \
|
||||
post-warp hull alloys, with internal wiring and circuitry consistent with modern electronics and engineering."
|
||||
if(/obj/machinery/replicator)
|
||||
return "Automated construction unit - Item appears to be able to synthesize synthetic items, some with simple internal circuitry. Method unknown, \
|
||||
phasing suggested?"
|
||||
if(/obj/structure/crystal)
|
||||
return "Crystal formation - Pseudo organic crystalline matrix, unlikely to have formed naturally. No known technology exists to synthesize this exact composition."
|
||||
if(/obj/machinery/artifact)
|
||||
//the fun one
|
||||
var/obj/machinery/artifact/A = scanned_obj
|
||||
var/out = "Anomalous alien device - Composed of an unknown alloy, "
|
||||
|
||||
//primary effect
|
||||
if(A.my_effect)
|
||||
//what kind of effect the artifact has
|
||||
switch(A.my_effect.effect_type)
|
||||
if(1)
|
||||
out += "concentrated energy emissions"
|
||||
if(2)
|
||||
out += "intermittent psionic wavefront"
|
||||
if(3)
|
||||
out += "electromagnetic energy"
|
||||
if(4)
|
||||
out += "high frequency particles"
|
||||
if(5)
|
||||
out += "organically reactive exotic particles"
|
||||
if(6)
|
||||
out += "interdimensional/bluespace? phasing"
|
||||
if(7)
|
||||
out += "atomic synthesis"
|
||||
else
|
||||
out += "low level energy emissions"
|
||||
out += " have been detected "
|
||||
|
||||
//how the artifact does it's effect
|
||||
switch(A.my_effect.effect_type)
|
||||
if(1)
|
||||
out += " emitting in an ambient energy field."
|
||||
if(2)
|
||||
out += " emitting in periodic bursts."
|
||||
else
|
||||
out += " interspersed throughout substructure and shell."
|
||||
|
||||
if(A.my_effect.trigger >= 0 && A.my_effect.trigger <= 4)
|
||||
out += " Activation index involves physical interaction with artifact surface."
|
||||
else if(A.my_effect.trigger >= 5 && A.my_effect.trigger <= 8)
|
||||
out += " Activation index involves energetic interaction with artifact surface."
|
||||
else if(A.my_effect.trigger >= 9 && A.my_effect.trigger <= 12)
|
||||
out += " Activation index involves precise local atmospheric conditions."
|
||||
else
|
||||
out += " Unable to determine any data about activation trigger."
|
||||
|
||||
//secondary:
|
||||
if(A.secondary_effect && A.secondary_effect.activated)
|
||||
//sciencey words go!
|
||||
out += "<br><br>Warning, internal scans indicate ongoing [pick("subluminous","subcutaneous","superstructural")] activity operating \
|
||||
independantly from primary systems. Auxiliary activity involves "
|
||||
|
||||
//what kind of effect the artifact has
|
||||
switch(A.secondary_effect.effect_type)
|
||||
if(1)
|
||||
out += "concentrated energy emissions"
|
||||
if(2)
|
||||
out += "intermittent psionic wavefront"
|
||||
if(3)
|
||||
out += "electromagnetic energy"
|
||||
if(4)
|
||||
out += "high frequency particles"
|
||||
if(5)
|
||||
out += "organically reactive exotic particles"
|
||||
if(6)
|
||||
out += "interdimensional/bluespace? phasing"
|
||||
if(7)
|
||||
out += "atomic synthesis"
|
||||
else
|
||||
out += "low level radiation"
|
||||
|
||||
//how the artifact does it's effect
|
||||
switch(A.secondary_effect.effect_type)
|
||||
if(1)
|
||||
out += " emitting in an ambient energy field."
|
||||
if(2)
|
||||
out += " emitting in periodic bursts."
|
||||
else
|
||||
out += " interspersed throughout substructure and shell."
|
||||
|
||||
if(A.secondary_effect.trigger >= 0 && A.secondary_effect.trigger <= 4)
|
||||
out += " Activation index involves physical interaction with artifact surface, but subsystems indicate \
|
||||
anomalous interference with standard attempts at triggering."
|
||||
else if(A.secondary_effect.trigger >= 5 && A.secondary_effect.trigger <= 8)
|
||||
out += " Activation index involves energetic interaction with artifact surface, but subsystems indicate \
|
||||
anomalous interference with standard attempts at triggering."
|
||||
else if(A.secondary_effect.trigger >= 9 && A.secondary_effect.trigger <= 12)
|
||||
out += " Activation index involves precise local atmospheric conditions, but subsystems indicate \
|
||||
anomalous interference with standard attempts at triggering."
|
||||
else
|
||||
out += " Unable to determine any data about activation trigger."
|
||||
return out
|
||||
else
|
||||
//it was an ordinary item
|
||||
return "[scanned_obj.name] - Mundane application, composed of carbo-ferritic alloy composite."
|
||||
@@ -1,318 +1,318 @@
|
||||
|
||||
//cael - some changes here. the analysis pad is entirely new
|
||||
|
||||
/obj/machinery/artifact_analyser
|
||||
name = "Artifact Analyser"
|
||||
desc = "Studies the structure of artifacts to discover their uses."
|
||||
icon = 'virology.dmi'
|
||||
icon_state = "analyser"
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/working = 0
|
||||
var/accuO = 0
|
||||
var/accuT = 0
|
||||
var/accuE1 = 0
|
||||
var/accuE2 = 0
|
||||
var/aorigin = "None"
|
||||
var/atrigger = "None"
|
||||
var/aeffect1 = "None"
|
||||
var/aeffect2 = "None"
|
||||
var/list/origin_bonuses
|
||||
var/list/trigger_bonuses
|
||||
var/list/function_bonuses
|
||||
var/list/range_bonuses
|
||||
var/cur_id = ""
|
||||
var/scan_num = 0
|
||||
var/obj/machinery/artifact/cur_artifact = null
|
||||
var/obj/machinery/analyser_pad/owned_pad = null
|
||||
var/list/allorigins = list("Ancient Robots","Martian","Wizard Federation","Extradimensional","Precursor")
|
||||
var/list/alltriggers = list("Contact with Living Organism","Heavy Impact","Contact with Energy Source","Contact with Hydrogen","Contact with Corrosive Substance","Contact with Volatile Substance","Contact with Toxins","Exposure to Heat")
|
||||
var/list/alleffects = list("Healing Device","Anti-biological Weapon","Non-lethal Stunning Trap","Mechanoid Repair Module","Mechanoid Deconstruction Device","Power Generator","Power Drain","Stellar Mineral Attractor","Agriculture Regulator","Shield Generator","Space-Time Displacer")
|
||||
var/list/allranges = list("Constant Short-Range Energy Field","Medium Range Energy Pulses","Long Range Energy Pulses","Extreme Range Energy Pulses","Requires contact with subject")
|
||||
|
||||
/obj/machinery/artifact_analyser/New()
|
||||
..()
|
||||
origin_bonuses = new/list()
|
||||
origin_bonuses["ancient"] = 0
|
||||
origin_bonuses["martian"] = 0
|
||||
origin_bonuses["wizard"] = 0
|
||||
origin_bonuses["eldritch"] = 0
|
||||
origin_bonuses["precursor"] = 0
|
||||
trigger_bonuses = new/list()
|
||||
trigger_bonuses["ancient"] = 0
|
||||
trigger_bonuses["martian"] = 0
|
||||
trigger_bonuses["wizard"] = 0
|
||||
trigger_bonuses["eldritch"] = 0
|
||||
trigger_bonuses["precursor"] = 0
|
||||
function_bonuses = new/list()
|
||||
function_bonuses["ancient"] = 0
|
||||
function_bonuses["martian"] = 0
|
||||
function_bonuses["wizard"] = 0
|
||||
function_bonuses["eldritch"] = 0
|
||||
function_bonuses["precursor"] = 0
|
||||
range_bonuses = new/list()
|
||||
range_bonuses["ancient"] = 0
|
||||
range_bonuses["martian"] = 0
|
||||
range_bonuses["wizard"] = 0
|
||||
range_bonuses["eldritch"] = 0
|
||||
range_bonuses["precursor"] = 0
|
||||
//
|
||||
spawn(10)
|
||||
owned_pad = locate() in orange(1, src)
|
||||
|
||||
/obj/machinery/artifact_analyser/attack_hand(var/mob/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
user.machine = src
|
||||
var/dat = "<B>Artifact Analyser</B><BR>"
|
||||
dat += "<HR><BR>"
|
||||
if(!owned_pad)
|
||||
dat += "<B><font color=red>Unable to locate analysis pad.</font><BR></b>"
|
||||
dat += "<HR><BR>"
|
||||
else if (!src.working)
|
||||
dat += "<B>Artifact ID:</B> [cur_id]<BR>"
|
||||
dat += "<B>Artifact Origin:</B> [aorigin] ([accuO]%)<BR>"
|
||||
dat += "<B>Activation Trigger:</B> [atrigger] ([accuT]%)<BR>"
|
||||
dat += "<B>Artifact Function:</B> [aeffect1] ([accuE1]%)<BR>"
|
||||
dat += "<B>Artifact Range:</B> [aeffect2] ([accuE2]%)<BR><BR>"
|
||||
dat += "<HR><BR>"
|
||||
dat += "Artifact ID is determined from unique energy emission signatures.<br>"
|
||||
dat += "<A href='?src=\ref[src];analyse=1'>Analyse Artifact (Scan number #[scan_num+1])</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];upload=1'>Upload/update artifact scan</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];print=1'>Print Page</a><BR>"
|
||||
else
|
||||
dat += "<B>Please wait. Analysis in progress.</B><BR>"
|
||||
dat += "<HR><BR>"
|
||||
//
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close<BR>"
|
||||
user << browse(dat, "window=artanalyser;size=450x500")
|
||||
onclose(user, "artanalyser")
|
||||
|
||||
/obj/machinery/artifact_analyser/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
use_power(350)
|
||||
//
|
||||
if(!owned_pad)
|
||||
for(var/obj/machinery/analyser_pad/pad in range(1))
|
||||
owned_pad = pad
|
||||
break
|
||||
|
||||
/obj/machinery/artifact_analyser/proc/AA_FailedAnalysis(var/failtype)
|
||||
switch(failtype)
|
||||
if(1)
|
||||
src.aorigin = "Failed to Identify"
|
||||
if (prob(20)) src.aorigin = pick(src.allorigins)
|
||||
if(2)
|
||||
src.atrigger = "Failed to Identify"
|
||||
if (prob(20)) src.atrigger = pick(src.alltriggers)
|
||||
if(3)
|
||||
src.aeffect1 = "Failed to Identify"
|
||||
if (prob(20)) src.aeffect1 = pick(src.alleffects)
|
||||
if(4)
|
||||
src.aeffect2 = "Failed to Identify"
|
||||
if (prob(20)) src.aeffect2 = pick(src.allranges)
|
||||
|
||||
/obj/machinery/artifact_analyser/proc/AA_Analyse()
|
||||
if(!cur_artifact)
|
||||
return
|
||||
src.accuO = 5 + rand(0,10) + origin_bonuses[cur_artifact.origin] + cur_artifact.activated * 50
|
||||
src.accuT = 5 + rand(0,10) + trigger_bonuses[cur_artifact.origin] + cur_artifact.activated * 50
|
||||
src.accuE1 = 5 + rand(0,10) + function_bonuses[cur_artifact.origin] + cur_artifact.activated * 50
|
||||
src.accuE2 = 5 + rand(0,10) + range_bonuses[cur_artifact.origin] + cur_artifact.activated * 50
|
||||
|
||||
//keep any correctly determined properties the same
|
||||
var/origin_correct = 0
|
||||
var/trigger_correct = 0
|
||||
var/function_correct = 0
|
||||
var/range_correct = 0
|
||||
if(cur_id == cur_artifact.display_id)
|
||||
if(src.aorigin == cur_artifact.origin)
|
||||
origin_correct = 1
|
||||
|
||||
if(src.atrigger == cur_artifact.my_effect.trigger)
|
||||
trigger_correct = 1
|
||||
else if(src.atrigger == cur_artifact.my_effect.triggerX)
|
||||
trigger_correct = 1
|
||||
|
||||
if(src.aeffect1 == cur_artifact.my_effect.effecttype)
|
||||
function_correct = 1
|
||||
|
||||
if(src.aeffect2 == cur_artifact.my_effect.effectmode)
|
||||
range_correct = 1
|
||||
|
||||
if (src.accuO > 100) src.accuO = 100
|
||||
if (src.accuT > 100) src.accuT = 100
|
||||
if (src.accuE1 > 100) src.accuE1 = 100
|
||||
if (src.accuE2 > 100) src.accuE2 = 100
|
||||
// Roll to generate report
|
||||
if (prob(accuO) || origin_correct)
|
||||
switch(cur_artifact.origin)
|
||||
if("ancient") src.aorigin = "Ancient Robots"
|
||||
if("martian") src.aorigin = "Martian"
|
||||
if("wizard") src.aorigin = "Wizard Federation"
|
||||
if("eldritch") src.aorigin = "Extradimensional"
|
||||
if("precursor") src.aorigin = "Precursor"
|
||||
else src.aorigin = "Unknown Origin"
|
||||
origin_bonuses[cur_artifact.origin] += 10
|
||||
else
|
||||
AA_FailedAnalysis(1)
|
||||
origin_bonuses[cur_artifact.origin] += 5
|
||||
if (prob(accuT) || trigger_correct)
|
||||
switch(cur_artifact.my_effect.trigger)
|
||||
if("touch") src.atrigger = "Contact with Living Organism"
|
||||
if("force") src.atrigger = "Heavy Impact"
|
||||
if("energy") src.atrigger = "Contact with Energy Source"
|
||||
if("chemical")
|
||||
switch(cur_artifact.my_effect.triggerX)
|
||||
if("hydrogen") src.atrigger = "Contact with Hydrogen"
|
||||
if("corrosive") src.atrigger = "Contact with Corrosive Substance"
|
||||
if("volatile") src.atrigger = "Contact with Volatile Substance"
|
||||
if("toxin") src.atrigger = "Contact with Toxins"
|
||||
if("heat") src.atrigger = "Exposure to Heat"
|
||||
else src.atrigger = "Unknown Trigger"
|
||||
trigger_bonuses[cur_artifact.origin] += 5
|
||||
else
|
||||
AA_FailedAnalysis(2)
|
||||
trigger_bonuses[cur_artifact.origin] += 1
|
||||
if (prob(accuE1) || function_correct)
|
||||
switch(cur_artifact.my_effect.effecttype)
|
||||
if("healing") src.aeffect1 = "Healing Device"
|
||||
if("injure") src.aeffect1 = "Anti-biological Weapon"
|
||||
// if("stun") src.aeffect1 = "Non-lethal Stunning Trap"
|
||||
if("roboheal") src.aeffect1 = "Mechanoid Repair Module"
|
||||
if("robohurt") src.aeffect1 = "Mechanoid Deconstruction Device"
|
||||
if("cellcharge") src.aeffect1 = "Power Generator"
|
||||
if("celldrain") src.aeffect1 = "Power Drain"
|
||||
if("planthelper") src.aeffect1 = "Agriculture Regulator"
|
||||
if("forcefield") src.aeffect1 = "Shield Generator"
|
||||
if("teleport") src.aeffect1 = "Space-Time Displacer"
|
||||
else src.aeffect1 = "Unknown Effect"
|
||||
function_bonuses[cur_artifact.origin] += 5
|
||||
else
|
||||
AA_FailedAnalysis(3)
|
||||
function_bonuses[cur_artifact.origin] += 1
|
||||
if (prob(accuE2) || range_correct)
|
||||
switch(cur_artifact.my_effect.effectmode)
|
||||
if("aura") src.aeffect2 = "Constant Short-Range Energy Field"
|
||||
if("pulse")
|
||||
if(cur_artifact.my_effect.aurarange > 7) src.aeffect2 = "Long Range Energy Pulses"
|
||||
else src.aeffect2 = "Medium Range Energy Pulses"
|
||||
if("worldpulse") src.aeffect2 = "Extreme Range Energy Pulses"
|
||||
if("contact") src.aeffect2 = "Requires contact with subject"
|
||||
else src.aeffect2 = "Unknown Range"
|
||||
range_bonuses[cur_artifact.origin] += 5
|
||||
else
|
||||
AA_FailedAnalysis(4)
|
||||
range_bonuses[cur_artifact.origin] += 1
|
||||
|
||||
cur_artifact.name = "alien artifact ([cur_artifact.display_id])"
|
||||
cur_artifact.desc = "A large alien device. It has a small tag near the bottom that reads \"[cur_artifact.display_id]\"."
|
||||
cur_id = cur_artifact.display_id
|
||||
cur_artifact.my_effect.artifact_id = cur_artifact.display_id
|
||||
|
||||
/obj/machinery/artifact_analyser/Topic(href, href_list)
|
||||
|
||||
if(href_list["analyse"])
|
||||
if(owned_pad)
|
||||
var/turf/pad_turf = get_turf(owned_pad)
|
||||
var/findarti = 0
|
||||
for(var/obj/machinery/artifact/A in pad_turf.contents)
|
||||
findarti++
|
||||
cur_artifact = A
|
||||
if (findarti == 1)
|
||||
if(cur_artifact && cur_artifact.being_used)
|
||||
var/message = "<b>[src]</b> states, \"Cannot analyse. Excess energy drain is disrupting signal.\""
|
||||
src.visible_message(message, message)
|
||||
else
|
||||
cur_artifact.anchored = 1
|
||||
cur_artifact.being_used = 1
|
||||
src.working = 1
|
||||
src.icon_state = "analyser_processing"
|
||||
var/time = rand(30,50) + max(0, 300 - scan_num * 10)
|
||||
/*for(var/i = artifact_research.starting_tier, i <= artifact_research.max_tiers, i++)
|
||||
for(var/datum/artiresearch/R in artifact_research.researched_items[i])
|
||||
if (R.bonustype == "analyser") time -= R.bonusTime*/
|
||||
time *= 10
|
||||
var/message = "<b>[src]</b> states, \"Commencing analysis.\""
|
||||
src.visible_message(message, message)
|
||||
use_power(500)
|
||||
spawn(time)
|
||||
src.working = 0
|
||||
icon_state = "analyser"
|
||||
cur_artifact.anchored = 0
|
||||
cur_artifact.being_used = 0
|
||||
if(cur_artifact.loc == pad_turf)
|
||||
AA_Analyse()
|
||||
scan_num++
|
||||
message = "<b>[src]</b> states, \"Analysis complete.\""
|
||||
src.visible_message(message, message)
|
||||
use_power(500)
|
||||
else if (findarti > 1)
|
||||
var/message = "<b>[src]</b> states, \"Cannot analyse. Error isolating energy signature.\""
|
||||
src.visible_message(message, message)
|
||||
else
|
||||
var/message = "<b>[src]</b> states, \"Cannot analyse. No noteworthy energy signature isolated.\""
|
||||
src.visible_message(message, message)
|
||||
|
||||
if(href_list["upload"] && cur_id != "")
|
||||
//add new datum to every DB in the world
|
||||
for(var/obj/machinery/computer/artifact_database/DB in world)
|
||||
var/update = 0
|
||||
for(var/datum/catalogued_artifact/CA in DB.catalogued_artifacts)
|
||||
if(CA.display_id == cur_id)
|
||||
//already there, so update it
|
||||
update = 1
|
||||
CA.origin = aorigin + " ([accuO]%)"
|
||||
CA.trigger = atrigger + " ([accuT]%)"
|
||||
CA.effecttype = aeffect1 + " ([accuE1]%)"
|
||||
CA.effectmode = aeffect2 + " ([accuE2]%)"
|
||||
if(!update)
|
||||
//not there, so add it
|
||||
var/datum/catalogued_artifact/CA = new()
|
||||
CA.display_id = cur_id
|
||||
CA.origin = aorigin + " ([accuO]%)"
|
||||
CA.trigger = atrigger + " ([accuT]%)"
|
||||
CA.effecttype = aeffect1 + " ([accuE1]%)"
|
||||
CA.effectmode = aeffect2 + " ([accuE2]%)"
|
||||
DB.catalogued_artifacts.Add(CA)
|
||||
use_power(100)
|
||||
|
||||
if(href_list["print"])
|
||||
var/r = "Artifact Analysis Report (Scan #[scan_num])<hr>"
|
||||
r += "<B>Artifact ID:</B> [cur_id] (determined from unique energy emission signatures)<BR>"
|
||||
r += "<B>Artifact Origin:</B> [aorigin] ([accuO]%)<BR>"
|
||||
r += "<B>Activation Trigger:</B> [atrigger] ([accuT]%)<BR>"
|
||||
r += "<B>Artifact Function:</B> [aeffect1] ([accuE1]%)<BR>"
|
||||
r += "<B>Artifact Range:</B> [aeffect2] ([accuE2]%)<BR><BR>"
|
||||
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(src.loc)
|
||||
P.name = "Artifact Analysis Report #[scan_num]"
|
||||
P.info = r
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message("\icon[src] \blue The [src.name] prints a sheet of paper", 3)
|
||||
use_power(10)
|
||||
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=artanalyser")
|
||||
usr.machine = null
|
||||
|
||||
src.updateDialog()
|
||||
|
||||
//stick artifacts onto this then switch the analyser on
|
||||
/obj/machinery/analyser_pad
|
||||
name = "artifact analysis pad"
|
||||
desc = "Studies the structure of artifacts to discover their uses."
|
||||
icon = 'stationobjs.dmi'
|
||||
icon_state = "tele0"
|
||||
anchored = 1
|
||||
density = 0
|
||||
|
||||
/obj/machinery/analyser_pad/New()
|
||||
..()
|
||||
/*spawn(10)
|
||||
for(var/obj/machinery/artifact_analyser/analyser in orange(1))
|
||||
world << "pad found analyser"
|
||||
if(!analyser.owned_pad)
|
||||
analyser.owned_pad = src
|
||||
world << "pad set analyser to self"
|
||||
break*/
|
||||
|
||||
//cael - some changes here. the analysis pad is entirely new
|
||||
|
||||
/obj/machinery/artifact_analyser
|
||||
name = "Artifact Analyser"
|
||||
desc = "Studies the structure of artifacts to discover their uses."
|
||||
icon = 'virology.dmi'
|
||||
icon_state = "analyser"
|
||||
anchored = 1
|
||||
density = 1
|
||||
var/working = 0
|
||||
var/accuO = 0
|
||||
var/accuT = 0
|
||||
var/accuE1 = 0
|
||||
var/accuE2 = 0
|
||||
var/aorigin = "None"
|
||||
var/atrigger = "None"
|
||||
var/aeffect1 = "None"
|
||||
var/aeffect2 = "None"
|
||||
var/list/origin_bonuses
|
||||
var/list/trigger_bonuses
|
||||
var/list/function_bonuses
|
||||
var/list/range_bonuses
|
||||
var/cur_id = ""
|
||||
var/scan_num = 0
|
||||
var/obj/machinery/artifact/cur_artifact = null
|
||||
var/obj/machinery/analyser_pad/owned_pad = null
|
||||
var/list/allorigins = list("Ancient Robots","Martian","Wizard Federation","Extradimensional","Precursor")
|
||||
var/list/alltriggers = list("Contact with Living Organism","Heavy Impact","Contact with Energy Source","Contact with Hydrogen","Contact with Corrosive Substance","Contact with Volatile Substance","Contact with Toxins","Exposure to Heat")
|
||||
var/list/alleffects = list("Healing Device","Anti-biological Weapon","Non-lethal Stunning Trap","Mechanoid Repair Module","Mechanoid Deconstruction Device","Power Generator","Power Drain","Stellar Mineral Attractor","Agriculture Regulator","Shield Generator","Space-Time Displacer")
|
||||
var/list/allranges = list("Constant Short-Range Energy Field","Medium Range Energy Pulses","Long Range Energy Pulses","Extreme Range Energy Pulses","Requires contact with subject")
|
||||
|
||||
/obj/machinery/artifact_analyser/New()
|
||||
..()
|
||||
origin_bonuses = new/list()
|
||||
origin_bonuses["ancient"] = 0
|
||||
origin_bonuses["martian"] = 0
|
||||
origin_bonuses["wizard"] = 0
|
||||
origin_bonuses["eldritch"] = 0
|
||||
origin_bonuses["precursor"] = 0
|
||||
trigger_bonuses = new/list()
|
||||
trigger_bonuses["ancient"] = 0
|
||||
trigger_bonuses["martian"] = 0
|
||||
trigger_bonuses["wizard"] = 0
|
||||
trigger_bonuses["eldritch"] = 0
|
||||
trigger_bonuses["precursor"] = 0
|
||||
function_bonuses = new/list()
|
||||
function_bonuses["ancient"] = 0
|
||||
function_bonuses["martian"] = 0
|
||||
function_bonuses["wizard"] = 0
|
||||
function_bonuses["eldritch"] = 0
|
||||
function_bonuses["precursor"] = 0
|
||||
range_bonuses = new/list()
|
||||
range_bonuses["ancient"] = 0
|
||||
range_bonuses["martian"] = 0
|
||||
range_bonuses["wizard"] = 0
|
||||
range_bonuses["eldritch"] = 0
|
||||
range_bonuses["precursor"] = 0
|
||||
//
|
||||
spawn(10)
|
||||
owned_pad = locate() in orange(1, src)
|
||||
|
||||
/obj/machinery/artifact_analyser/attack_hand(var/mob/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
user.machine = src
|
||||
var/dat = "<B>Artifact Analyser</B><BR>"
|
||||
dat += "<HR><BR>"
|
||||
if(!owned_pad)
|
||||
dat += "<B><font color=red>Unable to locate analysis pad.</font><BR></b>"
|
||||
dat += "<HR><BR>"
|
||||
else if (!src.working)
|
||||
dat += "<B>Artifact ID:</B> [cur_id]<BR>"
|
||||
dat += "<B>Artifact Origin:</B> [aorigin] ([accuO]%)<BR>"
|
||||
dat += "<B>Activation Trigger:</B> [atrigger] ([accuT]%)<BR>"
|
||||
dat += "<B>Artifact Function:</B> [aeffect1] ([accuE1]%)<BR>"
|
||||
dat += "<B>Artifact Range:</B> [aeffect2] ([accuE2]%)<BR><BR>"
|
||||
dat += "<HR><BR>"
|
||||
dat += "Artifact ID is determined from unique energy emission signatures.<br>"
|
||||
dat += "<A href='?src=\ref[src];analyse=1'>Analyse Artifact (Scan number #[scan_num+1])</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];upload=1'>Upload/update artifact scan</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];print=1'>Print Page</a><BR>"
|
||||
else
|
||||
dat += "<B>Please wait. Analysis in progress.</B><BR>"
|
||||
dat += "<HR><BR>"
|
||||
//
|
||||
dat += "<A href='?src=\ref[src];close=1'>Close<BR>"
|
||||
user << browse(dat, "window=artanalyser;size=450x500")
|
||||
onclose(user, "artanalyser")
|
||||
|
||||
/obj/machinery/artifact_analyser/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
use_power(350)
|
||||
//
|
||||
if(!owned_pad)
|
||||
for(var/obj/machinery/analyser_pad/pad in range(1))
|
||||
owned_pad = pad
|
||||
break
|
||||
|
||||
/obj/machinery/artifact_analyser/proc/AA_FailedAnalysis(var/failtype)
|
||||
switch(failtype)
|
||||
if(1)
|
||||
src.aorigin = "Failed to Identify"
|
||||
if (prob(20)) src.aorigin = pick(src.allorigins)
|
||||
if(2)
|
||||
src.atrigger = "Failed to Identify"
|
||||
if (prob(20)) src.atrigger = pick(src.alltriggers)
|
||||
if(3)
|
||||
src.aeffect1 = "Failed to Identify"
|
||||
if (prob(20)) src.aeffect1 = pick(src.alleffects)
|
||||
if(4)
|
||||
src.aeffect2 = "Failed to Identify"
|
||||
if (prob(20)) src.aeffect2 = pick(src.allranges)
|
||||
|
||||
/obj/machinery/artifact_analyser/proc/AA_Analyse()
|
||||
if(!cur_artifact)
|
||||
return
|
||||
src.accuO = 5 + rand(0,10) + origin_bonuses[cur_artifact.origin] + cur_artifact.activated * 50
|
||||
src.accuT = 5 + rand(0,10) + trigger_bonuses[cur_artifact.origin] + cur_artifact.activated * 50
|
||||
src.accuE1 = 5 + rand(0,10) + function_bonuses[cur_artifact.origin] + cur_artifact.activated * 50
|
||||
src.accuE2 = 5 + rand(0,10) + range_bonuses[cur_artifact.origin] + cur_artifact.activated * 50
|
||||
|
||||
//keep any correctly determined properties the same
|
||||
var/origin_correct = 0
|
||||
var/trigger_correct = 0
|
||||
var/function_correct = 0
|
||||
var/range_correct = 0
|
||||
if(cur_id == cur_artifact.display_id)
|
||||
if(src.aorigin == cur_artifact.origin)
|
||||
origin_correct = 1
|
||||
|
||||
if(src.atrigger == cur_artifact.my_effect.trigger)
|
||||
trigger_correct = 1
|
||||
else if(src.atrigger == cur_artifact.my_effect.triggerX)
|
||||
trigger_correct = 1
|
||||
|
||||
if(src.aeffect1 == cur_artifact.my_effect.effecttype)
|
||||
function_correct = 1
|
||||
|
||||
if(src.aeffect2 == cur_artifact.my_effect.effectmode)
|
||||
range_correct = 1
|
||||
|
||||
if (src.accuO > 100) src.accuO = 100
|
||||
if (src.accuT > 100) src.accuT = 100
|
||||
if (src.accuE1 > 100) src.accuE1 = 100
|
||||
if (src.accuE2 > 100) src.accuE2 = 100
|
||||
// Roll to generate report
|
||||
if (prob(accuO) || origin_correct)
|
||||
switch(cur_artifact.origin)
|
||||
if("ancient") src.aorigin = "Ancient Robots"
|
||||
if("martian") src.aorigin = "Martian"
|
||||
if("wizard") src.aorigin = "Wizard Federation"
|
||||
if("eldritch") src.aorigin = "Extradimensional"
|
||||
if("precursor") src.aorigin = "Precursor"
|
||||
else src.aorigin = "Unknown Origin"
|
||||
origin_bonuses[cur_artifact.origin] += 10
|
||||
else
|
||||
AA_FailedAnalysis(1)
|
||||
origin_bonuses[cur_artifact.origin] += 5
|
||||
if (prob(accuT) || trigger_correct)
|
||||
switch(cur_artifact.my_effect.trigger)
|
||||
if("touch") src.atrigger = "Contact with Living Organism"
|
||||
if("force") src.atrigger = "Heavy Impact"
|
||||
if("energy") src.atrigger = "Contact with Energy Source"
|
||||
if("chemical")
|
||||
switch(cur_artifact.my_effect.triggerX)
|
||||
if("hydrogen") src.atrigger = "Contact with Hydrogen"
|
||||
if("corrosive") src.atrigger = "Contact with Corrosive Substance"
|
||||
if("volatile") src.atrigger = "Contact with Volatile Substance"
|
||||
if("toxin") src.atrigger = "Contact with Toxins"
|
||||
if("heat") src.atrigger = "Exposure to Heat"
|
||||
else src.atrigger = "Unknown Trigger"
|
||||
trigger_bonuses[cur_artifact.origin] += 5
|
||||
else
|
||||
AA_FailedAnalysis(2)
|
||||
trigger_bonuses[cur_artifact.origin] += 1
|
||||
if (prob(accuE1) || function_correct)
|
||||
switch(cur_artifact.my_effect.effecttype)
|
||||
if("healing") src.aeffect1 = "Healing Device"
|
||||
if("injure") src.aeffect1 = "Anti-biological Weapon"
|
||||
// if("stun") src.aeffect1 = "Non-lethal Stunning Trap"
|
||||
if("roboheal") src.aeffect1 = "Mechanoid Repair Module"
|
||||
if("robohurt") src.aeffect1 = "Mechanoid Deconstruction Device"
|
||||
if("cellcharge") src.aeffect1 = "Power Generator"
|
||||
if("celldrain") src.aeffect1 = "Power Drain"
|
||||
if("planthelper") src.aeffect1 = "Agriculture Regulator"
|
||||
if("forcefield") src.aeffect1 = "Shield Generator"
|
||||
if("teleport") src.aeffect1 = "Space-Time Displacer"
|
||||
else src.aeffect1 = "Unknown Effect"
|
||||
function_bonuses[cur_artifact.origin] += 5
|
||||
else
|
||||
AA_FailedAnalysis(3)
|
||||
function_bonuses[cur_artifact.origin] += 1
|
||||
if (prob(accuE2) || range_correct)
|
||||
switch(cur_artifact.my_effect.effectmode)
|
||||
if("aura") src.aeffect2 = "Constant Short-Range Energy Field"
|
||||
if("pulse")
|
||||
if(cur_artifact.my_effect.aurarange > 7) src.aeffect2 = "Long Range Energy Pulses"
|
||||
else src.aeffect2 = "Medium Range Energy Pulses"
|
||||
if("worldpulse") src.aeffect2 = "Extreme Range Energy Pulses"
|
||||
if("contact") src.aeffect2 = "Requires contact with subject"
|
||||
else src.aeffect2 = "Unknown Range"
|
||||
range_bonuses[cur_artifact.origin] += 5
|
||||
else
|
||||
AA_FailedAnalysis(4)
|
||||
range_bonuses[cur_artifact.origin] += 1
|
||||
|
||||
cur_artifact.name = "alien artifact ([cur_artifact.display_id])"
|
||||
cur_artifact.desc = "A large alien device. It has a small tag near the bottom that reads \"[cur_artifact.display_id]\"."
|
||||
cur_id = cur_artifact.display_id
|
||||
cur_artifact.my_effect.artifact_id = cur_artifact.display_id
|
||||
|
||||
/obj/machinery/artifact_analyser/Topic(href, href_list)
|
||||
|
||||
if(href_list["analyse"])
|
||||
if(owned_pad)
|
||||
var/turf/pad_turf = get_turf(owned_pad)
|
||||
var/findarti = 0
|
||||
for(var/obj/machinery/artifact/A in pad_turf.contents)
|
||||
findarti++
|
||||
cur_artifact = A
|
||||
if (findarti == 1)
|
||||
if(cur_artifact && cur_artifact.being_used)
|
||||
var/message = "<b>[src]</b> states, \"Cannot analyse. Excess energy drain is disrupting signal.\""
|
||||
src.visible_message(message, message)
|
||||
else
|
||||
cur_artifact.anchored = 1
|
||||
cur_artifact.being_used = 1
|
||||
src.working = 1
|
||||
src.icon_state = "analyser_processing"
|
||||
var/time = rand(30,50) + max(0, 300 - scan_num * 10)
|
||||
/*for(var/i = artifact_research.starting_tier, i <= artifact_research.max_tiers, i++)
|
||||
for(var/datum/artiresearch/R in artifact_research.researched_items[i])
|
||||
if (R.bonustype == "analyser") time -= R.bonusTime*/
|
||||
time *= 10
|
||||
var/message = "<b>[src]</b> states, \"Commencing analysis.\""
|
||||
src.visible_message(message, message)
|
||||
use_power(500)
|
||||
spawn(time)
|
||||
src.working = 0
|
||||
icon_state = "analyser"
|
||||
cur_artifact.anchored = 0
|
||||
cur_artifact.being_used = 0
|
||||
if(cur_artifact.loc == pad_turf)
|
||||
AA_Analyse()
|
||||
scan_num++
|
||||
message = "<b>[src]</b> states, \"Analysis complete.\""
|
||||
src.visible_message(message, message)
|
||||
use_power(500)
|
||||
else if (findarti > 1)
|
||||
var/message = "<b>[src]</b> states, \"Cannot analyse. Error isolating energy signature.\""
|
||||
src.visible_message(message, message)
|
||||
else
|
||||
var/message = "<b>[src]</b> states, \"Cannot analyse. No noteworthy energy signature isolated.\""
|
||||
src.visible_message(message, message)
|
||||
|
||||
if(href_list["upload"] && cur_id != "")
|
||||
//add new datum to every DB in the world
|
||||
for(var/obj/machinery/computer/artifact_database/DB in world)
|
||||
var/update = 0
|
||||
for(var/datum/catalogued_artifact/CA in DB.catalogued_artifacts)
|
||||
if(CA.display_id == cur_id)
|
||||
//already there, so update it
|
||||
update = 1
|
||||
CA.origin = aorigin + " ([accuO]%)"
|
||||
CA.trigger = atrigger + " ([accuT]%)"
|
||||
CA.effecttype = aeffect1 + " ([accuE1]%)"
|
||||
CA.effectmode = aeffect2 + " ([accuE2]%)"
|
||||
if(!update)
|
||||
//not there, so add it
|
||||
var/datum/catalogued_artifact/CA = new()
|
||||
CA.display_id = cur_id
|
||||
CA.origin = aorigin + " ([accuO]%)"
|
||||
CA.trigger = atrigger + " ([accuT]%)"
|
||||
CA.effecttype = aeffect1 + " ([accuE1]%)"
|
||||
CA.effectmode = aeffect2 + " ([accuE2]%)"
|
||||
DB.catalogued_artifacts.Add(CA)
|
||||
use_power(100)
|
||||
|
||||
if(href_list["print"])
|
||||
var/r = "Artifact Analysis Report (Scan #[scan_num])<hr>"
|
||||
r += "<B>Artifact ID:</B> [cur_id] (determined from unique energy emission signatures)<BR>"
|
||||
r += "<B>Artifact Origin:</B> [aorigin] ([accuO]%)<BR>"
|
||||
r += "<B>Activation Trigger:</B> [atrigger] ([accuT]%)<BR>"
|
||||
r += "<B>Artifact Function:</B> [aeffect1] ([accuE1]%)<BR>"
|
||||
r += "<B>Artifact Range:</B> [aeffect2] ([accuE2]%)<BR><BR>"
|
||||
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(src.loc)
|
||||
P.name = "Artifact Analysis Report #[scan_num]"
|
||||
P.info = r
|
||||
for(var/mob/O in hearers(src, null))
|
||||
O.show_message("\icon[src] \blue The [src.name] prints a sheet of paper", 3)
|
||||
use_power(10)
|
||||
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=artanalyser")
|
||||
usr.machine = null
|
||||
|
||||
src.updateDialog()
|
||||
|
||||
//stick artifacts onto this then switch the analyser on
|
||||
/obj/machinery/analyser_pad
|
||||
name = "artifact analysis pad"
|
||||
desc = "Studies the structure of artifacts to discover their uses."
|
||||
icon = 'stationobjs.dmi'
|
||||
icon_state = "tele0"
|
||||
anchored = 1
|
||||
density = 0
|
||||
|
||||
/obj/machinery/analyser_pad/New()
|
||||
..()
|
||||
/*spawn(10)
|
||||
for(var/obj/machinery/artifact_analyser/analyser in orange(1))
|
||||
world << "pad found analyser"
|
||||
if(!analyser.owned_pad)
|
||||
analyser.owned_pad = src
|
||||
world << "pad set analyser to self"
|
||||
break*/
|
||||
@@ -1,58 +1,58 @@
|
||||
|
||||
/datum/catalogued_artifact
|
||||
var/trigger = "touch" // What activates it?
|
||||
var/effecttype = "healing" // What does it do?
|
||||
var/effectmode = "aura" // How does it carry out the effect?
|
||||
var/display_id = "" // Artifact ID to display once successfully scanned
|
||||
var/origin = ""
|
||||
|
||||
/obj/machinery/computer/artifact_database
|
||||
name = "Artifact Database"
|
||||
icon_state = "rdcomp"
|
||||
var/list/catalogued_artifacts
|
||||
|
||||
/obj/machinery/computer/artifact_database/New()
|
||||
..()
|
||||
catalogued_artifacts = new/list
|
||||
|
||||
/obj/machinery/computer/artifact_database/Topic(href, href_list)
|
||||
..()
|
||||
if( href_list["close"] )
|
||||
usr << browse(null, "window=artifact_db")
|
||||
usr.machine = null
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/computer/artifact_database/process()
|
||||
..()
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/computer/artifact_database/interact(mob/user)
|
||||
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
|
||||
if (!istype(user, /mob/living/silicon))
|
||||
user.machine = null
|
||||
user << browse(null, "window=artifact_db")
|
||||
return
|
||||
var/t = "<B>Artifact Database</B><BR>"
|
||||
t += "<hr>"
|
||||
for(var/datum/catalogued_artifact/CA in catalogued_artifacts)
|
||||
t += "<B>Artifact ID:</B> [CA.display_id] (determined from unique energy emission signatures)<BR>"
|
||||
t += "<B>Artifact Origin:</B> [CA.origin]<BR>"
|
||||
t += "<B>Activation Trigger:</B> [CA.trigger]<BR>"
|
||||
t += "<B>Artifact Function:</B> [CA.effecttype]<BR>"
|
||||
t += "<B>Artifact Range:</B> [CA.effectmode]<BR><BR>"
|
||||
t += "<hr>"
|
||||
t += "<A href='?src=\ref[src];refresh=1'>Refresh</A> <A href='?src=\ref[src];close=1'>Close</A><BR>"
|
||||
user << browse(t, "window=artifact_db;size=500x800")
|
||||
user.machine = src
|
||||
|
||||
/*
|
||||
/datum/artifact_effect
|
||||
var/origin = null // Used in the randomisation/research of the artifact.
|
||||
var/trigger = "touch" // What activates it?
|
||||
var/triggerX = "none" // Used for more varied triggers
|
||||
var/effecttype = "healing" // What does it do?
|
||||
var/effectmode = "aura" // How does it carry out the effect?
|
||||
var/aurarange = 4 // How far the artifact will extend an aura effect.
|
||||
var/display_id = "" // Artifact ID to display once successfully scanned
|
||||
var/list/created_field
|
||||
|
||||
/datum/catalogued_artifact
|
||||
var/trigger = "touch" // What activates it?
|
||||
var/effecttype = "healing" // What does it do?
|
||||
var/effectmode = "aura" // How does it carry out the effect?
|
||||
var/display_id = "" // Artifact ID to display once successfully scanned
|
||||
var/origin = ""
|
||||
|
||||
/obj/machinery/computer/artifact_database
|
||||
name = "Artifact Database"
|
||||
icon_state = "rdcomp"
|
||||
var/list/catalogued_artifacts
|
||||
|
||||
/obj/machinery/computer/artifact_database/New()
|
||||
..()
|
||||
catalogued_artifacts = new/list
|
||||
|
||||
/obj/machinery/computer/artifact_database/Topic(href, href_list)
|
||||
..()
|
||||
if( href_list["close"] )
|
||||
usr << browse(null, "window=artifact_db")
|
||||
usr.machine = null
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/computer/artifact_database/process()
|
||||
..()
|
||||
updateDialog()
|
||||
|
||||
/obj/machinery/computer/artifact_database/interact(mob/user)
|
||||
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
|
||||
if (!istype(user, /mob/living/silicon))
|
||||
user.machine = null
|
||||
user << browse(null, "window=artifact_db")
|
||||
return
|
||||
var/t = "<B>Artifact Database</B><BR>"
|
||||
t += "<hr>"
|
||||
for(var/datum/catalogued_artifact/CA in catalogued_artifacts)
|
||||
t += "<B>Artifact ID:</B> [CA.display_id] (determined from unique energy emission signatures)<BR>"
|
||||
t += "<B>Artifact Origin:</B> [CA.origin]<BR>"
|
||||
t += "<B>Activation Trigger:</B> [CA.trigger]<BR>"
|
||||
t += "<B>Artifact Function:</B> [CA.effecttype]<BR>"
|
||||
t += "<B>Artifact Range:</B> [CA.effectmode]<BR><BR>"
|
||||
t += "<hr>"
|
||||
t += "<A href='?src=\ref[src];refresh=1'>Refresh</A> <A href='?src=\ref[src];close=1'>Close</A><BR>"
|
||||
user << browse(t, "window=artifact_db;size=500x800")
|
||||
user.machine = src
|
||||
|
||||
/*
|
||||
/datum/artifact_effect
|
||||
var/origin = null // Used in the randomisation/research of the artifact.
|
||||
var/trigger = "touch" // What activates it?
|
||||
var/triggerX = "none" // Used for more varied triggers
|
||||
var/effecttype = "healing" // What does it do?
|
||||
var/effectmode = "aura" // How does it carry out the effect?
|
||||
var/aurarange = 4 // How far the artifact will extend an aura effect.
|
||||
var/display_id = "" // Artifact ID to display once successfully scanned
|
||||
var/list/created_field
|
||||
*/
|
||||
@@ -0,0 +1,227 @@
|
||||
|
||||
/obj/machinery/artifact_harvester
|
||||
name = "Exotic Particle Harvester"
|
||||
icon = 'virology.dmi'
|
||||
icon_state = "incubator" //incubator_on
|
||||
anchored = 1
|
||||
density = 1
|
||||
idle_power_usage = 50
|
||||
active_power_usage = 750
|
||||
use_power = 1
|
||||
var/harvesting = 0
|
||||
var/obj/item/weapon/anobattery/inserted_battery
|
||||
var/obj/machinery/artifact/cur_artifact
|
||||
var/obj/machinery/artifact_scanpad/owned_scanner = null
|
||||
|
||||
/obj/machinery/artifact_harvester/New()
|
||||
..()
|
||||
//connect to a nearby scanner pad
|
||||
owned_scanner = locate(/obj/machinery/artifact_scanpad) in get_step(src, dir)
|
||||
if(!owned_scanner)
|
||||
owned_scanner = locate(/obj/machinery/artifact_scanpad) in orange(1, src)
|
||||
|
||||
/obj/machinery/artifact_harvester/attackby(var/obj/I as obj, var/mob/user as mob)
|
||||
if(istype(I,/obj/item/weapon/anobattery))
|
||||
if(!inserted_battery)
|
||||
user << "\blue You insert [I] into [src]."
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
src.inserted_battery = I
|
||||
updateDialog()
|
||||
else
|
||||
user << "\red There is already a battery in [src]."
|
||||
else
|
||||
return..()
|
||||
|
||||
/obj/machinery/artifact_harvester/attack_hand(var/mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/artifact_harvester/interact(var/mob/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = "<B>Artifact Power Harvester</B><BR>"
|
||||
dat += "<HR><BR>"
|
||||
//
|
||||
if(owned_scanner)
|
||||
if(harvesting)
|
||||
if(harvesting > 0)
|
||||
dat += "Please wait. Harvesting in progress ([(inserted_battery.stored_charge/inserted_battery.capacity)*100]%).<br>"
|
||||
else
|
||||
dat += "Please wait. Energy dump in progress ([(inserted_battery.stored_charge/inserted_battery.capacity)*100]%).<br>"
|
||||
dat += "<A href='?src=\ref[src];stopharvest=1'>Halt early</A><BR>"
|
||||
else
|
||||
if(inserted_battery)
|
||||
dat += "<b>[inserted_battery.name]</b> inserted, charge level: [inserted_battery.stored_charge]/[inserted_battery.capacity] ([(inserted_battery.stored_charge/inserted_battery.capacity)*100]%)<BR>"
|
||||
dat += "<b>Energy signature ID:</b>[inserted_battery.battery_effect.artifact_id == "" ? "???" : "[inserted_battery.battery_effect.artifact_id]"]<BR>"
|
||||
dat += "<A href='?src=\ref[src];ejectbattery=1'>Eject battery</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];drainbattery=1'>Drain battery of all charge</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];harvest=1'>Begin harvesting</a><BR>"
|
||||
|
||||
else
|
||||
dat += "No battery inserted.<BR>"
|
||||
else
|
||||
dat += "<B><font color=red>Unable to locate analysis pad.</font><BR></b>"
|
||||
//
|
||||
dat += "<HR>"
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>Refresh</A> <A href='?src=\ref[src];close=1'>Close<BR>"
|
||||
user << browse(dat, "window=artharvester;size=450x500")
|
||||
onclose(user, "artharvester")
|
||||
|
||||
/obj/machinery/artifact_harvester/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
|
||||
if(harvesting > 0)
|
||||
//gain a bit of charge
|
||||
inserted_battery.stored_charge += 0.5
|
||||
|
||||
//check if we've finished
|
||||
if(inserted_battery.stored_charge >= inserted_battery.capacity)
|
||||
use_power = 1
|
||||
harvesting = 0
|
||||
cur_artifact.anchored = 0
|
||||
cur_artifact.being_used = 0
|
||||
src.visible_message("<b>[name]</b> states, \"Battery is full.\"")
|
||||
icon_state = "incubator"
|
||||
|
||||
else if(harvesting < 0)
|
||||
//dump some charge
|
||||
inserted_battery.stored_charge -= 2
|
||||
|
||||
//do the effect
|
||||
if(inserted_battery.battery_effect)
|
||||
inserted_battery.battery_effect.process()
|
||||
|
||||
//if the effect works by touch, activate it on anyone viewing the console
|
||||
if(inserted_battery.battery_effect.effect == 0)
|
||||
var/list/nearby = viewers(1, src)
|
||||
for(var/mob/M in nearby)
|
||||
if(M.machine == src)
|
||||
inserted_battery.battery_effect.DoEffectTouch(M)
|
||||
|
||||
//if there's no charge left, finish
|
||||
if(inserted_battery.stored_charge <= 0)
|
||||
use_power = 1
|
||||
inserted_battery.stored_charge = 0
|
||||
harvesting = 0
|
||||
if(inserted_battery.battery_effect && inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate()
|
||||
src.visible_message("<b>[name]</b> states, \"Battery dump completed.\"")
|
||||
icon_state = "incubator"
|
||||
|
||||
/obj/machinery/artifact_harvester/Topic(href, href_list)
|
||||
|
||||
if (href_list["harvest"])
|
||||
//locate artifact on analysis pad
|
||||
cur_artifact = null
|
||||
var/articount = 0
|
||||
var/obj/machinery/artifact/analysed
|
||||
for(var/obj/machinery/artifact/A in get_turf(owned_scanner))
|
||||
analysed = A
|
||||
articount++
|
||||
|
||||
var/mundane = 0
|
||||
for(var/obj/O in get_turf(owned_scanner))
|
||||
if(O.invisibility)
|
||||
continue
|
||||
if(!istype(O, /obj/machinery/artifact) && !istype(O, /obj/machinery/artifact_scanpad))
|
||||
mundane++
|
||||
break
|
||||
for(var/mob/O in get_turf(owned_scanner))
|
||||
if(O.invisibility)
|
||||
continue
|
||||
mundane++
|
||||
break
|
||||
|
||||
if(analysed.being_used)
|
||||
var/message = "<b>[src]</b> states, \"Cannot harvest. Too much interference.\""
|
||||
src.visible_message(message)
|
||||
else if(articount == 1 && !mundane)
|
||||
cur_artifact = analysed
|
||||
//there should already be a battery inserted, but this is just in case
|
||||
if(inserted_battery)
|
||||
//see if we can clear out an old effect
|
||||
//delete it when the ids match to account for duplicate ids having different effects
|
||||
if(inserted_battery.battery_effect && inserted_battery.stored_charge <= 0)
|
||||
del(inserted_battery.battery_effect)
|
||||
|
||||
//only charge up
|
||||
var/matching_id = 0
|
||||
if(inserted_battery.battery_effect)
|
||||
matching_id = (inserted_battery.battery_effect.artifact_id == cur_artifact.my_effect.artifact_id)
|
||||
var/matching_effecttype = 0
|
||||
if(inserted_battery.battery_effect)
|
||||
matching_effecttype = (inserted_battery.battery_effect.type == cur_artifact.my_effect.type)
|
||||
if(!inserted_battery.battery_effect || (matching_id && matching_effecttype))
|
||||
harvesting = 1
|
||||
use_power = 2
|
||||
cur_artifact.anchored = 1
|
||||
cur_artifact.being_used = 1
|
||||
icon_state = "incubator_on"
|
||||
var/message = "<b>[src]</b> states, \"Beginning artifact energy harvesting.\""
|
||||
src.visible_message(message)
|
||||
|
||||
//duplicate the artifact's effect datum
|
||||
if(!inserted_battery.battery_effect)
|
||||
var/effecttype = cur_artifact.my_effect.type
|
||||
var/datum/artifact_effect/E = new effecttype(inserted_battery)
|
||||
|
||||
//duplicate it's unique settings
|
||||
for(var/varname in list("chargelevelmax","artifact_id","effect","effectrange","trigger"))
|
||||
E.vars[varname] = cur_artifact.my_effect.vars[varname]
|
||||
|
||||
//copy the new datum into the battery
|
||||
inserted_battery.battery_effect = E
|
||||
inserted_battery.stored_charge = 0
|
||||
else
|
||||
var/message = "<b>[src]</b> states, \"Cannot harvest. Incompatible energy signatures detected.\""
|
||||
src.visible_message(message)
|
||||
else if(cur_artifact)
|
||||
var/message = "<b>[src]</b> states, \"Cannot harvest. No battery inserted.\""
|
||||
src.visible_message(message)
|
||||
else if(articount > 1 || mundane)
|
||||
var/message = "<b>[src]</b> states, \"Cannot harvest. Error isolating energy signature.\""
|
||||
src.visible_message(message)
|
||||
else if(!articount)
|
||||
var/message = "<b>[src]</b> states, \"Cannot harvest. No noteworthy energy signature isolated.\""
|
||||
src.visible_message(message)
|
||||
|
||||
if (href_list["stopharvest"])
|
||||
if(harvesting)
|
||||
if(harvesting < 0 && inserted_battery.battery_effect && inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate()
|
||||
harvesting = 0
|
||||
cur_artifact.anchored = 0
|
||||
cur_artifact.being_used = 0
|
||||
src.visible_message("<b>[name]</b> states, \"Activity interrupted.\"")
|
||||
icon_state = "incubator"
|
||||
|
||||
if (href_list["ejectbattery"])
|
||||
src.inserted_battery.loc = src.loc
|
||||
src.inserted_battery = null
|
||||
|
||||
if (href_list["drainbattery"])
|
||||
if(inserted_battery)
|
||||
if(inserted_battery.battery_effect && inserted_battery.stored_charge > 0)
|
||||
if(alert("This action will dump all charge, safety gear is recommended before proceeding","Warning","Continue","Cancel"))
|
||||
if(!inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate(0)
|
||||
harvesting = -1
|
||||
use_power = 2
|
||||
icon_state = "incubator_on"
|
||||
var/message = "<b>[src]</b> states, \"Warning, battery charge dump commencing.\""
|
||||
src.visible_message(message)
|
||||
else
|
||||
var/message = "<b>[src]</b> states, \"Cannot dump energy. Battery is drained of charge already.\""
|
||||
src.visible_message(message)
|
||||
else
|
||||
var/message = "<b>[src]</b> states, \"Cannot dump energy. No battery inserted.\""
|
||||
src.visible_message(message)
|
||||
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=artharvester")
|
||||
usr.unset_machine(src)
|
||||
|
||||
updateDialog()
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
/obj/machinery/artifact_scanpad
|
||||
name = "Anomaly Scanner Pad"
|
||||
desc = "Place things here for scanning."
|
||||
icon = 'stationobjs.dmi'
|
||||
icon_state = "tele0"
|
||||
anchored = 1
|
||||
density = 0
|
||||
413
code/modules/research/xenoarchaeology/manuals.dm
Normal file
413
code/modules/research/xenoarchaeology/manuals.dm
Normal file
@@ -0,0 +1,413 @@
|
||||
|
||||
/obj/item/weapon/book/manual/excavation
|
||||
name = "Out on the dig"
|
||||
icon_state = "excavation"
|
||||
author = "Professor Patrick Mason, Curator of the Antiquities Museum on Ichar VII"
|
||||
title = "Out on the dig"
|
||||
dat = {"<html>
|
||||
<head>
|
||||
<style>
|
||||
h1 {font-size: 18px; margin: 15px 0px 5px;}
|
||||
h1 {font-size: 15px; margin: 15px 0px 5px;}
|
||||
li {margin: 2px 0px 2px 15px;}
|
||||
ul {list-style: none; margin: 5px; padding: 0px;}
|
||||
ol {margin: 5px; padding: 0px 15px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1><a name="Contents">Contents</a></h1>
|
||||
<ol>
|
||||
<li><a href="#Prep">Prepping the expedition</a></li>
|
||||
<li><a href="#Tools">Knowing your tools</a></li>
|
||||
<li><a href="#Find">Finding the dig</a></li>
|
||||
<li><a href="#Analyse">Analysing deposits</a></li>
|
||||
<li><a href="#Excavate">Extracting your first find</a></li>
|
||||
</ol>
|
||||
<br>
|
||||
|
||||
<h1><a name="Prep">Prepping the expedition</a></h1>
|
||||
Every digsite I've been to, someone has forgotten something and I've never yet been to a dig that hasn't had me hiking to get to it - so gather your gear
|
||||
and get it to the site the first time. You learn quick that time is money, when you've got a shipful of bandits searching for you the next valley over,
|
||||
but don't be afraid to clear some space if there are any inconvenient boulders in the way.<br>
|
||||
<list>
|
||||
<li>Floodlights (if it's dark)</li>
|
||||
<li>Wooden trestle tables (for holding tools and finds)</li>
|
||||
<li>Suspension field generator</li>
|
||||
<li>Load bearing servitors (such as a mulebot, or hover-tray)</li>
|
||||
<li>Spare energy packs</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Tools">Knowing your tools</a></h1>
|
||||
Every archaeologist has a plethora of tools at their disposal, but here's the important ones:<br>
|
||||
<list>
|
||||
<li><b>Picks, pickaxes and brushes</b> - don't underestimate the the smallest or largest in your arsenal, each one clears a different amount
|
||||
of the rockface so each one has a use.</li>
|
||||
<li><b>Measuring tape</b> - don't leave home without it, you can use it to measure the depth a rock face has been excavated to.</li>
|
||||
<li><b>GPS locater</b> - knowing where you are is the first step to not be lost.</li>
|
||||
<li><b>Core sampler</b> - use this to take core samples from rock faces, which you can then run to the lab for analysis.</li>
|
||||
<li><b>Depth scanner</b> - uses x-ray diffraction to locate anomalous densities in rock, indicating archaeological deposits or mineral veins.
|
||||
Comes with a handy reference log containing co-ordinates and time of each scan.</li>
|
||||
<li><b>Radio beacon locater</b> - leave a beacon at an item of interest, then track it down later with this handy gadget. Watch for interference from other
|
||||
devices though.</li>
|
||||
<li><b>Flashlight or portable light source</b> - Self explanatory, I hope.</li>
|
||||
<li><b>Environmental safety gear</b> - This one's dependant on the environment you're working in, but enclosed footwear and pack of internals
|
||||
could save your life.</li>
|
||||
<li><b>Anomaly safety gear</b> - A biosealed and catalysis-resistant suit along with eye shielding, tinted hood and non-reactive disposable gloves are
|
||||
the best kind of protection you can hope for from the errors our forbears may have unleashed.</li>
|
||||
<li><b>Personal defence weapon</b> - Never know what you'll find on the dig: pirates, natives, ancient guardians, carnivorous wildlife...
|
||||
it pays in blood to be prepared.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Find">Finding the dig</a></h1>
|
||||
Wouldn't be an archaeologist without their dig, but everyone has to start somewhere. Here's a basic procedure I go through when cataloguing a new planet:<br>
|
||||
<list>
|
||||
<li><b>Get in touch with the locals</b> (in particular geologists, miners and farmers) - Never know what's been turned up by accident, then left to
|
||||
gather dust on a shelf.</li>
|
||||
<li><b>Check the obvious areas first</b> - even if you're pressed for time, these ones are the generally easiest to search, and the most likely targets
|
||||
of your rivals.</li>
|
||||
<li><b>Do some prospecting</b> - the earth mother isn't in the habit of displaying her secrets to the world (although sometimes you get lucky).
|
||||
Drop a shaft and clear away a bit of surface rock here and there, you never know what might be lurking below the surface.</li>
|
||||
<li><b>Tips on unearthing a deposit</b> - How do you know when you're golden? Look for telltale white strata that looks strange or out of place, or if
|
||||
something has broken under your pick while you're digging. Your depth scanner is your best friend, but even it can't distinguish between
|
||||
ordinary minerals and ancient leavings, if in doubt then err on the side of caution.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Analyse">Analysing the contents of a dig</a></h1>
|
||||
You've found some unusual strata, but it's not all peaches from here. No archaeologist ever managed to pull a bone from the earth without doing thorough
|
||||
chemical analysis on every two meters of rock face nearby.<br>
|
||||
<list>
|
||||
<li><b>Take core samples</b> - Grab a rock core for every 4m^2.</li>
|
||||
<li><b>Clear around any potential finds</b> - Clear away ordinary rock, leaving your prizes reachable in a clearly marked area.</li>
|
||||
<li><b>Haul off excess rock</b> - It's easy for a dig to get cluttered, and a neat archaeologist is a successful archaeologist.</li>
|
||||
<li><b>Don't be afraid to be cautious</b> - It's slower sometimes, but the extra time will be worth the payoff when you find an Exolitic relic.</li>
|
||||
<li><b>Chemical analysis</b> - I won't go into detail here, but the labwork is essential to any successful extraction. Marshal your core samples, and
|
||||
send them off to the labcoated geniuses</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Excavate">Extracting your first find</a></h1>
|
||||
<list>
|
||||
<li><b>Scan the rock</b> - Use a depth scanner to determine the find's depth and clearance. DON'T FORGET THESE.</li>
|
||||
<li><b>Choose stasis field</b> - Chemical analysis on a core sample from the rock face will tell you which field is necessary to extract the find safely</li>
|
||||
<li><b>Setup field gen</b> - Bolt it down, choose the field, check the charge and activate it. If you forget it, you'll wish you hadn't when that priceless
|
||||
Uryom vase crumbles as it sees the light of day.</li>
|
||||
<li><b>FUNCTIONAL AND SAFE digging</b> - Dig into the rock until you've cleared away a depth equal to (the anomaly depth MINUS the clearance range). The find
|
||||
should come loose on it's own, but it will be in the midst of a chunk of rock. Use a welder or miniature excavation tool to clear away the excess.</li>
|
||||
<li><b>FANCY AND SPEEDY digging</b> - Dig into the rock until you've cleared away a depth equal to the anomaly depth, but without any of your strokes
|
||||
entering the clearance range.</li>
|
||||
<li><b>The Big Find</b> - Sometimes, you'll chance upon something big, both literally and figuratively. Giant statues and functioning remnants of Precursor
|
||||
technology are just as exciting, to the right buyers. If your digging leaves a large boulder behind, dig into it normally and see if anything's hidden
|
||||
inside.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
|
||||
/obj/item/weapon/book/manual/mass_spectrometry
|
||||
name = "High power mass spectrometry, a comprehensive guide"
|
||||
icon_state = "analysis"
|
||||
author = "Winton Rice, Chief Mass Spectrometry Technician at the Institute of Applied Sciences on Arcadia"
|
||||
title = "High powered mass spectrometry, a comprehensive guide"
|
||||
dat = {"<html>
|
||||
<head>
|
||||
<style>
|
||||
h1 {font-size: 18px; margin: 15px 0px 5px;}
|
||||
h1 {font-size: 15px; margin: 15px 0px 5px;}
|
||||
li {margin: 2px 0px 2px 15px;}
|
||||
ul {list-style: none; margin: 5px; padding: 0px;}
|
||||
ol {margin: 5px; padding: 0px 15px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1><a name="Contents">Contents</a></h1>
|
||||
<ol>
|
||||
<li><a href="#Terms">A note on terms</a></li>
|
||||
<li><a href="#Isotope">Isotope ratio spectrometer</a></li>
|
||||
<li><a href="#Accelerator">Accelerator spectrometer</a></li>
|
||||
<li><a href="#Gas">Gas chromatography spectrometer</a></li>
|
||||
<li><a href="#Ion">Ion mobility spectrometer</a></li>
|
||||
</ol>
|
||||
|
||||
<br>
|
||||
<h1><a name="Terms">A note on terms</a></h1>
|
||||
<list>
|
||||
<li><b>Dissonance ratio</b> - This is a pseudoarbitrary value indicating the overal presence of a particular element in a greater composite.
|
||||
It takes into account volume, density, molecular excitation and isotope spread.</li>
|
||||
<li><b>Mass spectrometry</b> - MS is the procedure used used to measure and quantify the components of matter. The most prized tool in the field of
|
||||
'Materials analysis'</li>
|
||||
<li><b>Radiometric dating</b> - MS applied using the right carrier reagents can be used to accurately determine the age of a sample.</li>
|
||||
<li><b>Sample specifity</b> - A pseudoarbitrary value used to indicate how well a sample resonates with the employed carrier reagent. Great specifity
|
||||
(material resonance) indicates that there is much of the carrier reagent present in the sample.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Isotope">Isotope ratio spectrometer</a></h1>
|
||||
Isotope ratio mass spectrometers work by coating a small surface with a semiliquid <i>stationary phase</i> consisting of the sample to be
|
||||
analysed, and recording it's interactions with a gaseous <i>mobile phase</i> comprised of an inert or nonreactive gas such as helium or nitrogen.<br>
|
||||
<br>
|
||||
IRMS are employed as radiometric daters, extremely accurate but only so up to ages of one billion years.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Accelerator">Accelerator spectrometer</a></h1>
|
||||
The accelerator mass spectrometer works by accelerating ions to extraordinarily high kinetic energies before mass analysis. The special strength of AMS is
|
||||
isolate rare or low-strength isotopes, making it able to determine much greater ages with reasonable accuracy.<br>
|
||||
<br>
|
||||
AMS are employed as extreme age radiometric daters, able to determine the age of the sample on a scale of billions of years.
|
||||
They are commonly located in geology and archaeology laboratories.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Gas">Gas chromatography spectrometer</a></h1>
|
||||
Gas-liquid chromatography mass spectrometers work by coating a small surface with a semiliquid <i>stationary phase</i> consisting of the sample to be
|
||||
analysed, and recording it's interactions with a gaseous <i>mobile phase</i> comprised of an inert or nonreactive gas such as helium or nitrogen.<br>
|
||||
<br>
|
||||
GLCS are employed in forensic and geological analysis to determine what elements are present in a sample.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Ion">Ion mobility spectrometer</a></h1>
|
||||
Ion mobility mass spectrometers work by examining the mobility of ionized molecules in an inert carrier gas<br>
|
||||
<br>
|
||||
IMS returns a dissonance ratio over the scanned sample and carrier reagent, indicating the average total presence of the sample.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
|
||||
/obj/item/weapon/book/manual/anomaly_spectroscopy
|
||||
name = "Spectroscopy: Analysing the anomalies of the cosmos"
|
||||
icon_state = "anomaly"
|
||||
author = "Doctor Martin Boyle, Director Research at the Lower Hydrolian Sector Listening Array"
|
||||
title = "Spectroscopy: Analysing the anomalies of the cosmos"
|
||||
dat = {"<html>
|
||||
<head>
|
||||
<style>
|
||||
h1 {font-size: 18px; margin: 15px 0px 5px;}
|
||||
h1 {font-size: 15px; margin: 15px 0px 5px;}
|
||||
li {margin: 2px 0px 2px 15px;}
|
||||
ul {list-style: none; margin: 5px; padding: 0px;}
|
||||
ol {margin: 5px; padding: 0px 15px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1><a name="Contents">Contents</a></h1>
|
||||
<ol>
|
||||
<li><a href="#Terms">Some useful phrases for you</a></li>
|
||||
<li><a href="#Sample">Sample preparation and analysis</a></li>
|
||||
<li><a href="#Fourier">Fourier transform spectroscope</a></li>
|
||||
<li><a href="#Hyperspectral">Hyperspectral Imager</a></li>
|
||||
</ol>
|
||||
|
||||
<br>
|
||||
<h1><a name="Terms">Some useful phrases for you</a></h1>
|
||||
<list>
|
||||
<li><b>Spectroscopy</b> - Spectroscopy is the study of the behaviour of light, commonly used in the 26th century for analysis of anomalous
|
||||
behaviour of energy or light.</li>
|
||||
<li><b>Sample specifity</b> - A pseudoarbitrary value used to indicate how well a sample resonates with the employed carrier reagent. Great specifity
|
||||
(material resonance) indicates that there is much of the carrier reagent present in the sample.</li>
|
||||
<li><b>Anomalies</b> - Inexplicable or uncategorised occurrences in the cosmos. A fascinating and dangerous study is made to determine the function of
|
||||
these rare finds, and the term is often applied to describe technology left behind by vastly superior ancient alien forerunners.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Sample">Sample preparation and analysis</a></h1>
|
||||
When you are readying your spectrometry lab for analysis, you'll need to make sure the sample is in a form the machines can glean data from.
|
||||
<list>
|
||||
<li><b>Obtain material sample</b> - This should be an ordinary chunk of matter the size of your finger, a good example is a 6mm rock core.</li>
|
||||
<li><b>Run density separation treatment</b> - Perform the DST procedure on your sample, following generic specifications.</li>
|
||||
<li><b>Ensure sample purity</b> - DST can sometimes leave behind chemical waste or chunks of matter, make sure there aren't any before proceeding.</li>
|
||||
<li><b>Prepare analysis tray</b> - A sample tray holds a miniscule amount of liquid (2u), but that's all that our spectrometers require for a good reading.</li>
|
||||
<li><b>Choose carrier reagent</b> - Standard spectrometers require 1u of the material sample, and 1u of a 'carrier' reagent to provide control comparison
|
||||
and to enable refraction inferencing.</li>
|
||||
<li><b>Insert sample tray into machine</b> - And press the 'Go' button. Now go make a cup of coffee.</li>
|
||||
<li><b>Monitor machine heat levels</b> - The upper end mass spectrometers have quite complex internals, and have a tendency to critically overheat.
|
||||
Make sure the heat limit isn't exceeded, or there may be potentially disastrous consequences.</li>
|
||||
<li><b>Examine analysis report</b> - it won't always make sense or provide the information you hoped for, but if you've been careful during DST and ensured
|
||||
sample integrity, then there's always something to be learnt. Just don't lose the paperwork!</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Fourier">Fourier transform spectroscope</a></h1>
|
||||
The FTS measures temporal coherence of radiating energy, then applies time-and-space domain measurements on the collected emission data. The collective
|
||||
procedure is known as the <i>Fourier Transform Procedure,</i> with the mathematical algorithms dating back to the 19th century on Earth.<br>
|
||||
<br>
|
||||
As well as providing background energy readings, an FTS calculates the approximate distance and direction towards any anomalous energy signatures from
|
||||
the location the scanned sample was taken from.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Hyperspectral">Hyperspectral Imager</a></h1>
|
||||
The imager scans and collates spectral energy signatures from across the electromagnetic spectrum. The collected data is then presented to the viewer in
|
||||
graph form, with any anomalous (uncatalogued or unidentified) energy signatures highlighted.<br>
|
||||
<br>
|
||||
As well as visualising background energy readings, a hyperspectral imager will isolate and identify any anomalous energy signatures in the sample.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
|
||||
/obj/item/weapon/book/manual/materials_chemistry_analysis
|
||||
name = "Chemical preparation for materials analysis"
|
||||
icon_state = "chemistry"
|
||||
author = "Jasper Pascal, Senior Lecturer in Materials Analysis at the University of Jol'Nar"
|
||||
title = "Chemical preparation for materials analysis"
|
||||
dat = {"<html>
|
||||
<head>
|
||||
<style>
|
||||
h1 {font-size: 18px; margin: 15px 0px 5px;}
|
||||
h1 {font-size: 15px; margin: 15px 0px 5px;}
|
||||
li {margin: 2px 0px 2px 15px;}
|
||||
ul {list-style: none; margin: 5px; padding: 0px;}
|
||||
ol {margin: 5px; padding: 0px 15px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1><a name="Contents">Contents</a></h1>
|
||||
<ol>
|
||||
<li><a href="#Terms">Relevant words and their meanings</a></li>
|
||||
<li><a href="#Sample">Sample preparation for spectrometry/spectroscopy</a></li>
|
||||
<li><a href="#DST">Density Separation Treatment</a></li>
|
||||
<li><a href="#Carrier">Choosing a carrier reagent</a></li>
|
||||
</ol>
|
||||
<br>
|
||||
<h1><a name="Terms">Relevant words and their meanings</a></h1>
|
||||
<list>
|
||||
<li><b>Dissonance ratio</b> - This is a pseudoarbitrary value indicating the overal presence of a particular element in a greater composite.
|
||||
It takes into account volume, density, molecular excitation and isotope spread.</li>
|
||||
<li><b>Density separation treatment</b> - The DST procedure purifies a sample, removing any unwanted matter to ensure the finest scan resolution possible.</li>
|
||||
<li><b>Mass spectrometry</b> - MS is the procedure used used to measure and quantify the components of matter. The most prized tool in the field of
|
||||
'Materials analysis'</li>
|
||||
<li><b>Spectroscopy</b> - Spectroscopy is the study of the behaviour of light, commonly used in the 26th century for analysis of anomalous
|
||||
behaviour of energy or light.</li>
|
||||
<li><b>Sample specifity</b> - A pseudoarbitrary value used to indicate how well a sample resonates with the employed carrier reagent. Great specifity
|
||||
(material resonance) indicates that there is much of the carrier reagent present in the sample.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Sample">Sample preparation for spectrometry/spectroscopy</a></h1>
|
||||
When you are readying your spectrometry lab for analysis, you'll need to make sure the sample is in a form the machines can glean data from.
|
||||
<list>
|
||||
<li><b>Obtain material sample</b> - This should be an ordinary chunk of matter the size of your finger, a good example is a 6mm rock core.</li>
|
||||
<li><b>Run density separation treatment</b> - Perform the DST procedure on your sample, following generic specifications.</li>
|
||||
<li><b>Ensure sample purity</b> - DST can sometimes leave behind chemical waste or chunks of matter, make sure there aren't any before proceeding.</li>
|
||||
<li><b>Prepare analysis tray</b> - A sample tray holds a miniscule amount of liquid (2u), but that's all that our spectrometers require for a good reading.</li>
|
||||
<li><b>Choose carrier reagent</b> - Standard spectrometers require 1u of the material sample, and 1u of a 'carrier' reagent to provide control comparison
|
||||
and to enable refraction inferencing.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="DST">Density Separation Treatment</a></h1>
|
||||
<list>
|
||||
<li><b>Obtain material sample</b> - This should be an ordinary chunk of matter the size of your finger, a good example is a 6mm rock core.</li>
|
||||
<li><b>Grind material to powder</b> - In order to treat the material, we have to have the sample in it's basest form.</li>
|
||||
<li><b>Prepare separator solution</b> - A chemical solution called LiNa2WO4, or <i>Lithium Sodium Tungstate</i> must be prepared to separate
|
||||
the the denser clumps of matter out of the refined sample. This is done by mixing 1 part lithium, 2 parts sodium, 1 part tungsten, 4 parts oxygen.</li>
|
||||
<li><b>Mix separator with sample</b> - The resulting mixture is very close to the final product, but make sure to extract any leftover reagents and
|
||||
the chemical waste byproduct.</li>
|
||||
<li><b>Bring sample to boil</b> - Using a standard bunsen burner, bring the mixture to a boil to vaporise the remaining unwanted matter. Remember
|
||||
to again clear out any waste byproducts.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Carrier">Choosing a carrier reagent</a></h1>
|
||||
Below is a list of the most commonly used scan carrier reagents, and the particular molecules they resonate most strongly with:
|
||||
<list>
|
||||
<li><b>Carbon</b> - Trace organic cells, typically used for carbon dating of organic remains.</li>
|
||||
<li><b>Potassium</b> - Long exposure particles floating in the depths of space, such as meteorites.</li>
|
||||
<li><b>Hydrogen</b> - Trace water particles.</li>
|
||||
<li><b>Nitrogen</b> - Crystalline structures.</li>
|
||||
<li><b>Mercury</b> - Metallic derivatives such as ferritic elements and pure metallic substances.</li>
|
||||
<li><b>Iron</b> - Metallic composites such as alloys and atomic structures that are metallic in nature.</li>
|
||||
<li><b>Chlorine</b> - Metamorphic/igneous rock composite.</li>
|
||||
<li><b>Phosphorus</b> - Metamorphic/sedimentary rock composite.</li>
|
||||
<li><b>Plasma</b> - Anomalous materials such as bluespace phased composites that are not fully understood by modern science.</li>
|
||||
</list><br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
|
||||
/obj/item/weapon/book/manual/anomaly_testing
|
||||
name = "Anomalous materials and energies"
|
||||
icon_state = "triangulate"
|
||||
author = "Norman York, formerly of the Tyrolion Institute on Titan"
|
||||
title = "Anomalous materials and energies"
|
||||
dat = {"<html>
|
||||
<head>
|
||||
<style>
|
||||
h1 {font-size: 18px; margin: 15px 0px 5px;}
|
||||
h1 {font-size: 15px; margin: 15px 0px 5px;}
|
||||
li {margin: 2px 0px 2px 15px;}
|
||||
ul {list-style: none; margin: 5px; padding: 0px;}
|
||||
ol {margin: 5px; padding: 0px 15px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1><a name="Contents">Contents</a></h1>
|
||||
<ol>
|
||||
<li><a href="#Anomalies">Forward: Modern attitude towards anomalies</a></li>
|
||||
<li><a href="#Tri">Triangulating anomalous energy readings</a></li>
|
||||
<li><a href="#Synthetic">Harvesting and utilising anomalous energy signatures</a></li>
|
||||
</ol>
|
||||
<br>
|
||||
<h1><a name="Anomalies">Modern attitude towards anomalies</a></h1>
|
||||
It's only when confronted with things we don't know, that we may push back our knowledge of the world around us. Nowhere is this more obvious than the
|
||||
vast and inscrutable mysterious of the cosmos that scholars from such august institutions as the Elysian Institute of the Sciences present
|
||||
formulas and hypotheses for every few decades.<br>
|
||||
<br>
|
||||
Using our vast telescopic array installations and deep space satellite networks, we are able to detect anomalous energy fields and formations in deep space,
|
||||
but are limited to those that are large enough to output energy that will stretch across light years worth of distance between stars.<br>
|
||||
<br>
|
||||
While some sectors (such as the Hydrolian Rift and Keppel's Run) are replete with inexplicable energetic activity and unique phenomena found nowhere else in
|
||||
the galaxy, the majority of space is dry, barren and cold - and if past experience has told us anything, it is that there are always more things we are
|
||||
unable to explain.<br>
|
||||
<br>
|
||||
Indeed, a great source of knowledge and technology has always been those who come before us, in the form of the multitudinous ancient alien precursors that
|
||||
have left scattered remnants of their great past all over settled (and unexplored) space.<br>
|
||||
<br>
|
||||
It is from xenoarchaeologists, high energy materials researchers and technology reconstruction authorities that we are able to theorise on the gifts these
|
||||
species have left behind, and in some cases even reverse engineer or rebuild the technology in question. My colleague Doctor Raymond Ward of the
|
||||
Tyrolian Institute on Titan has made great breakthroughs in a related field through his pioneering development of universally reflective materials capable
|
||||
of harvesting and 'bottling' up virtually any energy emissions yet encountered by spacefaring civilisations.<br>
|
||||
<br>
|
||||
And yet, there are some amongst us who do not see the benefits of those who have come before us - indeed, some among them profess the opinion that there
|
||||
is no species that could possibly match humanity in it's achievements and knowledge, or simply that employing non-human technology is dangerous and unethical.
|
||||
Folly, say I. If it is their desire to throw onto the wayside the greatest achievements <i>in the history of the galaxy</i>, simply for preferment of the
|
||||
greatest achievements <i>in the history of mankind</i>, then they have no business in the establishment of science.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Tri">Triangulating anomalous energy readings</a></h1>
|
||||
Strong energy emissions, when remaining constant from any one fixed location for millenia, can leave an 'imprint' or distinctive energy signature on other
|
||||
matter composites that are spatially fixed relative to the source.<br>
|
||||
<br>
|
||||
By taking samples of such 'fixed' matter, we can apply complex analytics such as the modified Fourier Transform Procedure to reverse engineer the path of the
|
||||
energy, and determine the approximate distance and direction that the energy source is, relative to the sample's point in space.<br>
|
||||
<br>
|
||||
A canny researcher can thusly analyse material samples from pre-chosen points strategically scattered around an area, and if there are any anomalous energy
|
||||
emissions in range of those points, combined they can direct the researcher to the source.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
<h1><a name="Synthetic">Harvesting and utilising anomalous energy signatures</a></h1>
|
||||
As mentioned in the forward, my colleague from the Tyrolian Institute on Saturn's moon of Titan, in the Sol System, Doctor Raymond Ward has made great strides
|
||||
in the area of harvesting and application of the energy emitted by anomalous phenomena from around the galaxy (although I profess I have not yet seen him
|
||||
venture further from his birthplace on Earth than the comfortable distance of the Sol Cis-Oort Satellite Sphere).<br>
|
||||
<br>
|
||||
By employing a patented semi-phased alloy with unique and fascinating bluespace interaction properties, Ward's contraption is able to 'harvest' energy, store
|
||||
it and redirect it later at will (with appropriate electronic mechanisms, of course). Although he professes to see or desire no commercial or material gain
|
||||
for the application and use of said energy once it is harvested, there are no doubt myriad ways we can come to benefit from such things beyond mere research,
|
||||
such as the reconstruction of torn cartiligenous tissue that a peculiar radiation from an amphibious species on Brachis IV was found to emit.<br>
|
||||
<a href="#Contents">Contents</a>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
105
code/modules/research/xenoarchaeology/misc.dm
Normal file
105
code/modules/research/xenoarchaeology/misc.dm
Normal file
@@ -0,0 +1,105 @@
|
||||
|
||||
//---- Noticeboard
|
||||
|
||||
/obj/structure/noticeboard/anomaly/New()
|
||||
notices = 5
|
||||
icon_state = "nboard05"
|
||||
|
||||
//add some memos
|
||||
var/obj/item/weapon/paper/P = new()
|
||||
P.name = "Memo RE: proper analysis procedure"
|
||||
P.info = "Rose,<br>activate <i>then</i> analyse the artifacts, the machine will have a much easier time determining their function/s. Remember to employ basic quasi-elemental forces such as heat, energy, force and various chemical mixes - who knows why those ancient aliens made such obscure activation indices.<br><br>And don't forget your suit this time, I can't afford to have any researchers out of commision for as long as that again!.<br>Ward"
|
||||
P.stamped = list(/obj/item/weapon/stamp/rd)
|
||||
P.overlays = list("paper_stamped_rd")
|
||||
src.contents += P
|
||||
|
||||
P = new()
|
||||
P.name = "Memo RE: materials gathering"
|
||||
P.info = "Corasang,<br>the hands-on approach to gathering our samples may very well be slow at times, but it's safer than allowing the blundering miners to roll willy-nilly over our dig sites in their mechs, destroying everything in the process. And don't forget the escavation tools on your way out there!<br>- R.W"
|
||||
P.stamped = list(/obj/item/weapon/stamp/rd)
|
||||
P.overlays = list("paper_stamped_rd")
|
||||
src.contents += P
|
||||
|
||||
P = new()
|
||||
P.name = "Memo RE: ethical quandaries"
|
||||
P.info = "Darion-<br><br>I don't care what his rank is, our business is that of science and knowledge - questions of moral application do not come into this. Sure, so there are those who would employ the energy-wave particles my modified device has managed to abscond for their own personal gain, but I can hardly see the practical benefits of some of these artifacts our benefactors left behind. Ward--"
|
||||
P.stamped = list(/obj/item/weapon/stamp/rd)
|
||||
P.overlays = list("paper_stamped_rd")
|
||||
src.contents += P
|
||||
|
||||
P = new()
|
||||
P.name = "READ ME! Before you people destroy any more samples"
|
||||
P.info = "how many times do i have to tell you people, these xeno-arch samples are del-i-cate, and should be handled so! careful application of a focussed, ceoncentrated heat or some corrosive liquids should clear away the extraneous carbon matter, while application of an energy beam will most decidedly destroy it entirely! W, <b>the one who signs your paychecks</b>"
|
||||
P.stamped = list(/obj/item/weapon/stamp/rd)
|
||||
P.overlays = list("paper_stamped_rd")
|
||||
src.contents += P
|
||||
|
||||
P = new()
|
||||
P.name = "Reminder regarding the anomalous material suits"
|
||||
P.info = "Do you people think the anomaly suits are cheap to come by? I'm about a hair trigger away from instituting a log book for the damn things. Only wear them if you're going out for a dig, and for god's sake don't go tramping around in them unless you're field testing something, R"
|
||||
P.stamped = list(/obj/item/weapon/stamp/rd)
|
||||
P.overlays = list("paper_stamped_rd")
|
||||
src.contents += P
|
||||
|
||||
//---- Bookcase
|
||||
|
||||
/obj/structure/bookcase/manuals/xenoarchaeology
|
||||
name = "Xenoarchaeology Manuals bookcase"
|
||||
|
||||
New()
|
||||
..()
|
||||
new /obj/item/weapon/book/manual/excavation(src)
|
||||
new /obj/item/weapon/book/manual/mass_spectrometry(src)
|
||||
new /obj/item/weapon/book/manual/materials_chemistry_analysis(src)
|
||||
new /obj/item/weapon/book/manual/anomaly_testing(src)
|
||||
new /obj/item/weapon/book/manual/anomaly_spectroscopy(src)
|
||||
update_icon()
|
||||
|
||||
//---- Lockers and closets
|
||||
|
||||
/obj/structure/closet/secure_closet/xenoarchaeologist
|
||||
name = "Xenoarchaeologist Locker"
|
||||
req_access = list(access_tox_storage)
|
||||
icon_state = "secureres1"
|
||||
icon_closed = "secureres"
|
||||
icon_locked = "secureres1"
|
||||
icon_opened = "secureresopen"
|
||||
icon_broken = "secureresbroken"
|
||||
icon_off = "secureresoff"
|
||||
|
||||
New()
|
||||
..()
|
||||
sleep(2)
|
||||
new /obj/item/clothing/under/rank/scientist(src)
|
||||
new /obj/item/clothing/suit/storage/labcoat(src)
|
||||
new /obj/item/clothing/shoes/white(src)
|
||||
new /obj/item/clothing/glasses/science(src)
|
||||
new /obj/item/device/radio/headset/headset_sci(src)
|
||||
new /obj/item/weapon/storage/belt/archaeology(src)
|
||||
new /obj/item/weapon/storage/box/excavation(src)
|
||||
return
|
||||
|
||||
/obj/structure/closet/excavation
|
||||
name = "Excavation tools"
|
||||
icon_state = "toolcloset"
|
||||
|
||||
New()
|
||||
..()
|
||||
sleep(2)
|
||||
new /obj/item/weapon/storage/belt/archaeology(src)
|
||||
new /obj/item/weapon/storage/box/excavation(src)
|
||||
new /obj/item/device/flashlight/lantern(src)
|
||||
new /obj/item/device/depth_scanner(src)
|
||||
new /obj/item/device/core_sampler(src)
|
||||
new /obj/item/device/gps(src)
|
||||
new /obj/item/device/beacon_locator(src)
|
||||
new /obj/item/device/radio/beacon(src)
|
||||
new /obj/item/clothing/glasses/meson(src)
|
||||
new /obj/item/weapon/pickaxe(src)
|
||||
return
|
||||
|
||||
//---- Isolation room air alarms
|
||||
|
||||
/obj/machinery/alarm/isolation
|
||||
name = "Isolation room air control"
|
||||
req_access = list(access_research)
|
||||
@@ -1,36 +0,0 @@
|
||||
/obj/item/device/depth_scanner
|
||||
name = "depth analysis scanner"
|
||||
desc = "Used to check mass spatial depth and density."
|
||||
icon = 'pda.dmi'
|
||||
icon_state = "crap"
|
||||
item_state = "analyzer"
|
||||
w_class = 1.0
|
||||
flags = FPRINT | TABLEPASS
|
||||
//slot_flags = SLOT_BELT
|
||||
|
||||
/obj/item/weapon/pickaxe/hand_pick
|
||||
name = "hand pick"
|
||||
icon_state = "excavation"
|
||||
item_state = "minipick"
|
||||
digspeed = 50
|
||||
desc = "A smaller, more precise version of the pickaxe."
|
||||
flags = FPRINT | TABLEPASS
|
||||
w_class = 2.0
|
||||
|
||||
/obj/item/weapon/pickaxe/mini_pick
|
||||
name = "mini pick"
|
||||
icon_state = "excavation"
|
||||
item_state = "minipick"
|
||||
digspeed = 60
|
||||
desc = "A miniature excavation tool for precise digging around delicate finds."
|
||||
flags = FPRINT | TABLEPASS
|
||||
w_class = 1.0
|
||||
|
||||
//todo: this
|
||||
/obj/item/device/beacon_locator
|
||||
name = "locater device"
|
||||
desc = "Used to triangulate position signal emitters."
|
||||
icon = 'device.dmi'
|
||||
icon_state = "pinoff" //pinonfar, pinonmedium, pinonclose, pinondirect, pinonnull
|
||||
item_state = "electronic"
|
||||
w_class = 1.0
|
||||
@@ -0,0 +1,196 @@
|
||||
|
||||
/obj/item/weapon/anobattery
|
||||
name = "Anomaly power battery"
|
||||
icon = 'icons/obj/xenoarchaeology.dmi'
|
||||
icon_state = "anobattery0"
|
||||
var/datum/artifact_effect/battery_effect
|
||||
var/capacity = 200
|
||||
var/stored_charge = 0
|
||||
var/effect_id = ""
|
||||
|
||||
/obj/item/weapon/anobattery/New()
|
||||
battery_effect = new()
|
||||
|
||||
/obj/item/weapon/anobattery/proc/UpdateSprite()
|
||||
var/p = (stored_charge/capacity)*100
|
||||
p = min(p, 100)
|
||||
icon_state = "anobattery[round(p,25)]"
|
||||
|
||||
/obj/item/weapon/anodevice
|
||||
name = "Anomaly power utilizer"
|
||||
icon = 'xenoarchaeology.dmi'
|
||||
icon_state = "anodev"
|
||||
var/cooldown = 0
|
||||
var/activated = 0
|
||||
var/timing = 0
|
||||
var/time = 50
|
||||
var/archived_time = 50
|
||||
var/obj/item/weapon/anobattery/inserted_battery
|
||||
var/turf/archived_loc
|
||||
|
||||
/obj/item/weapon/anodevice/New()
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
|
||||
/obj/item/weapon/anodevice/attackby(var/obj/I as obj, var/mob/user as mob)
|
||||
if(istype(I, /obj/item/weapon/anobattery))
|
||||
if(!inserted_battery)
|
||||
user << "\blue You insert the battery."
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
inserted_battery = I
|
||||
UpdateSprite()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/anodevice/attack_self(var/mob/user as mob)
|
||||
return src.interact(user)
|
||||
|
||||
/obj/item/weapon/anodevice/interact(var/mob/user)
|
||||
user.set_machine(src)
|
||||
var/dat = "<b>Anomalous Materials Energy Utiliser</b><br>"
|
||||
if(inserted_battery)
|
||||
if(cooldown)
|
||||
dat += "Cooldown in progress, please wait.<br>"
|
||||
else if(activated)
|
||||
if(timing)
|
||||
dat += "Device active.<br>"
|
||||
else
|
||||
dat += "Device active in timed mode.<br>"
|
||||
|
||||
dat += "[inserted_battery] inserted, anomaly ID: [inserted_battery.battery_effect.artifact_id ? inserted_battery.battery_effect.artifact_id : "NA"]<BR>"
|
||||
dat += "<b>Total Power:</b> [inserted_battery.stored_charge]/[inserted_battery.capacity]<BR><BR>"
|
||||
dat += "<b>Timed activation:</b> <A href='?src=\ref[src];neg_changetime_max=-100'>--</a> <A href='?src=\ref[src];neg_changetime=-10'>-</a> [time >= 1000 ? "[time/10]" : time >= 100 ? " [time/10]" : " [time/10]" ] <A href='?src=\ref[src];changetime=10'>+</a> <A href='?src=\ref[src];changetime_max=100'>++</a><BR>"
|
||||
if(cooldown)
|
||||
dat += "<font color=red>Cooldown in progress.</font><BR>"
|
||||
dat += "<br>"
|
||||
else if(!activated)
|
||||
dat += "<A href='?src=\ref[src];startup=1'>Start</a><BR>"
|
||||
dat += "<A href='?src=\ref[src];startup=1;starttimer=1'>Start in timed mode</a><BR>"
|
||||
else
|
||||
dat += "<a href='?src=\ref[src];shutdown=1'>Shutdown emission</a><br>"
|
||||
dat += "<br>"
|
||||
dat += "<A href='?src=\ref[src];ejectbattery=1'>Eject battery</a><BR>"
|
||||
else
|
||||
dat += "Please insert battery<br>"
|
||||
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
|
||||
dat += "<hr>"
|
||||
dat += "<a href='?src=\ref[src]'>Refresh</a> <a href='?src=\ref[src];close=1'>Close</a>"
|
||||
|
||||
user << browse(dat, "window=anodevice;size=400x500")
|
||||
onclose(user, "anodevice")
|
||||
|
||||
/obj/item/weapon/anodevice/process()
|
||||
if(cooldown > 0)
|
||||
cooldown -= 1
|
||||
if(cooldown <= 0)
|
||||
cooldown = 0
|
||||
src.visible_message("\blue \icon[src] [src] chimes.", "\blue \icon[src] You hear something chime.")
|
||||
else if(activated)
|
||||
if(inserted_battery && inserted_battery.battery_effect)
|
||||
//make sure the effect is active
|
||||
if(!inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate(1)
|
||||
|
||||
//update the effect loc
|
||||
var/turf/T = get_turf(src)
|
||||
if(T != archived_loc)
|
||||
archived_loc = T
|
||||
inserted_battery.battery_effect.UpdateMove()
|
||||
|
||||
//process the effect
|
||||
inserted_battery.battery_effect.process()
|
||||
//if someone is holding the device, do the effect on them
|
||||
if(inserted_battery.battery_effect.effect == 0 && ismob(src.loc))
|
||||
inserted_battery.battery_effect.DoEffectTouch(src.loc)
|
||||
|
||||
//handle charge
|
||||
inserted_battery.stored_charge -= 1
|
||||
if(inserted_battery.stored_charge <= 0)
|
||||
shutdown_emission()
|
||||
|
||||
//handle timed mode
|
||||
if(timing)
|
||||
time -= 1
|
||||
if(time <= 0)
|
||||
shutdown_emission()
|
||||
else
|
||||
shutdown()
|
||||
|
||||
/obj/item/weapon/anodevice/proc/shutdown_emission()
|
||||
if(activated)
|
||||
activated = 0
|
||||
timing = 0
|
||||
src.visible_message("\blue \icon[src] [src] buzzes.", "\icon[src]\blue You hear something buzz.")
|
||||
|
||||
cooldown = archived_time / 2
|
||||
|
||||
if(inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate(1)
|
||||
|
||||
/obj/item/weapon/anodevice/Topic(href, href_list)
|
||||
|
||||
if(href_list["neg_changetime_max"])
|
||||
time += -100
|
||||
if(time > inserted_battery.capacity)
|
||||
time = inserted_battery.capacity
|
||||
else if (time < 0)
|
||||
time = 0
|
||||
if(href_list["neg_changetime"])
|
||||
time += -10
|
||||
if(time > inserted_battery.capacity)
|
||||
time = inserted_battery.capacity
|
||||
else if (time < 0)
|
||||
time = 0
|
||||
if(href_list["changetime"])
|
||||
time += 10
|
||||
if(time > inserted_battery.capacity)
|
||||
time = inserted_battery.capacity
|
||||
else if (time < 0)
|
||||
time = 0
|
||||
if(href_list["changetime_max"])
|
||||
time += 100
|
||||
if(time > inserted_battery.capacity)
|
||||
time = inserted_battery.capacity
|
||||
else if (time < 0)
|
||||
time = 0
|
||||
if(href_list["startup"])
|
||||
activated = 1
|
||||
if(!inserted_battery.battery_effect.activated)
|
||||
inserted_battery.battery_effect.ToggleActivate(1)
|
||||
if(href_list["shutdown"])
|
||||
activated = 0
|
||||
if(href_list["starttimer"])
|
||||
timing = 1
|
||||
archived_time = time
|
||||
if(href_list["ejectbattery"])
|
||||
shutdown_emission()
|
||||
inserted_battery.loc = get_turf(src)
|
||||
inserted_battery = null
|
||||
UpdateSprite()
|
||||
if(href_list["close"])
|
||||
usr << browse(null, "window=anodevice")
|
||||
usr.unset_machine(src)
|
||||
|
||||
..()
|
||||
updateDialog()
|
||||
|
||||
/obj/item/weapon/anodevice/proc/UpdateSprite()
|
||||
if(!inserted_battery)
|
||||
icon_state = "anodev"
|
||||
return
|
||||
var/p = (inserted_battery.stored_charge/inserted_battery.capacity)*100
|
||||
p = min(p, 100)
|
||||
icon_state = "anodev[round(p,25)]"
|
||||
|
||||
/obj/item/weapon/anodevice/Del()
|
||||
processing_objects.Remove(src)
|
||||
..()
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user