Merge pull request #5276 from caelaislinn/xenoarchaeology

Xenoarchaeology
This commit is contained in:
Chinsky
2014-06-20 14:41:25 +04:00
42 changed files with 1505 additions and 388 deletions
+6 -3
View File
@@ -1,9 +1,6 @@
/**********************Mineral deposits**************************/
datum/controller/game_controller/var/list/artifact_spawning_turfs = list()
var/list/artifact_spawn = list() // Runtime fix for geometry loading before controller is instantiated.
/turf/simulated/mineral //wall piece
name = "Rock"
icon = 'icons/turf/walls.dmi'
@@ -480,6 +477,12 @@ var/list/artifact_spawn = list() // Runtime fix for geometry loading before cont
for(var/obj/item/weapon/ore/O in contents)
O.attackby(W,user)
return
else if(istype(W,/obj/item/weapon/storage/bag/fossils))
var/obj/item/weapon/storage/bag/fossils/S = W
if(S.collection_mode)
for(var/obj/item/weapon/fossil/F in contents)
F.attackby(W,user)
return
else
..(W,user)
@@ -5,8 +5,9 @@
icon = 'icons/obj/cryogenics.dmi'
icon_state = "cellold0"
var/spawn_type
var/current_ticks_spawning = 0
var/ticks_required_to_spawn
var/time_spent_spawning = 0
var/time_per_spawn = 0
var/last_process= 0
density = 1
var/previous_power_state = 0
@@ -17,7 +18,7 @@
/obj/machinery/auto_cloner/New()
..()
ticks_required_to_spawn = rand(240,1440)
time_per_spawn = rand(1200,3600)
//33% chance to spawn nasties
if(prob(33))
@@ -53,13 +54,12 @@
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
if(time_spent_spawning >= time_per_spawn)
time_spent_spawning = 0
use_power = 1
src.visible_message("\blue \icon[src] [src] pings!")
icon_state = "cellold1"
@@ -68,7 +68,7 @@
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)
if(time_spent_spawning / time_per_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..."
@@ -76,6 +76,8 @@
use_power = 1
icon_state = "cellold1"
desc = "It's full of a bubbling viscous liquid, and is lit by a mysterious glow."
time_spent_spawning = time_spent_spawning + world.time - last_process
else
if(previous_power_state)
previous_power_state = 0
@@ -83,5 +85,6 @@
src.visible_message("\blue \icon[src] [src] suddenly shuts down.")
//cloned mob slowly breaks down
if(current_ticks_spawning > 0)
current_ticks_spawning--
time_spent_spawning = max(time_spent_spawning + last_process - world.time, 0)
last_process = world.time
@@ -10,10 +10,15 @@
active_power_usage = 1000
use_power = 1
var/spawn_progress = 0
var/max_spawn_ticks = 5
var/spawn_progress_time = 0
var/max_spawn_time = 50
var/last_process_time = 0
var/list/construction = list()
var/list/spawning_types = list()
var/list/stored_materials = list()
var/fail_message
/obj/machinery/replicator/New()
..()
@@ -66,32 +71,52 @@
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")], "
var/button_desc = "a [pick("yellow","purple","green","blue","red","orange","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
fail_message = "\blue \icon[src] a [pick("loud","soft","sinister","eery","triumphant","depressing","cheerful","angry")] \
[pick("horn","beep","bing","bleep","blat","honk","hrumph","ding")] sounds and a \
[pick("yellow","purple","green","blue","red","orange","white")] \
[pick("light","dial","meter","window","protrusion","knob","antenna","swirly thing")] \
[pick("swirls","flashes","whirrs","goes schwing","blinks","flickers","strobes","lights up")] on the \
[pick("front","side","top","bottom","rear","inside")] of [src]. A [pick("slot","funnel","chute","tube")] opens up in the \
[pick("front","side","top","bottom","rear","inside")]."
/obj/machinery/replicator/process()
if(spawning_types.len && powered())
spawn_progress++
if(spawn_progress > max_spawn_ticks)
spawn_progress_time += world.time - last_process_time
if(spawn_progress_time > max_spawn_time)
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)
var/obj/source_material = pop(stored_materials)
var/spawn_type = pop(spawning_types)
var/obj/spawned_obj = new spawn_type(src.loc)
if(source_material)
if(lentext(source_material.name) < MAX_MESSAGE_LEN)
spawned_obj.name = "[source_material] " + spawned_obj.name
if(lentext(source_material.desc) < MAX_MESSAGE_LEN * 2)
if(spawned_obj.desc)
spawned_obj.desc += " It is made of [source_material]."
else
spawned_obj.desc = "It is made of [source_material]."
source_material.loc = null
if(!spawning_types.len)
spawn_progress_time = 0
max_spawn_time = rand(30,100)
if(!spawning_types.len || !stored_materials.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")].")
last_process_time = world.time
/obj/machinery/replicator/attack_hand(mob/user as mob)
interact(user)
@@ -103,17 +128,26 @@
user << browse(dat, "window=alien_replicator")
/obj/machinery/replicator/attackby(obj/item/weapon/W as obj, mob/living/user as mob)
user.drop_item()
W.loc = src
stored_materials.Add(W)
src.visible_message("\blue [user] inserts [W] into [src].")
/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.")
if(stored_materials.len > spawning_types.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)"
spawning_types.Add(construction[construction[index]])
spawn_progress_time = 0
use_power = 2
icon_state = "borgcharger1(old)"
else
src.visible_message(fail_message)
@@ -12,6 +12,7 @@
/datum/artifact_effect/cold/DoEffectTouch(var/mob/user)
if(holder)
user << "\blue A chill passes up your spine!"
var/datum/gas_mixture/env = holder.loc.return_air()
if(env)
env.temperature = max(env.temperature - rand(5,50), 0)
@@ -41,7 +41,8 @@
/datum/artifact_effect/badfeeling/DoEffectAura()
if(holder)
for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/human/H in range(src.effectrange,T))
if(prob(5))
if(prob(75))
H << "<font color='red'>[pick(messages)]</font>"
@@ -54,7 +55,8 @@
/datum/artifact_effect/badfeeling/DoEffectPulse()
if(holder)
for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/human/H in range(src.effectrange,T))
if(prob(50))
if(prob(95))
H << "<font color='red' size='[num2text(rand(1,5))]'><b>[pick(drastic_messages)]</b></font>"
@@ -15,7 +15,8 @@
/datum/artifact_effect/cellcharge/DoEffectAura()
if(holder)
for (var/obj/machinery/power/apc/C in range(200, holder))
var/turf/T = get_turf(holder)
for (var/obj/machinery/power/apc/C in range(200, T))
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))
@@ -28,7 +29,8 @@
/datum/artifact_effect/cellcharge/DoEffectPulse()
if(holder)
for (var/obj/machinery/power/apc/C in range(200, holder))
var/turf/T = get_turf(holder)
for (var/obj/machinery/power/apc/C in range(200, T))
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))
@@ -17,7 +17,8 @@
/datum/artifact_effect/celldrain/DoEffectAura()
if(holder)
for (var/obj/machinery/power/apc/C in range(200, holder))
var/turf/T = get_turf(holder)
for (var/obj/machinery/power/apc/C in range(200, T))
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))
@@ -30,7 +31,8 @@
/datum/artifact_effect/celldrain/DoEffectPulse()
if(holder)
for (var/obj/machinery/power/apc/C in range(200, holder))
var/turf/T = get_turf(holder)
for (var/obj/machinery/power/apc/C in range(200, T))
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))
@@ -30,7 +30,8 @@
/datum/artifact_effect/dnaswitch/DoEffectAura()
if(holder)
for(var/mob/living/carbon/human/H in range(src.effectrange,holder))
var/turf/T = get_turf(holder)
for(var/mob/living/carbon/human/H in range(src.effectrange,T))
var/weakness = GetAnomalySusceptibility(H)
if(prob(weakness * 100))
if(prob(30))
@@ -48,7 +49,8 @@
/datum/artifact_effect/dnaswitch/DoEffectPulse()
if(holder)
for(var/mob/living/carbon/human/H in range(200, holder))
var/turf/T = get_turf(holder)
for(var/mob/living/carbon/human/H in range(200, T))
var/weakness = GetAnomalySusceptibility(H)
if(prob(weakness * 100))
if(prob(75))
@@ -9,5 +9,6 @@
/datum/artifact_effect/emp/DoEffectPulse()
if(holder)
empulse(get_turf(holder), effectrange/2, effectrange)
var/turf/T = get_turf(holder)
empulse(T, effectrange/2, effectrange)
return 1
@@ -39,7 +39,8 @@
/datum/artifact_effect/goodfeeling/DoEffectAura()
if(holder)
for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/human/H in range(src.effectrange,T))
if(prob(5))
if(prob(75))
H << "<font color='blue'>[pick(messages)]</font>"
@@ -52,7 +53,8 @@
/datum/artifact_effect/goodfeeling/DoEffectPulse()
if(holder)
for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/human/H in range(src.effectrange,T))
if(prob(50))
if(prob(95))
H << "<font color='blue' size='[num2text(rand(1,5))]'><b>[pick(drastic_messages)]</b></font>"
@@ -36,7 +36,8 @@
/datum/artifact_effect/heal/DoEffectAura()
//todo: check over this properly
if(holder)
for (var/mob/living/carbon/C in range(src.effectrange,holder))
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/C in range(src.effectrange,T))
var/weakness = GetAnomalySusceptibility(C)
if(prob(weakness * 100))
if(prob(10))
@@ -51,7 +52,8 @@
/datum/artifact_effect/heal/DoEffectPulse()
//todo: check over this properly
if(holder)
for (var/mob/living/carbon/C in range(src.effectrange,holder))
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/C in range(src.effectrange,T))
var/weakness = GetAnomalySusceptibility(C)
if(prob(weakness * 100))
C << "\blue A wave of energy invigorates you."
@@ -15,6 +15,7 @@
/datum/artifact_effect/heat/DoEffectTouch(var/mob/user)
if(holder)
user << "\red You feel a wave of heat travel up your spine!"
var/datum/gas_mixture/env = holder.loc.return_air()
if(env)
env.temperature += rand(5,50)
@@ -21,7 +21,8 @@
/datum/artifact_effect/hurt/DoEffectAura()
if(holder)
for (var/mob/living/carbon/C in range(src.effectrange,holder))
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/C in range(src.effectrange,T))
var/weakness = GetAnomalySusceptibility(C)
if(prob(weakness * 100))
if(prob(10))
@@ -35,7 +36,8 @@
/datum/artifact_effect/hurt/DoEffectPulse()
if(holder)
for (var/mob/living/carbon/C in range(effectrange, holder))
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/C in range(effectrange, T))
var/weakness = GetAnomalySusceptibility(C)
if(prob(weakness * 100))
C << "\red A wave of painful energy strikes you!"
@@ -16,14 +16,16 @@
/datum/artifact_effect/radiate/DoEffectAura()
if(holder)
for (var/mob/living/M in range(src.effectrange,holder))
var/turf/T = get_turf(holder)
for (var/mob/living/M in range(src.effectrange,T))
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))
var/turf/T = get_turf(holder)
for (var/mob/living/M in range(src.effectrange,T))
M.apply_effect(radiation_amount * 25,IRRADIATE,0)
M.updatehealth()
return 1
@@ -17,7 +17,8 @@
/datum/artifact_effect/roboheal/DoEffectAura()
if(holder)
for (var/mob/living/silicon/robot/M in range(src.effectrange,holder))
var/turf/T = get_turf(holder)
for (var/mob/living/silicon/robot/M in range(src.effectrange,T))
if(prob(10))
M << "\blue SYSTEM ALERT: Beneficial energy field detected!"
M.adjustBruteLoss(-1)
@@ -27,7 +28,8 @@
/datum/artifact_effect/roboheal/DoEffectPulse()
if(holder)
for (var/mob/living/silicon/robot/M in range(src.effectrange,holder))
var/turf/T = get_turf(holder)
for (var/mob/living/silicon/robot/M in range(src.effectrange,T))
M << "\blue SYSTEM ALERT: Structural damage has been repaired by energy pulse!"
M.adjustBruteLoss(-10)
M.adjustFireLoss(-10)
@@ -17,7 +17,8 @@
/datum/artifact_effect/robohurt/DoEffectAura()
if(holder)
for (var/mob/living/silicon/robot/M in range(src.effectrange,holder))
var/turf/T = get_turf(holder)
for (var/mob/living/silicon/robot/M in range(src.effectrange,T))
if(prob(10)) M << "\red SYSTEM ALERT: Harmful energy field detected!"
M.adjustBruteLoss(1)
M.adjustFireLoss(1)
@@ -26,7 +27,8 @@
/datum/artifact_effect/robohurt/DoEffectPulse()
if(holder)
for (var/mob/living/silicon/robot/M in range(src.effectrange,holder))
var/turf/T = get_turf(holder)
for (var/mob/living/silicon/robot/M in range(src.effectrange,T))
M << "\red SYSTEM ALERT: Structural damage inflicted by energy pulse!"
M.adjustBruteLoss(10)
M.adjustFireLoss(10)
@@ -22,7 +22,8 @@
/datum/artifact_effect/sleepy/DoEffectAura()
if(holder)
for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/human/H in range(src.effectrange,T))
var/weakness = GetAnomalySusceptibility(H)
if(prob(weakness * 100))
if(prob(10))
@@ -35,7 +36,8 @@
/datum/artifact_effect/sleepy/DoEffectPulse()
if(holder)
for(var/mob/living/carbon/human/H in range(src.effectrange, holder))
var/turf/T = get_turf(holder)
for(var/mob/living/carbon/human/H in range(src.effectrange, T))
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.")
@@ -9,33 +9,35 @@
/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))
var/susceptibility = GetAnomalySusceptibility(C)
if(prob(susceptibility * 100))
C << "\red A powerful force overwhelms your consciousness."
C.weakened += 45 * weakness
C.stuttering += 45 * weakness
C.stunned += rand(1,10) * weakness
C.Weaken(rand(1,10) * susceptibility)
C.stuttering += 30 * susceptibility
C.Stun(rand(1,10) * susceptibility)
/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))
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/C in range(src.effectrange,T))
var/susceptibility = GetAnomalySusceptibility(C)
if(prob(10 * susceptibility))
C << "\red Your body goes numb for a moment."
C.weakened += 2
C.Weaken(2)
C.stuttering += 2
if(prob(10))
C.stunned += 1
C.Stun(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))
var/turf/T = get_turf(holder)
for (var/mob/living/carbon/C in range(src.effectrange,T))
var/susceptibility = GetAnomalySusceptibility(C)
if(prob(100 * susceptibility))
C << "\red A wave of energy overwhelms your senses!"
C.weakened += 4 * weakness
C.stuttering += 4 * weakness
C.SetWeakened(4 * susceptibility)
C.stuttering = 4 * susceptibility
if(prob(10))
C.stunned += 1 * weakness
C.SetStunned(1 * susceptibility)
@@ -6,60 +6,53 @@
/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()
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()
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(orange(get_turf(holder), 50))
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/turf/T = get_turf(holder)
for (var/mob/living/M in range(src.effectrange,T))
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()
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()
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(orange(get_turf(T), 50))
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/turf/T = get_turf(holder)
for (var/mob/living/M in range(src.effectrange, T))
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!"
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()
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()
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(orange(get_turf(T), 50))
sparks = new /datum/effect/effect/system/spark_spread()
sparks.set_up(3, 0, get_turf(M))
sparks.start()
@@ -113,7 +113,10 @@
switch(find_type)
if(1)
item_type = "bowl"
new_item = new /obj/item/weapon/reagent_containers/glass(src.loc)
if(prob(33))
new_item = new /obj/item/weapon/reagent_containers/glass/replenishing(src.loc)
else
new_item = new /obj/item/weapon/reagent_containers/glass/beaker(src.loc)
new_item.icon = 'icons/obj/xenoarchaeology.dmi'
new_item.icon_state = "bowl"
apply_image_decorations = 1
@@ -121,7 +124,10 @@
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)
if(prob(33))
new_item = new /obj/item/weapon/reagent_containers/glass/replenishing(src.loc)
else
new_item = new /obj/item/weapon/reagent_containers/glass/beaker(src.loc)
new_item.icon = 'icons/obj/xenoarchaeology.dmi'
new_item.icon_state = "urn"
apply_image_decorations = 1
@@ -139,11 +145,14 @@
"It's a mystery how anyone is supposed to eat with this",\
"You wonder what the creator's mouth was shaped like")]."
if(4)
name = "statuette"
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 fetal position","cheering","sobbing","making a plaintive gesture","making a rude gesture")]."
if(prob(25))
new_item = new /obj/item/weapon/vampiric(src.loc)
if(5)
item_type = "instrument"
icon_state = "instrument"
@@ -194,6 +203,9 @@
new_item = new /obj/item/weapon/storage/box(src.loc)
new_item.icon = 'icons/obj/xenoarchaeology.dmi'
new_item.icon_state = "box"
var/obj/item/weapon/storage/box/new_box = new_item
new_box.max_w_class = pick(1,2,2,3,3,3,4,4)
new_box.max_combined_w_class = rand(new_box.max_w_class, new_box.max_w_class * 10)
if(prob(30))
apply_image_decorations = 1
if(12)
@@ -260,6 +272,10 @@
apply_material_decorations = 0
if(prob(10))
apply_image_decorations = 1
if(prob(25))
new_item = new /obj/item/device/soulstone(src.loc)
new_item.icon = 'icons/obj/xenoarchaeology.dmi'
new_item.icon_state = icon_state
if(17)
//cultblade
apply_prefix = 0
@@ -462,7 +478,12 @@
"It doesn't look human.")
apply_image_decorations = 0
apply_material_decorations = 0
if(35)
//gas mask
if(prob(25))
new_item = new /obj/item/clothing/mask/gas/poltergeist(src.loc)
else
new_item = new /obj/item/clothing/mask/gas(src.loc)
var/decorations = ""
if(apply_material_decorations)
source_material = pick("cordite","quadrinium","steel","titanium","aluminium","ferritic-alloy","plasteel","duranium")
@@ -520,18 +541,14 @@
new_item.name = name
new_item.desc = src.desc
if(talkative && istype(new_item,/obj/item/weapon))
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
if(talkative)
new_item.talking_atom = new()
talking_atom.holder_atom = new_item
talking_atom.init()
del(src)
else if(talkative)
listening_to_players = 1
if(prob(25))
speaking_to_players = 1
processing_objects.Add(src)
src.talking_atom = new()
talking_atom.holder_atom = src
talking_atom.init()
@@ -33,7 +33,8 @@
#define ARCHAEO_REMAINS_HUMANOID 32
#define ARCHAEO_REMAINS_ROBOT 33
#define ARCHAEO_REMAINS_XENO 34
#define MAX_ARCHAEO 34
#define ARCHAEO_GASMASK 35
#define MAX_ARCHAEO 35
//eggs
//droppings
//footprints
@@ -119,6 +120,8 @@
return "carbon"
if(ARCHAEO_REMAINS_XENO)
return "carbon"
if(ARCHAEO_GASMASK)
return "carbon"
return "phoron"
//see /turf/simulated/mineral/New() in code/modules/mining/mine_turfs.dm
@@ -153,6 +156,7 @@
100;ARCHAEO_PEN,\
100;ARCHAEO_LIGHTER,\
100;ARCHAEO_BOX,\
75;ARCHAEO_GASMASK,\
75;ARCHAEO_COIN,\
75;ARCHAEO_UNKNOWN,\
50;ARCHAEO_SHARD,\
@@ -161,6 +165,7 @@
)
if(DIGSITE_TECHNICAL)
find_type = pick(\
125;ARCHAEO_GASMASK,\
100;ARCHAEO_METAL,\
100;ARCHAEO_GASTANK,\
100;ARCHAEO_TELEBEACON,\
@@ -175,6 +180,7 @@
if(DIGSITE_TEMPLE)
find_type = pick(\
200;ARCHAEO_CULTROBES,\
200;ARCHAEO_STATUETTE,\
100;ARCHAEO_URN,\
100;ARCHAEO_BOWL,\
100;ARCHAEO_KNIFE,\
@@ -188,7 +194,8 @@
10;ARCHAEO_CLAYMORE,\
10;ARCHAEO_SHARD,\
10;ARCHAEO_RODS,\
10;ARCHAEO_METAL\
10;ARCHAEO_METAL,\
10;ARCHAEO_GASMASK,\
)
if(DIGSITE_WAR)
find_type = pick(\
@@ -200,6 +207,7 @@
50;ARCHAEO_UNKNOWN,\
50;ARCHAEO_CULTROBES,\
50;ARCHAEO_CULTBLADE,\
50;ARCHAEO_GASMASK,\
25;ARCHAEO_HANDCUFFS,\
25;ARCHAEO_BEARTRAP,\
25;ARCHAEO_TOOL\
@@ -262,6 +270,8 @@ var/list/finds_as_strings = list( \
#undef ARCHAEO_REMAINS_HUMANOID
#undef ARCHAEO_REMAINS_ROBOT
#undef ARCHAEO_REMAINS_XENO
#undef ARCHAEO_GASMASK
#undef MAX_ARCHAEO
#undef DIGSITE_GARDEN
#undef DIGSITE_ANIMAL
@@ -7,6 +7,7 @@
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "bone"
desc = "It's a fossil."
var/animal = 1
/obj/item/weapon/fossil/base/New()
var/list/l = list("/obj/item/weapon/fossil/bone"=9,"/obj/item/weapon/fossil/skull"=3,
@@ -97,6 +98,7 @@
name = "Fossilised plant"
icon_state = "plant1"
desc = "It's fossilised plant remains."
animal = 0
/obj/item/weapon/fossil/plant/New()
icon_state = "plant[rand(1,4)]"
@@ -0,0 +1,203 @@
//endless reagents!
/obj/item/weapon/reagent_containers/glass/replenishing
var/spawning_id
/obj/item/weapon/reagent_containers/glass/replenishing/New()
..()
processing_objects.Add(src)
spawning_id = pick("blood","holywater","lube","stoxin","ethanol","ice","glycerol","fuel","cleaner")
/obj/item/weapon/reagent_containers/glass/replenishing/process()
reagents.add_reagent(spawning_id, 0.3)
//a talking gas mask!
/obj/item/clothing/mask/gas/poltergeist
var/list/heard_talk = list()
var/last_twitch = 0
var/max_stored_messages = 100
/obj/item/clothing/mask/gas/poltergeist/New()
processing_objects.Add(src)
/obj/item/clothing/mask/gas/poltergeist/process()
if(heard_talk.len && istype(src.loc, /mob/living) && prob(10))
var/mob/living/M = src.loc
M.say(pick(heard_talk))
/obj/item/clothing/mask/gas/poltergeist/hear_talk(mob/M as mob, text)
..()
if(heard_talk.len > max_stored_messages)
heard_talk.Remove(pick(heard_talk))
heard_talk.Add(text)
if(istype(src.loc, /mob/living) && world.time - last_twitch > 50)
last_twitch = world.time
//a vampiric statuette
//todo: cult integration
/obj/item/weapon/vampiric
name = "statuette"
icon_state = "statuette"
icon = 'icons/obj/xenoarchaeology.dmi'
var/charges = 0
var/list/nearby_mobs = list()
var/last_bloodcall = 0
var/bloodcall_interval = 50
var/last_eat = 0
var/eat_interval = 100
var/wight_check_index = 1
var/list/shadow_wights = list()
/obj/item/weapon/vampiric/New()
..()
processing_objects.Add(src)
/obj/item/weapon/vampiric/process()
//see if we've identified anyone nearby
if(world.time - last_bloodcall > bloodcall_interval && nearby_mobs.len)
var/mob/living/carbon/human/M = pop(nearby_mobs)
if(M in view(7,src) && M.health > 20)
if(prob(50))
bloodcall(M)
nearby_mobs.Add(M)
//suck up some blood to gain power
if(world.time - last_eat > eat_interval)
var/obj/effect/decal/cleanable/blood/B = locate() in range(2,src)
if(B)
last_eat = world.time
B.loc = null
if(istype(B, /obj/effect/decal/cleanable/blood/drip))
charges += 0.25
else
charges += 1
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1, -3)
//use up stored charges
if(charges >= 10)
charges -= 10
new /obj/effect/spider/eggcluster(pick(view(1,src)))
if(charges >= 3)
if(prob(5))
charges -= 1
var/spawn_type = pick(/mob/living/simple_animal/hostile/creature)
new spawn_type(pick(view(1,src)))
playsound(src.loc, pick('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg'), 50, 1, -3)
if(charges >= 1)
if(shadow_wights.len < 5 && prob(5))
shadow_wights.Add(new /obj/effect/shadow_wight(src.loc))
playsound(src.loc, 'sound/effects/ghost.ogg', 50, 1, -3)
charges -= 0.1
if(charges >= 0.1)
if(prob(5))
src.visible_message("\red \icon[src] [src]'s eyes glow ruby red for a moment!")
charges -= 0.1
//check on our shadow wights
if(shadow_wights.len)
wight_check_index++
if(wight_check_index > shadow_wights.len)
wight_check_index = 1
var/obj/effect/shadow_wight/W = shadow_wights[wight_check_index]
if(isnull(W))
shadow_wights.Remove(wight_check_index)
else if(isnull(W.loc))
shadow_wights.Remove(wight_check_index)
else if(get_dist(W, src) > 10)
shadow_wights.Remove(wight_check_index)
/obj/item/weapon/vampiric/hear_talk(mob/M as mob, text)
..()
if(world.time - last_bloodcall >= bloodcall_interval && M in view(7, src))
bloodcall(M)
/obj/item/weapon/vampiric/proc/bloodcall(var/mob/living/carbon/human/M)
last_bloodcall = world.time
if(istype(M))
playsound(src.loc, pick('sound/hallucinations/wail.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/far_noise.ogg'), 50, 1, -3)
nearby_mobs.Add(M)
var/target = pick("chest","groin","head","l_arm","r_arm","r_leg","l_leg","l_hand","r_hand","l_foot","r_foot")
M.apply_damage(rand(5, 10), BRUTE, target)
M << "\red The skin on your [parse_zone(target)] feels like it's ripping apart, and a stream of blood flies out."
var/obj/effect/decal/cleanable/blood/splatter/animated/B = new(M.loc)
B.target_turf = pick(range(1, src))
B.blood_DNA = list()
B.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
M.vessel.remove_reagent("blood",rand(25,50))
//animated blood 2 SPOOKY
/obj/effect/decal/cleanable/blood/splatter/animated
var/turf/target_turf
var/loc_last_process
/obj/effect/decal/cleanable/blood/splatter/animated/New()
..()
processing_objects.Add(src)
loc_last_process = src.loc
/obj/effect/decal/cleanable/blood/splatter/animated/process()
if(target_turf && src.loc != target_turf)
step_towards(src,target_turf)
if(src.loc == loc_last_process)
target_turf = null
loc_last_process = src.loc
//leave some drips behind
if(prob(50))
var/obj/effect/decal/cleanable/blood/drip/D = new(src.loc)
D.blood_DNA = src.blood_DNA.Copy()
if(prob(50))
D = new(src.loc)
D.blood_DNA = src.blood_DNA.Copy()
if(prob(50))
D = new(src.loc)
D.blood_DNA = src.blood_DNA.Copy()
else
..()
/obj/effect/shadow_wight
name = "shadow wight"
icon = 'icons/mob/mob.dmi'
icon_state = "shade"
density = 1
/obj/effect/shadow_wight/New()
processing_objects.Add(src)
/obj/effect/shadow_wight/process()
if(src.loc)
src.loc = get_turf(pick(orange(1,src)))
var/mob/living/carbon/M = locate() in src.loc
if(M)
playsound(src.loc, pick('sound/hallucinations/behind_you1.ogg',\
'sound/hallucinations/behind_you2.ogg',\
'sound/hallucinations/i_see_you1.ogg',\
'sound/hallucinations/i_see_you2.ogg',\
'sound/hallucinations/im_here1.ogg',\
'sound/hallucinations/im_here2.ogg',\
'sound/hallucinations/look_up1.ogg',\
'sound/hallucinations/look_up2.ogg',\
'sound/hallucinations/over_here1.ogg',\
'sound/hallucinations/over_here2.ogg',\
'sound/hallucinations/over_here3.ogg',\
'sound/hallucinations/turn_around1.ogg',\
'sound/hallucinations/turn_around2.ogg',\
), 50, 1, -3)
M.sleeping = max(M.sleeping,rand(5,10))
src.loc = null
else
processing_objects.Remove(src)
/obj/effect/shadow_wight/Bump(var/atom/obstacle)
obstacle << "\red You feel a chill run down your spine!"
@@ -4,50 +4,64 @@
// 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
//for easy reference
/obj/var/datum/talking_atom/talking_atom
/obj/item/weapon/process()
if(!speaking_to_players)
/datum/talking_atom
var/list/heard_words = list()
var/last_talk_time = 0
var/atom/holder_atom
var/talk_interval = 50
var/talk_chance = 10
/datum/talking_atom/proc/init()
if(holder_atom)
processing_objects.Add(src)
/datum/talking_atom/proc/process()
if(!holder_atom)
processing_objects.Remove(src)
return
if(prob(10) && world.timeofday >= lastsaid && heard_words.len >= 1)
else if(heard_words.len >= 1 && world.time > last_talk_time + talk_interval && prob(talk_chance))
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 = text2list(msg, " ")
/datum/talking_atom/proc/catchMessage(var/msg, var/mob/source)
if(!holder_atom)
return
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])]"
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 = text2list(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)
var/list/options = list("[holder_atom] seems to be listening intently to [source]...",\
"[holder_atom] seems to be focussing on [source]...",\
"[holder_atom] seems to turn it's attention to [source]...")
holder_atom.loc.visible_message("\blue \icon[holder_atom] [pick(options)]")
if(prob(20))
spawn(2)
SaySomething(pick(seperate))
/*/obj/item/weapon/talkingcrystal/proc/debug()
//set src in view()
@@ -57,7 +71,9 @@
for(var/X in d)
world << "[X]"*/
/obj/item/weapon/proc/SaySomething(var/word = null)
/datum/talking_atom/proc/SaySomething(var/word = null)
if(!holder_atom)
return
var/msg
var/limit = rand(max(5,heard_words.len/2))+3
@@ -95,7 +111,7 @@
else
msg+="!"
var/list/listening = viewers(src)
var/list/listening = viewers(holder_atom)
for(var/mob/M in mob_list)
if (!M.client)
continue //skip monkeys and leavers
@@ -105,5 +121,5 @@
listening|=M
for(var/mob/M in listening)
M << "<b>[src]</b> reverberates, \blue\"[msg]\""
lastsaid = world.timeofday + rand(300,800)
M << "\icon[holder_atom] <b>[holder_atom]</b> reverberates, \blue\"[msg]\""
last_talk_time = world.time
@@ -0,0 +1,77 @@
/mob/living/simple_animal/hostile/samak
name = "samak"
desc = "A fast, armoured predator accustomed to hiding and ambushing in cold terrain."
faction = "samak"
icon_state = "samak"
icon_living = "samak"
icon_dead = "samak_dead"
icon = 'code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi'
move_to_delay = 2
maxHealth = 125
health = 125
speed = 2
melee_damage_lower = 5
melee_damage_upper = 15
attacktext = "mauls"
cold_damage_per_tick = 0
speak_chance = 5
speak = list("Hruuugh!","Hrunnph")
emote_see = list("paws the ground","shakes its mane","stomps")
emote_hear = list("snuffles")
/mob/living/simple_animal/hostile/diyaab
name = "diyaab"
desc = "A small pack animal. Although omnivorous, it will hunt meat on occasion."
faction = "diyaab"
icon_state = "diyaab"
icon_living = "diyaab"
icon_dead = "diyaab_dead"
icon = 'code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi'
move_to_delay = 1
maxHealth = 25
health = 25
speed = 1
melee_damage_lower = 1
melee_damage_upper = 8
attacktext = "gouges"
cold_damage_per_tick = 0
speak_chance = 5
speak = list("Awrr?","Aowrl!","Worrl")
emote_see = list("sniffs the air cautiously","looks around")
emote_hear = list("snuffles")
/mob/living/simple_animal/hostile/shantak
name = "shantak"
desc = "A piglike creature with a bright iridiscent mane that sparkles as though lit by an inner light. Don't be fooled by its beauty though."
faction = "shantak"
icon_state = "shantak"
icon_living = "shantak"
icon_dead = "shantak_dead"
icon = 'code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi'
move_to_delay = 1
maxHealth = 75
health = 75
speed = 1
melee_damage_lower = 3
melee_damage_upper = 12
attacktext = "gouges"
cold_damage_per_tick = 0
speak_chance = 5
speak = list("Shuhn","Shrunnph?","Shunpf")
emote_see = list("scratches the ground","shakes out it's mane","tinkles gently")
/mob/living/simple_animal/yithian
name = "yithian"
desc = "A friendly creature vaguely resembling an oversized snail without a shell."
icon_state = "yithian"
icon_living = "yithian"
icon_dead = "yithian_dead"
icon = 'code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi'
/mob/living/simple_animal/tindalos
name = "tindalos"
desc = "It looks like a large, flightless grasshopper."
icon_state = "tindalos"
icon_living = "tindalos"
icon_dead = "tindalos_dead"
icon = 'code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi'
@@ -0,0 +1,202 @@
/obj/item/seeds/telriis
name = "pack of telriis seeds"
desc = "These seeds grow into telriis grass. Not recommended for consumption by sentient species."
icon_state = "seed-alien1"
mypath = "/obj/item/seeds/telriis"
species = "telriis"
plantname = "Telriis grass"
productname = "/obj/item/weapon/telriis_clump"
lifespan = 50 //number of ticks
endurance = 50 //
maturation = 5 //ticks to full growth stage
production = 5 //ticks till ready to harvest
yield = 4 //number produced when harvest
potency = 5
plant_type = 1 //1=weed, 2=shroom, 0=normal
growthstages = 4
/obj/item/weapon/reagent_containers/food/snacks/grown/telriis_clump
name = "telriis grass"
desc = "A clump of telriis grass, not recommended for consumption by sentients."
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "telriisclump"
New(var/loc, var/potency)
..()
reagents.add_reagent("pwine", potency * 5)
reagents.add_reagent("nutriment", potency)
bitesize = 1+round(reagents.total_volume / 2, 1)
/obj/item/seeds/thaadra
name = "pack of thaa'dra seeds"
desc = "These seeds grow into Thaa'dra lichen. Likes the cold."
icon_state = "seed-alien3"
mypath = "/obj/item/seeds/thaadra"
species = "thaadra"
plantname = "Thaa'dra lichen"
productname = "/obj/item/weapon/reagent_containers/food/snacks/grown/thaadra"
lifespan = 20
endurance = 10
maturation = 5
production = 9
yield = 2
potency = 5
plant_type = 2
growthstages = 4
/obj/item/weapon/reagent_containers/food/snacks/grown/thaadrabloom
name = "thaa'dra bloom"
desc = "Looks chewy, might be good to eat."
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "thaadrabloom"
New(var/loc, var/potency)
..()
reagents.add_reagent("frostoil", potency * 1.5 + 5)
reagents.add_reagent("nutriment", potency)
bitesize = 1+round(reagents.total_volume / 2, 1)
/obj/item/seeds/jurlmah
name = "pack of jurl'mah seeds"
desc = "These seeds grow into jurl'mah reeds, which produce large syrupy pods."
icon_state = "seed-alien3"
mypath = "/obj/item/seeds/jurlmah"
species = "jurlmah"
plantname = "jurl'mah reeds"
productname = "/obj/item/weapon/reagent_containers/food/snacks/grown/jurlmah"
lifespan = 20
endurance = 12
maturation = 8
production = 9
yield = 3
potency = 10
growthstages = 5
/obj/item/weapon/reagent_containers/food/snacks/grown/jurlmah
name = "jurl'mah pod"
desc = "Bulbous and veiny, it appears to pulse slightly as you look at it."
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "jurlmahpod"
New(var/loc, var/potency)
..()
reagents.add_reagent("serotrotium", potency)
reagents.add_reagent("nutriment", potency)
bitesize = 1+round(reagents.total_volume / 2, 1)
/obj/item/seeds/amauri
name = "pack of amauri seeds"
desc = "Grows into a straight, dark plant with small round fruit."
icon_state = "seed-alien3"
mypath = "/obj/item/seeds/amauri"
species = "amauri"
plantname = "amauri plant"
productname = "/obj/item/weapon/reagent_containers/food/snacks/grown/amauri"
lifespan = 30
endurance = 10
maturation = 8
production = 9
yield = 4
potency = 10
growthstages = 3
/obj/item/weapon/reagent_containers/food/snacks/grown/amauri
name = "amauri fruit"
desc = "It is small, round and hard. Its skin is a thick dark purple."
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "amaurifruit"
New(var/loc, var/potency)
..()
reagents.add_reagent("zombiepowder", potency * 10)
reagents.add_reagent("condensedcapsaicin", potency * 5)
reagents.add_reagent("nutriment", potency)
bitesize = 1+round(reagents.total_volume / 2, 1)
/obj/item/seeds/gelthi
name = "pack of gelthi seeds"
desc = "Grows into a bright, wavy plant with many small fruits."
icon_state = "seed-alien2"
mypath = "/obj/item/seeds/gelthi"
species = "gelthi"
plantname = "gelthi plant"
productname = "/obj/item/weapon/reagent_containers/food/snacks/grown/gelthi"
lifespan = 20
endurance = 15
maturation = 6
production = 6
yield = 2
potency = 1
growthstages = 3
/obj/item/weapon/reagent_containers/food/snacks/grown/gelthi
name = "gelthi berries"
desc = "They feel fluffy and slightly warm to the touch."
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "gelthiberries"
New(var/loc, var/potency)
..()
//this may prove a little strong
reagents.add_reagent("stoxin", (potency * potency) / 5)
reagents.add_reagent("capsaicin", (potency * potency) / 5)
reagents.add_reagent("nutriment", potency)
bitesize = 1+round(reagents.total_volume / 2, 1)
/obj/item/seeds/vale
name = "pack of vale seeds"
desc = "The vale bush is often depicted in ancient heiroglyphs and is similar to cherry blossoms."
icon_state = "seed-alien2"
mypath = "/obj/item/seeds/vale"
species = "vale"
plantname = "vale bush"
productname = "/obj/item/weapon/reagent_containers/food/snacks/grown/vale"
lifespan = 25
endurance = 15
maturation = 8
production = 10
yield = 3
potency = 3
growthstages = 4
/obj/item/weapon/reagent_containers/food/snacks/grown/vale
name = "vale leaves"
desc = "Small, curly leaves covered in a soft pale fur."
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "valeleaves"
New(var/loc, var/potency)
..()
reagents.add_reagent("paracetamol", potency * 5)
reagents.add_reagent("dexalin", potency * 2)
reagents.add_reagent("nutriment", potency)
bitesize = 1+round(reagents.total_volume / 2, 1)
/obj/item/seeds/surik
name = "pack of surik seeds"
desc = "A spiky blue vine with large fruit resembling pig ears."
icon_state = "seed-alien3"
mypath = "/obj/item/seeds/surik"
species = "surik"
plantname = "surik vine"
productname = "/obj/item/weapon/reagent_containers/food/snacks/grown/surik"
lifespan = 30
endurance = 18
maturation = 7
production = 7
yield = 3
potency = 3
growthstages = 4
/obj/item/weapon/reagent_containers/food/snacks/grown/surik
name = "surik fruit"
desc = "Multiple layers of blue skin peeling away to reveal a spongey core, vaguely resembling an ear."
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "surikfruit"
New(var/loc, var/potency)
..()
reagents.add_reagent("impedrezene", potency * 3)
reagents.add_reagent("synaptizine", potency * 2)
reagents.add_reagent("nutriment", potency)
bitesize = 1+round(reagents.total_volume / 2, 1)
@@ -0,0 +1,319 @@
//gene sequence datum
datum/genesequence
var/spawned_type
var/spawned_type_text
var/list/full_genome_sequence = list()
#define SCANFOSSIL_RETVAL_WRONGTYPE 1
#define SCANFOSSIL_RETVAL_NOMOREGENESEQ 2
#define SCANFOSSIL_RETVAL_SUCCESS 4
/obj/machinery/computer/reconstitutor
name = "Flora reconstitution console"
icon = 'icons/obj/computer.dmi'
icon_state = "dna"
circuit = "/obj/item/weapon/circuitboard/reconstitutor"
req_access = list(access_heads) //Only used for record deletion right now.
var/obj/machinery/clonepod/pod1 = 1 //Linked cloning pod.
var/temp = ""
var/menu = 1 //Which menu screen to display
var/list/records = list()
var/datum/dna2/record/active_record = null
var/obj/item/weapon/disk/data/diskette = null //Mostly so the geneticist can steal everything.
var/loading = 0 // Nice loading text
var/list/undiscovered_genesequences = null
var/list/discovered_genesequences = list()
var/list/completed_genesequences = list()
var/list/undiscovered_genomes = list()
var/list/manually_placed_genomes = list()
var/list/discovered_genomes = list("! Clear !")
var/list/accepted_fossil_types = list(/obj/item/weapon/fossil/plant)
/obj/machinery/computer/reconstitutor/New()
if(!undiscovered_genesequences)
undiscovered_genesequences = master_controller.all_plant_genesequences.Copy()
..()
/obj/machinery/computer/reconstitutor/animal
name = "Fauna reconstitution console"
accepted_fossil_types = list(/obj/item/weapon/fossil/bone,/obj/item/weapon/fossil/shell,/obj/item/weapon/fossil/skull)
pod1 = null
circuit = "/obj/item/weapon/circuitboard/reconstitutor/animal"
/obj/machinery/computer/reconstitutor/animal/New()
undiscovered_genesequences = master_controller.all_animal_genesequences.Copy()
..()
/obj/machinery/computer/reconstitutor/attackby(obj/item/W, mob/user)
if(istype(W,/obj/item/weapon/fossil))
user.drop_item()
W.loc = src.loc
switch(scan_fossil(W))
if(1)
src.visible_message("\red \icon[src] [src] scans the fossil and rejects it.")
if(2)
visible_message("\red \icon[src] [src] can not extract any more genetic data from new fossils.")
if(4)
src.visible_message("\blue \icon[src] [user] inserts [W] into [src], the fossil is consumed as [src] extracts genetic data from it.")
del(W)
updateDialog()
else if (istype(W, /obj/item/weapon/storage))
var/obj/item/weapon/storage/S = W
S.hide_from(usr)
var/numaccepted = 0
var/numrejected = 0
var/full = 0
for(var/obj/item/weapon/fossil/F in S.contents)
switch(scan_fossil(F))
if(SCANFOSSIL_RETVAL_WRONGTYPE)
numrejected += 1
if(SCANFOSSIL_RETVAL_NOMOREGENESEQ)
full = 1
if(SCANFOSSIL_RETVAL_SUCCESS)
numaccepted += 1
S.remove_from_storage(F, src) //This will move the item to this item's contents
del(F)
updateDialog()
var/outmsg = "\blue You empty all the fossils from [S] into [src]."
if(numaccepted)
outmsg += " \blue[numaccepted] fossils were accepted and consumed as [src] extracts genetic data from them."
if(numrejected)
outmsg += " \red[numrejected] fossils were rejected."
if(full)
outmsg += " \red[src] can not extract any more genetic data from new fossils."
visible_message(outmsg)
else
..()
/obj/machinery/computer/reconstitutor/attack_hand(var/mob/user as mob)
src.add_fingerprint(user)
interact(user)
/obj/machinery/computer/reconstitutor/interact(mob/user)
if(stat & (NOPOWER|BROKEN) || get_dist(src, user) > 1)
user.unset_machine(src)
return
var/dat = "<B>Garland Corp genetic reconstitutor</B><BR>"
dat += "<HR>"
if(!pod1)
pod1 = locate() in orange(1, src)
if(!pod1)
dat += "<b><font color=red>Unable to locate cloning pod.</font></b><br>"
else if(istype(pod1))
dat += "<b><font color=green>Cloning pod connected.</font></b><br>"
dat += "<table border=1>"
dat += "<tr>"
dat += "<td><b>GENE1</b></td>"
dat += "<td><b>GENE2</b></td>"
dat += "<td><b>GENE3</b></td>"
dat += "<td><b>GENE4</b></td>"
dat += "<td><b>GENE5</b></td>"
dat += "<td><b>GENE6</b></td>"
dat += "<td><b>GENE7</b></td>"
dat += "<td></td>"
dat += "<td></td>"
dat += "</tr>"
//WIP gene sequences
for(var/sequence_num = 1, sequence_num <= discovered_genesequences.len, sequence_num += 1)
var/datum/genesequence/cur_genesequence = discovered_genesequences[sequence_num]
dat += "<tr>"
var/num_correct = 0
for(var/curindex = 1, curindex <= 7, curindex++)
var/bgcolour = "#ffffff"//white ffffff, red ff0000
//background colour hints at correct positioning
if(manually_placed_genomes[sequence_num][curindex])
//green background if slot is correctly filled
if(manually_placed_genomes[sequence_num][curindex] == cur_genesequence.full_genome_sequence[curindex])
bgcolour = "#008000"
num_correct += 1
if(num_correct == 7)
discovered_genesequences -= cur_genesequence
completed_genesequences += cur_genesequence
manually_placed_genomes[sequence_num] = new/list(7)
interact(user)
return
//yellow background if adjacent to correct slot
if(curindex > 1 && manually_placed_genomes[sequence_num][curindex] == cur_genesequence.full_genome_sequence[curindex - 1])
bgcolour = "#ffff00"
else if(curindex < 7 && manually_placed_genomes[sequence_num][curindex] == cur_genesequence.full_genome_sequence[curindex + 1])
bgcolour = "#ffff00"
var/this_genome_slot = manually_placed_genomes[sequence_num][curindex]
if(!this_genome_slot)
this_genome_slot = "- - - - -"
dat += "<td><a href='?src=\ref[src];sequence_num=[sequence_num];insertpos=[curindex]' style='background-color:[bgcolour]'>[this_genome_slot]</a></td>"
dat += "<td><a href='?src=\ref[src];reset=1;sequence_num=[sequence_num]'>Reset</a></td>"
//dat += "<td><a href='?src=\ref[src];clone=1;sequence_num=[sequence_num]'>Clone</a></td>"
dat += "</tr>"
//completed gene sequences
for(var/sequence_num = 1, sequence_num <= completed_genesequences.len, sequence_num += 1)
var/datum/genesequence/cur_genesequence = completed_genesequences[sequence_num]
dat += "<tr>"
for(var/curindex = 1, curindex <= 7, curindex++)
var/this_genome_slot = cur_genesequence.full_genome_sequence[curindex]
dat += "<td style='background-color:#008000'>[this_genome_slot]</td>"
dat += "<td><a href='?src=\ref[src];wipe=1;sequence_num=[sequence_num]'>Wipe</a></td>"
dat += "<td><a href='?src=\ref[src];clone=1;sequence_num=[sequence_num]'>Clone</a></td>"
dat += "</tr>"
dat += "</table>"
dat += "<br>"
dat += "<hr>"
dat += "<a href='?src=\ref[src];close=1'>Close</a>"
user << browse(dat, "window=reconstitutor;size=600x500")
user.set_machine(src)
onclose(user, "reconstitutor")
/obj/machinery/computer/reconstitutor/animal/Topic(href, href_list)
if(href_list["clone"])
var/sequence_num = text2num(href_list["sequence_num"])
var/datum/genesequence/cloned_genesequence = completed_genesequences[sequence_num]
if(pod1)
if(pod1.occupant)
visible_message("\red \icon[src] The cloning pod is currently occupied.")
else if(pod1.biomass < CLONE_BIOMASS)
visible_message("\red \icon[src] Not enough biomass in the cloning pod.")
else if(pod1.mess)
visible_message("\red \icon[src] Error: clonepod malfunction.")
else
visible_message("\blue \icon[src] [src] clones something from a reconstituted gene sequence!")
playsound(src.loc, 'sound/effects/screech.ogg', 50, 1, -3)
pod1.occupant = new cloned_genesequence.spawned_type(pod1)
pod1.locked = 1
pod1.icon_state = "pod_1"
//pod1.occupant.name = "[pod1.occupant.name] ([rand(0,999)])"
pod1.biomass -= CLONE_BIOMASS
else
usr << "\red \icon[src] Unable to locate cloning pod!"
else
..()
/obj/machinery/computer/reconstitutor/Topic(href, href_list)
if(href_list["insertpos"])
//world << "inserting gene for genesequence [href_list["insertgenome"]] at pos [text2num(href_list["insertpos"])]"
var/sequence_num = text2num(href_list["sequence_num"])
var/insertpos = text2num(href_list["insertpos"])
var/old_genome = manually_placed_genomes[sequence_num][insertpos]
discovered_genomes = sortList(discovered_genomes)
var/new_genome = input(usr, "Which genome do you want to insert here?") as null|anything in discovered_genomes
if(new_genome == "! Clear !")
manually_placed_genomes[sequence_num][insertpos] = null
else if(new_genome)
manually_placed_genomes[sequence_num][insertpos] = new_genome
discovered_genomes.Remove(new_genome)
if(old_genome)
discovered_genomes.Add(old_genome)
updateDialog()
else if(href_list["reset"])
var/sequence_num = text2num(href_list["sequence_num"])
for(var/curindex = 1, curindex <= 7, curindex++)
var/old_genome = manually_placed_genomes[sequence_num][curindex]
manually_placed_genomes[sequence_num][curindex] = null
if(old_genome)
discovered_genomes.Add(old_genome)
updateDialog()
else if(href_list["wipe"])
var/sequence_num = text2num(href_list["sequence_num"])
var/datum/genesequence/wiped_genesequence = completed_genesequences[sequence_num]
completed_genesequences.Remove(wiped_genesequence)
discovered_genesequences.Add(wiped_genesequence)
discovered_genomes.Add(wiped_genesequence.full_genome_sequence)
discovered_genomes = sortList(discovered_genomes)
updateDialog()
else if(href_list["clone"])
var/sequence_num = text2num(href_list["sequence_num"])
var/datum/genesequence/cloned_genesequence = completed_genesequences[sequence_num]
visible_message("\blue \icon[src] [src] clones a packet of seeds from a reconstituted gene sequence!")
playsound(src.loc, 'sound/effects/screech.ogg', 50, 1, -3)
new cloned_genesequence.spawned_type(src.loc)
else if(href_list["close"])
usr.unset_machine(src)
usr << browse(null, "window=reconstitutor")
else
..()
/obj/machinery/computer/reconstitutor/proc/scan_fossil(var/obj/item/weapon/fossil/scan_fossil)
//see whether we accept these kind of fossils
if(accepted_fossil_types.len && !accepted_fossil_types.Find(scan_fossil.type))
return SCANFOSSIL_RETVAL_WRONGTYPE
//see whether we are going to discover a new sequence, new genome for existing sequence or nothing
var/new_genome_prob = discovered_genesequences.len * 50
if( (new_genome_prob >= 100 || prob(new_genome_prob)) && undiscovered_genomes.len)
//create a new genome for an existing gene sequence
var/newly_discovered_genome = pick(undiscovered_genomes)
undiscovered_genomes -= newly_discovered_genome
discovered_genomes.Add(newly_discovered_genome)
//chance to discover a second genome
if(prob(75))
newly_discovered_genome = pick(undiscovered_genomes)
undiscovered_genomes -= newly_discovered_genome
discovered_genomes.Add(newly_discovered_genome)
//chance to discover a third genome
if(prob(50))
newly_discovered_genome = pick(undiscovered_genomes)
undiscovered_genomes -= newly_discovered_genome
discovered_genomes.Add(newly_discovered_genome)
else if(undiscovered_genesequences.len)
//discover new gene sequence
var/datum/genesequence/newly_discovered_genesequence = pick(undiscovered_genesequences)
undiscovered_genesequences -= newly_discovered_genesequence
discovered_genesequences += newly_discovered_genesequence
//add genomes for new gene sequence to pool of discoverable genomes
undiscovered_genomes.Add(newly_discovered_genesequence.full_genome_sequence)
manually_placed_genomes.Add(null)
manually_placed_genomes[manually_placed_genomes.len] = new/list(7)
else
//there's no point scanning any more fossils, we've already discovered everything
return SCANFOSSIL_RETVAL_NOMOREGENESEQ
return SCANFOSSIL_RETVAL_SUCCESS
#undef SCANFOSSIL_RETVAL_WRONGTYPE
#undef SCANFOSSIL_RETVAL_NOMOREGENESEQ
#undef SCANFOSSIL_RETVAL_SUCCESS
/obj/item/weapon/circuitboard/reconstitutor
name = "Circuit board (Flora Reconstitution Console)"
build_path = "/obj/machinery/computer/reconstitutor"
origin_tech = "programming=2;biotech=4;materials=6"
frame_desc = "Requires 2 Advanced Scanning Module, 1 Nano Manipulator, 1 Matter Bin and 1 Advanced Capacitor."
req_components = list(
"/obj/item/weapon/stock_parts/scanning_module/adv" = 2,
"/obj/item/weapon/stock_parts/manipulator/nano" = 1,
"/obj/item/weapon/stock_parts/matter_bin" = 1,
"/obj/item/weapon/stock_parts/capacitor/adv" = 1)
/obj/item/weapon/circuitboard/reconstitutor/animal
name = "Circuit board (Fauna Reconstitution Console)"
build_path = "/obj/machinery/computer/reconstitutor/animal"
origin_tech = "programming=2;biotech=4;materials=6"
frame_desc = "Requires 2 Advanced Scanning Module, 1 Nano Manipulator, 1 Matter Bin and 1 Advanced Capacitor."
req_components = list(
"/obj/item/weapon/stock_parts/scanning_module/adv" = 2,
"/obj/item/weapon/stock_parts/manipulator/nano" = 1,
"/obj/item/weapon/stock_parts/matter_bin" = 1,
"/obj/item/weapon/stock_parts/capacitor/adv" = 1)
@@ -12,6 +12,7 @@
var/obj/item/weapon/anobattery/inserted_battery
var/obj/machinery/artifact/cur_artifact
var/obj/machinery/artifact_scanpad/owned_scanner = null
var/last_process = 0
/obj/machinery/artifact_harvester/New()
..()
@@ -47,14 +48,14 @@
if(owned_scanner)
if(harvesting)
if(harvesting > 0)
dat += "Please wait. Harvesting in progress ([(inserted_battery.stored_charge/inserted_battery.capacity)*100]%).<br>"
dat += "Please wait. Harvesting in progress ([round((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 += "Please wait. Energy dump in progress ([round((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 += "<b>Energy signature ID:</b>[inserted_battery.battery_effect ? (inserted_battery.battery_effect.artifact_id == "" ? "???" : "[inserted_battery.battery_effect.artifact_id]") : "NA"]<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>"
@@ -74,8 +75,9 @@
return
if(harvesting > 0)
//gain a bit of charge
inserted_battery.stored_charge += 0.5
//charge at 33% consumption rate
inserted_battery.stored_charge += (world.time - last_process) / 3
last_process = world.time
//check if we've finished
if(inserted_battery.stored_charge >= inserted_battery.capacity)
@@ -88,14 +90,14 @@
else if(harvesting < 0)
//dump some charge
inserted_battery.stored_charge -= 2
inserted_battery.stored_charge -= (world.time - last_process) / 3
//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)
if(inserted_battery.battery_effect.effect == EFFECT_TOUCH)
var/list/nearby = viewers(1, src)
for(var/mob/M in nearby)
if(M.machine == src)
@@ -114,79 +116,115 @@
/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++
if(!inserted_battery)
src.visible_message("<b>[src]</b> states, \"Cannot harvest. No battery inserted.\"")
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
else if(inserted_battery.stored_charge >= inserted_battery.capacity)
src.visible_message("<b>[src]</b> states, \"Cannot harvest. battery is full.\"")
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)
else
//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)
//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++
//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.\""
if(articount <= 0)
var/message = "<b>[src]</b> states, \"Cannot harvest. No noteworthy energy signature isolated.\""
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)
else if(analysed && analysed.being_used)
src.visible_message("<b>[src]</b> states, \"Cannot harvest. Source already being harvested.\"")
else
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(articount > 1 || mundane)
var/message = "<b>[src]</b> states, \"Cannot harvest. Too many artifacts on the pad.\""
src.visible_message(message)
else
cur_artifact = analysed
//if both effects are active, we can't harvest either
if(cur_artifact.my_effect.activated && cur_artifact.secondary_effect.activated)
src.visible_message("<b>[src]</b> states, \"Cannot harvest. Source is emitting conflicting energy signatures.\"")
else if(!cur_artifact.my_effect.activated && !cur_artifact.secondary_effect.activated)
src.visible_message("<b>[src]</b> states, \"Cannot harvest. No energy emitting from source.\"")
else
//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)
//
var/datum/artifact_effect/source_effect
//if we already have charge in the battery, we can only recharge it from the source artifact
if(inserted_battery.stored_charge > 0)
var/battery_matches_primary_id = 0
if(inserted_battery.battery_effect && inserted_battery.battery_effect.artifact_id == cur_artifact.my_effect.artifact_id)
battery_matches_primary_id = 1
if(battery_matches_primary_id && cur_artifact.my_effect.activated)
//we're good to recharge the primary effect!
source_effect = cur_artifact.my_effect
var/battery_matches_secondary_id = 0
if(inserted_battery.battery_effect && inserted_battery.battery_effect.artifact_id == cur_artifact.secondary_effect.artifact_id)
battery_matches_secondary_id = 1
if(battery_matches_secondary_id && cur_artifact.secondary_effect.activated)
//we're good to recharge the secondary effect!
source_effect = cur_artifact.secondary_effect
if(!source_effect)
src.visible_message("<b>[src]</b> states, \"Cannot harvest. Battery is charged with a different energy signature.\"")
else
//we're good to charge either
if(cur_artifact.my_effect.activated)
//charge the primary effect
source_effect = cur_artifact.my_effect
else if(cur_artifact.secondary_effect.activated)
//charge the secondary effect
source_effect = cur_artifact.secondary_effect
if(source_effect)
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 energy harvesting.\""
src.visible_message(message)
last_process = world.time
//duplicate the artifact's effect datum
if(!inserted_battery.battery_effect)
var/effecttype = source_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] = source_effect.vars[varname]
//copy the new datum into the battery
inserted_battery.battery_effect = E
inserted_battery.stored_charge = 0
if (href_list["stopharvest"])
if(harvesting)
@@ -195,7 +233,7 @@
harvesting = 0
cur_artifact.anchored = 0
cur_artifact.being_used = 0
src.visible_message("<b>[name]</b> states, \"Activity interrupted.\"")
src.visible_message("<b>[name]</b> states, \"Energy harvesting interrupted.\"")
icon_state = "incubator"
if (href_list["ejectbattery"])
@@ -207,7 +245,8 @@
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)
inserted_battery.battery_effect.ToggleActivate(1)
last_process = world.time
harvesting = -1
use_power = 2
icon_state = "incubator_on"
@@ -285,10 +285,8 @@
data = " - Mundane object (archaic xenos origins)<br>"
var/obj/item/weapon/archaeological_find/A = scanned_item
if(A.speaking_to_players)
data = " - Exhibits properties consistent with sonic reproduction.<br>"
if(A.listening_to_players)
data = " - Exhibits properties similar to audio capture technology.<br>"
if(A.talking_atom)
data = " - Exhibits properties consistent with sonic reproduction and audio capture technologies.<br>"
var/anom_found = 0
if(G)
@@ -0,0 +1,145 @@
/datum/controller/game_controller
var/list/all_animal_genesequences = list()
var/list/all_plant_genesequences = list()
var/list/genome_prefixes = null
var/list/artifact_spawning_turfs = list()
var/list/digsite_spawning_turfs = list()
var/list/spawn_types_animal = list("/mob/living/carbon/slime",\
"/mob/living/simple_animal/hostile/alien",\
"/mob/living/simple_animal/hostile/alien/drone",\
"/mob/living/simple_animal/hostile/alien/sentinel",\
"/mob/living/simple_animal/hostile/giant_spider",\
"/mob/living/simple_animal/hostile/giant_spider/hunter",\
"/mob/living/simple_animal/hostile/giant_spider/nurse",\
"/mob/living/simple_animal/hostile/creature",\
"/mob/living/simple_animal/hostile/samak",\
"/mob/living/simple_animal/hostile/diyaab",\
"/mob/living/simple_animal/hostile/shantak",\
"/mob/living/simple_animal/tindalos",\
"/mob/living/simple_animal/yithian")
var/list/spawn_types_plant = list("/obj/item/seeds/walkingmushroommycelium",\
"/obj/item/seeds/killertomatoseed",\
"/obj/item/seeds/shandseed",
"/obj/item/seeds/mtearseed",
"/obj/item/seeds/thaadra",\
"/obj/item/seeds/telriis",\
"/obj/item/seeds/jurlmah",\
"/obj/item/seeds/amauri",\
"/obj/item/seeds/gelthi",\
"/obj/item/seeds/vale",\
"/obj/item/seeds/surik")
#define XENOARCH_SPAWN_CHANCE 0.5
#define DIGSITESIZE_LOWER 4
#define DIGSITESIZE_UPPER 12
#define ARTIFACTSPAWNNUM_LOWER 6
#define ARTIFACTSPAWNNUM_UPPER 12
datum/controller/game_controller/proc/SetupXenoarch()
//create digsites
for(var/turf/simulated/mineral/M in block(locate(1,1,1), locate(world.maxx, world.maxy, world.maxz)))
if(isnull(M.geologic_data))
M.geologic_data = new/datum/geosample(M)
if(!prob(XENOARCH_SPAWN_CHANCE))
continue
digsite_spawning_turfs.Add(M)
var/digsite = get_random_digsite_type()
var/target_digsite_size = rand(DIGSITESIZE_LOWER, DIGSITESIZE_UPPER)
var/list/processed_turfs = list()
var/list/turfs_to_process = list(M)
while(turfs_to_process.len)
var/turf/simulated/mineral/archeo_turf = pop(turfs_to_process)
if(target_digsite_size > 1)
var/list/viable_adjacent_turfs = orange(1, archeo_turf)
for(var/turf/simulated/mineral/T in orange(1, archeo_turf))
if(T.finds)
continue
if(T in processed_turfs)
continue
viable_adjacent_turfs.Add(T)
for(var/turf/simulated/mineral/T in viable_adjacent_turfs)
if(prob(target_digsite_size/viable_adjacent_turfs.len))
turfs_to_process.Add(T)
target_digsite_size -= 1
if(target_digsite_size <= 0)
break
processed_turfs.Add(archeo_turf)
if(isnull(archeo_turf.finds))
archeo_turf.finds = list()
if(prob(50))
archeo_turf.finds.Add(new /datum/find(digsite, rand(5,95)))
else if(prob(75))
archeo_turf.finds.Add(new /datum/find(digsite, rand(5,45)))
archeo_turf.finds.Add(new /datum/find(digsite, rand(55,95)))
else
archeo_turf.finds.Add(new /datum/find(digsite, rand(5,30)))
archeo_turf.finds.Add(new /datum/find(digsite, rand(35,75)))
archeo_turf.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 = archeo_turf.finds[1]
if(F.excavation_required <= F.view_range)
archeo_turf.archaeo_overlay = "overlay_archaeo[rand(1,3)]"
archeo_turf.overlays += archeo_turf.archaeo_overlay
//have a chance for an artifact to spawn here, but not in animal or plant digsites
if(isnull(M.artifact_find) && digsite != 1 && digsite != 2)
artifact_spawning_turfs.Add(archeo_turf)
//create artifact machinery
var/num_artifacts_spawn = rand(ARTIFACTSPAWNNUM_LOWER, ARTIFACTSPAWNNUM_UPPER)
while(artifact_spawning_turfs.len > num_artifacts_spawn)
pick_n_take(artifact_spawning_turfs)
var/list/artifacts_spawnturf_temp = artifact_spawning_turfs.Copy()
while(artifacts_spawnturf_temp.len > 0)
var/turf/simulated/mineral/artifact_turf = pop(artifacts_spawnturf_temp)
artifact_turf.artifact_find = new()
//make sure we have some prefixes for the gene sequences
if(!genome_prefixes)
genome_prefixes = alphabet_uppercase.Copy()
if(!genome_prefixes.len)
del genome_prefixes
genome_prefixes = alphabet_uppercase.Copy()
//create animal gene sequences
while(spawn_types_animal.len && genome_prefixes.len)
var/datum/genesequence/new_sequence = new/datum/genesequence()
new_sequence.spawned_type_text = pick(spawn_types_animal)
new_sequence.spawned_type = text2path(new_sequence.spawned_type_text)
spawn_types_animal -= new_sequence.spawned_type_text
var/prefixletter = pick(genome_prefixes)
genome_prefixes -= prefixletter
while(new_sequence.full_genome_sequence.len < 7)
new_sequence.full_genome_sequence.Add("[prefixletter][pick(alphabet_uppercase)][pick(alphabet_uppercase)][pick(1,2,3,4,5,6,7,8,9,0)][pick(1,2,3,4,5,6,7,8,9,0)]")
all_animal_genesequences.Add(new_sequence)
//create plant gene sequences
while(spawn_types_plant.len && genome_prefixes.len)
var/datum/genesequence/new_sequence = new/datum/genesequence()
new_sequence.spawned_type = pick(spawn_types_plant)
spawn_types_plant -= new_sequence.spawned_type_text
var/prefixletter = pick(genome_prefixes)
genome_prefixes -= prefixletter
while(new_sequence.full_genome_sequence.len < 7)
new_sequence.full_genome_sequence.Add("[prefixletter][pick(1,2,3,4,5,6,7,8,9,0)][pick(1,2,3,4,5,6,7,8,9,0)][pick(alphabet_uppercase)][pick(alphabet_uppercase)]")
all_plant_genesequences.Add(new_sequence)
#undef XENOARCH_SPAWN_CHANCE
#undef DIGSITESIZE_LOWER
#undef DIGSITESIZE_UPPER
#undef ARTIFACTSPAWNNUM_LOWER
#undef ARTIFACTSPAWNNUM_UPPER
+1 -49
View File
@@ -1,52 +1,3 @@
#define XENOARCH_SPAWN_CHANCE 0.5
#define XENOARCH_SPREAD_CHANCE 15
#define ARTIFACT_SPAWN_CHANCE 20
proc/SetupXenoarch()
for(var/turf/simulated/mineral/M in block(locate(1,1,1), locate(world.maxx, world.maxy, world.maxz)))
if(!M.geologic_data)
M.geologic_data = new/datum/geosample(M)
if(!prob(XENOARCH_SPAWN_CHANCE))
continue
var/digsite = get_random_digsite_type()
var/list/processed_turfs = list()
var/list/turfs_to_process = list(M)
for(var/turf/simulated/mineral/archeo_turf in turfs_to_process)
for(var/turf/simulated/mineral/T in orange(1, archeo_turf))
if(T.finds)
continue
if(T in processed_turfs)
continue
if(prob(XENOARCH_SPREAD_CHANCE))
turfs_to_process.Add(T)
processed_turfs.Add(archeo_turf)
if(!archeo_turf.finds)
archeo_turf.finds = list()
if(prob(50))
archeo_turf.finds.Add(new /datum/find(digsite, rand(5,95)))
else if(prob(75))
archeo_turf.finds.Add(new /datum/find(digsite, rand(5,45)))
archeo_turf.finds.Add(new /datum/find(digsite, rand(55,95)))
else
archeo_turf.finds.Add(new /datum/find(digsite, rand(5,30)))
archeo_turf.finds.Add(new /datum/find(digsite, rand(35,75)))
archeo_turf.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 = archeo_turf.finds[1]
if(F.excavation_required <= F.view_range)
archeo_turf.archaeo_overlay = "overlay_archaeo[rand(1,3)]"
archeo_turf.overlays += archeo_turf.archaeo_overlay
//dont create artifact machinery in animal or plant digsites, or if we already have one
if(!M.artifact_find && digsite != 1 && digsite != 2 && prob(ARTIFACT_SPAWN_CHANCE))
M.artifact_find = new()
artifact_spawn.Add(src)
//---- Noticeboard
@@ -152,6 +103,7 @@ proc/SetupXenoarch()
new /obj/item/weapon/pickaxe(src)
new /obj/item/device/measuring_tape(src)
new /obj/item/weapon/pickaxe/hand(src)
new /obj/item/weapon/storage/bag/fossils(src)
return
//---- Isolation room air alarms
@@ -4,7 +4,7 @@
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "anobattery0"
var/datum/artifact_effect/battery_effect
var/capacity = 200
var/capacity = 300
var/stored_charge = 0
var/effect_id = ""
@@ -20,13 +20,15 @@
name = "Anomaly power utilizer"
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "anodev"
var/cooldown = 0
var/activated = 0
var/timing = 0
var/time = 50
var/archived_time = 50
var/duration = 0
var/interval = 0
var/time_end = 0
var/last_activation = 0
var/last_process = 0
var/obj/item/weapon/anobattery/inserted_battery
var/turf/archived_loc
var/energy_consumed_on_touch = 100
/obj/item/weapon/anodevice/New()
..()
@@ -47,54 +49,35 @@
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>"
if(activated)
dat += "Device active.<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>"
dat += "<b>Charge:</b> [inserted_battery.stored_charge] / [inserted_battery.capacity]<BR>"
dat += "<b>Time left activated:</b> [round(max((time_end - last_process) / 10, 0))]<BR>"
if(activated)
dat += "<a href='?src=\ref[src];shutdown=1'>Shutdown</a><br>"
else
dat += "<a href='?src=\ref[src];shutdown=1'>Shutdown emission</a><br>"
dat += "<br>"
dat += "<A href='?src=\ref[src];startup=1'>Start</a><BR>"
dat += "<BR>"
dat += "<b>Activate duration (sec):</b> <A href='?src=\ref[src];changetime=-100;duration=1'>--</a> <A href='?src=\ref[src];changetime=-10;duration=1'>-</a> [duration/10] <A href='?src=\ref[src];changetime=10;duration=1'>+</a> <A href='?src=\ref[src];changetime=100;duration=1'>++</a><BR>"
dat += "<b>Activate interval (sec):</b> <A href='?src=\ref[src];changetime=-100;interval=1'>--</a> <A href='?src=\ref[src];changetime=-10;interval=1'>-</a> [interval/10] <A href='?src=\ref[src];changetime=10;interval=1'>+</a> <A href='?src=\ref[src];changetime=100;interval=1'>++</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>"
dat += "<a href='?src=\ref[src];refresh=1'>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(activated)
if(inserted_battery && inserted_battery.battery_effect)
//make sure the effect is active
if(!inserted_battery.battery_effect.activated)
@@ -106,71 +89,83 @@
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)
var/mob/holder
if(ismob(src.loc))
holder = src.loc
//handle charge
inserted_battery.stored_charge -= 1
if(inserted_battery.stored_charge <= 0)
shutdown_emission()
if(world.time - last_activation > interval)
if(inserted_battery.battery_effect.effect == EFFECT_TOUCH)
if(interval > 0)
//apply the touch effect to the holder
if(holder)
holder << "the \icon[src] [src] held by [holder] shudders in your grasp."
else
src.loc.visible_message("the \icon[src] [src] shudders.")
inserted_battery.battery_effect.DoEffectTouch(holder)
//handle timed mode
if(timing)
time -= 1
if(time <= 0)
shutdown_emission()
//consume power
inserted_battery.stored_charge -= energy_consumed_on_touch
else
//consume power equal to time passed
inserted_battery.stored_charge -= world.time - last_process
else if(inserted_battery.battery_effect.effect == EFFECT_PULSE)
inserted_battery.battery_effect.chargelevel = inserted_battery.battery_effect.chargelevelmax
//consume power relative to the time the artifact takes to charge and the effect range
inserted_battery.stored_charge -= inserted_battery.battery_effect.effectrange * inserted_battery.battery_effect.effectrange * inserted_battery.battery_effect.chargelevelmax
else
//consume power equal to time passed
inserted_battery.stored_charge -= world.time - last_process
last_activation = world.time
//process the effect
inserted_battery.battery_effect.process()
//work out if we need to shutdown
if(inserted_battery.stored_charge <= 0)
src.loc.visible_message("\blue \icon[src] [src] buzzes.", "\blue \icon[src] You hear something buzz.")
shutdown_emission()
else if(world.time > time_end)
src.loc.visible_message("\blue \icon[src] [src] chimes.", "\blue \icon[src] You hear something chime.")
shutdown_emission()
else
shutdown()
src.visible_message("\blue \icon[src] [src] buzzes.", "\blue \icon[src] You hear something buzz.")
shutdown_emission()
last_process = world.time
/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
var/timedif = text2num(href_list["changetime"])
if(href_list["duration"])
duration += timedif
//max 30 sec duration
duration = min(max(duration, 0), 300)
if(activated)
time_end += timedif
else if(href_list["interval"])
interval += timedif
//max 10 sec interval
interval = min(max(interval, 0), 100)
if(href_list["startup"])
activated = 1
src.visible_message("\blue \icon[src] [src] whirrs.", "\icon[src]\blue You hear something whirr.")
if(!inserted_battery.battery_effect.activated)
inserted_battery.battery_effect.ToggleActivate(1)
time_end = world.time + duration
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)
@@ -178,10 +173,10 @@
UpdateSprite()
if(href_list["close"])
usr << browse(null, "window=anodevice")
usr.unset_machine(src)
else if(ismob(src.loc))
var/mob/M = src.loc
src.interact(M)
..()
updateDialog()
/obj/item/weapon/anodevice/proc/UpdateSprite()
if(!inserted_battery)
@@ -194,3 +189,23 @@
/obj/item/weapon/anodevice/Del()
processing_objects.Remove(src)
..()
/obj/item/weapon/anodevice/attack(mob/living/M as mob, mob/living/user as mob, def_zone)
if (!istype(M))
return
if(activated && inserted_battery.battery_effect.effect == EFFECT_TOUCH && !isnull(inserted_battery))
inserted_battery.battery_effect.DoEffectTouch(M)
inserted_battery.stored_charge -= energy_consumed_on_touch
user.visible_message("\blue [user] taps [M] with [src], and it shudders on contact.")
else
user.visible_message("\blue [user] taps [M] with [src], but nothing happens.")
//admin logging
user.lastattacked = M
M.lastattacker = user
if(inserted_battery.battery_effect)
user.attack_log += "\[[time_stamp()]\]<font color='red'> Tapped [M.name] ([M.ckey]) with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])</font>"
M.attack_log += "\[[time_stamp()]\]<font color='orange'> Tapped by [user.name] ([user.ckey]) with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])</font>"
msg_admin_attack("[key_name(user)] tapped [key_name(M)] with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])" )
@@ -22,3 +22,15 @@
w_class = 2
//todo: dig site tape
/obj/item/weapon/storage/bag/fossils
name = "Fossil Satchel"
desc = "Transports delicate fossils in suspension so they don't break during transit."
icon = 'icons/obj/mining.dmi'
icon_state = "satchel"
slot_flags = SLOT_BELT | SLOT_POCKET
w_class = 3
storage_slots = 50
max_combined_w_class = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * ore.w_class
max_w_class = 3
can_hold = list("/obj/item/weapon/fossil")