mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-25 01:22:13 +00:00
Merge remote-tracking branch 'upstream/dev' into emergency-shuttle
Conflicts: code/setup.dm
This commit is contained in:
@@ -114,7 +114,7 @@
|
||||
|
||||
//play the recieving admin the adminhelp sound (if they have them enabled)
|
||||
//non-admins shouldn't be able to disable this
|
||||
if(C.prefs.toggles & SOUND_ADMINHELP)
|
||||
if(C.prefs && C.prefs.toggles & SOUND_ADMINHELP)
|
||||
C << 'sound/effects/adminhelp.ogg'
|
||||
|
||||
log_admin("PM: [key_name(src)]->[key_name(C)]: [msg]")
|
||||
|
||||
@@ -220,7 +220,7 @@ BLIND // can't see anything
|
||||
permeability_coefficient = 0.02
|
||||
flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE | THICKMATERIAL
|
||||
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen)
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/device/suit_cooling_unit)
|
||||
slowdown = 3
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50)
|
||||
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins."
|
||||
icon_state = "s-ninja"
|
||||
item_state = "s-ninja_suit"
|
||||
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/weapon/cell)
|
||||
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/cell)
|
||||
slowdown = 0
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
siemens_coefficient = 0.2
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
item_state = "eng_hardsuit"
|
||||
slowdown = 1
|
||||
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 80)
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd)
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd)
|
||||
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
|
||||
@@ -359,7 +359,7 @@
|
||||
slowdown = 1
|
||||
w_class = 3
|
||||
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 60)
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs)
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs)
|
||||
siemens_coefficient = 0.6
|
||||
species_restricted = list("exclude","Unathi","Tajaran","Skrell","Vox")
|
||||
|
||||
@@ -402,7 +402,7 @@
|
||||
name = "medical hardsuit"
|
||||
desc = "A special suit that protects against hazardous, low pressure environments. Has minor radiation shielding."
|
||||
item_state = "medical_hardsuit"
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical)
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical)
|
||||
armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 50)
|
||||
|
||||
//Security
|
||||
@@ -421,7 +421,7 @@
|
||||
desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor."
|
||||
item_state = "sec_hardsuit"
|
||||
armor = list(melee = 60, bullet = 10, laser = 30, energy = 5, bomb = 45, bio = 100, rad = 10)
|
||||
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/melee/baton)
|
||||
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton)
|
||||
siemens_coefficient = 0.7
|
||||
|
||||
|
||||
|
||||
@@ -4,12 +4,15 @@
|
||||
//for multiple items just add mutliple entries, unless i change it to be a listlistlist
|
||||
//yes, it has to be an item, you can't pick up nonitems
|
||||
|
||||
/proc/EquipCustomItems(mob/living/carbon/human/M)
|
||||
// load lines
|
||||
var/file = file2text("config/custom_items.txt")
|
||||
var/lines = text2list(file, "\n")
|
||||
/var/list/custom_items = list()
|
||||
|
||||
for(var/line in lines)
|
||||
/hook/startup/proc/loadCustomItems()
|
||||
var/custom_items_file = file2text("config/custom_items.txt")
|
||||
custom_items = text2list(custom_items_file, "\n")
|
||||
return 1
|
||||
|
||||
/proc/EquipCustomItems(mob/living/carbon/human/M)
|
||||
for(var/line in custom_items)
|
||||
// split & clean up
|
||||
var/list/Entry = text2list(line, ":")
|
||||
for(var/i = 1 to Entry.len)
|
||||
@@ -24,6 +27,8 @@
|
||||
var/ok = 0 // 1 if the item was placed successfully
|
||||
P = trim(P)
|
||||
var/path = text2path(P)
|
||||
if(!path) continue
|
||||
|
||||
var/obj/item/Item = new path()
|
||||
if(istype(Item,/obj/item/weapon/card/id))
|
||||
//id card needs to replace the original ID
|
||||
|
||||
@@ -21,9 +21,25 @@ datum/event/organ_failure/start()
|
||||
while(severity > 0 && candidates.len)
|
||||
var/mob/living/carbon/human/C = candidates[1]
|
||||
|
||||
// Bruise one of their organs
|
||||
var/O = pick(C.internal_organs)
|
||||
var/datum/organ/internal/I = C.internal_organs[O]
|
||||
I.damage = I.min_bruised_damage
|
||||
candidates.Remove(C)
|
||||
severity--
|
||||
var/acute = prob(15)
|
||||
if (prob(75))
|
||||
//internal organ infection
|
||||
var/O = pick(C.internal_organs)
|
||||
var/datum/organ/internal/I = C.internal_organs[O]
|
||||
|
||||
if (acute)
|
||||
I.germ_level = max(INFECTION_LEVEL_TWO, I.germ_level)
|
||||
else
|
||||
I.germ_level = max(rand(INFECTION_LEVEL_ONE,INFECTION_LEVEL_ONE*2), I.germ_level)
|
||||
else
|
||||
//external organ infection
|
||||
var/datum/organ/external/O = pick(C.organs)
|
||||
|
||||
if (acute)
|
||||
O.germ_level = max(INFECTION_LEVEL_TWO, O.germ_level)
|
||||
else
|
||||
O.germ_level = max(rand(INFECTION_LEVEL_ONE,INFECTION_LEVEL_ONE*2), O.germ_level)
|
||||
|
||||
C.bad_external_organs |= O
|
||||
|
||||
severity--
|
||||
|
||||
@@ -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'
|
||||
@@ -39,19 +36,19 @@ var/list/artifact_spawn = list() // Runtime fix for geometry loading before cont
|
||||
if((istype(get_step(src, NORTH), /turf/simulated/floor)) || (istype(get_step(src, NORTH), /turf/space)) || (istype(get_step(src, NORTH), /turf/simulated/shuttle/floor)))
|
||||
T = get_step(src, NORTH)
|
||||
if (T)
|
||||
T.overlays += image('icons/turf/walls.dmi', "rock_side_s")
|
||||
T.overlays += image('icons/turf/walls.dmi', "rock_side_s", layer=2)
|
||||
if((istype(get_step(src, SOUTH), /turf/simulated/floor)) || (istype(get_step(src, SOUTH), /turf/space)) || (istype(get_step(src, SOUTH), /turf/simulated/shuttle/floor)))
|
||||
T = get_step(src, SOUTH)
|
||||
if (T)
|
||||
T.overlays += image('icons/turf/walls.dmi', "rock_side_n", layer=6)
|
||||
T.overlays += image('icons/turf/walls.dmi', "rock_side_n", layer=2)
|
||||
if((istype(get_step(src, EAST), /turf/simulated/floor)) || (istype(get_step(src, EAST), /turf/space)) || (istype(get_step(src, EAST), /turf/simulated/shuttle/floor)))
|
||||
T = get_step(src, EAST)
|
||||
if (T)
|
||||
T.overlays += image('icons/turf/walls.dmi', "rock_side_w", layer=6)
|
||||
T.overlays += image('icons/turf/walls.dmi', "rock_side_w", layer=2)
|
||||
if((istype(get_step(src, WEST), /turf/simulated/floor)) || (istype(get_step(src, WEST), /turf/space)) || (istype(get_step(src, WEST), /turf/simulated/shuttle/floor)))
|
||||
T = get_step(src, WEST)
|
||||
if (T)
|
||||
T.overlays += image('icons/turf/walls.dmi', "rock_side_e", layer=6)
|
||||
T.overlays += image('icons/turf/walls.dmi', "rock_side_e", layer=2)
|
||||
|
||||
|
||||
ex_act(severity)
|
||||
@@ -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)
|
||||
|
||||
@@ -72,7 +72,7 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
Die()
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
/obj/item/clothing/mask/facehugger/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature > 300)
|
||||
Die()
|
||||
return
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/mob/living/carbon/Life()
|
||||
..()
|
||||
|
||||
// Increase germ_level regularly
|
||||
if(germ_level < GERM_LEVEL_AMBIENT && prob(80)) //if you're just standing there, you shouldn't get more germs beyond an ambient level
|
||||
germ_level++
|
||||
|
||||
/mob/living/carbon/Move(NewLoc, direct)
|
||||
. = ..()
|
||||
if(.)
|
||||
@@ -7,6 +14,10 @@
|
||||
src.nutrition -= HUNGER_FACTOR/10
|
||||
if((FAT in src.mutations) && src.m_intent == "run" && src.bodytemperature <= 360)
|
||||
src.bodytemperature += 2
|
||||
|
||||
// Moving around increases germ_level faster
|
||||
if(germ_level < GERM_LEVEL_MOVE_CAP && prob(8))
|
||||
germ_level++
|
||||
|
||||
/mob/living/carbon/relaymove(var/mob/user, direction)
|
||||
if(user in src.stomach_contents)
|
||||
@@ -252,11 +263,13 @@
|
||||
|
||||
/mob/living/carbon/proc/throw_mode_off()
|
||||
src.in_throw_mode = 0
|
||||
src.throw_icon.icon_state = "act_throw_off"
|
||||
if(src.throw_icon) //in case we don't have the HUD and we use the hotkey
|
||||
src.throw_icon.icon_state = "act_throw_off"
|
||||
|
||||
/mob/living/carbon/proc/throw_mode_on()
|
||||
src.in_throw_mode = 1
|
||||
src.throw_icon.icon_state = "act_throw_on"
|
||||
if(src.throw_icon)
|
||||
src.throw_icon.icon_state = "act_throw_on"
|
||||
|
||||
/mob/proc/throw_item(atom/target)
|
||||
return
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
|
||||
|
||||
if(!key && brain_op_stage != 4 && stat != DEAD)
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] totally catatonic. The stresses of life in deep-space must have been too much for [t_him]. Any recovery is unlikely</span>\n"
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] fast asleep. It doesn't look like they are waking up anytime soon.</span>\n"
|
||||
else if(!client && brain_op_stage != 4 && stat != DEAD)
|
||||
msg += "[t_He] [t_has] suddenly fallen asleep.\n"
|
||||
|
||||
@@ -262,7 +262,7 @@
|
||||
wound_flavor_text["[temp.display_name]"] = "<span class='warning'>[t_He] has a robot [temp.display_name]!</span>\n"
|
||||
continue
|
||||
else
|
||||
wound_flavor_text["[temp.display_name]"] = "<span class='warning'>[t_He] has a robot [temp.display_name], it has"
|
||||
wound_flavor_text["[temp.display_name]"] = "<span class='warning'>[t_He] has a robot [temp.display_name]. It has"
|
||||
if(temp.brute_dam) switch(temp.brute_dam)
|
||||
if(0 to 20)
|
||||
wound_flavor_text["[temp.display_name]"] += " some dents"
|
||||
@@ -284,8 +284,8 @@
|
||||
var/this_wound_desc = W.desc
|
||||
if(W.bleeding()) this_wound_desc = "bleeding [this_wound_desc]"
|
||||
else if(W.bandaged) this_wound_desc = "bandaged [this_wound_desc]"
|
||||
if(W.germ_level > 1000) this_wound_desc = "badly infected [this_wound_desc]"
|
||||
else if(W.germ_level > 100) this_wound_desc = "lightly infected [this_wound_desc]"
|
||||
if(W.germ_level > 600) this_wound_desc = "badly infected [this_wound_desc]"
|
||||
else if(W.germ_level > 330) this_wound_desc = "lightly infected [this_wound_desc]"
|
||||
if(this_wound_desc in wound_descriptors)
|
||||
wound_descriptors[this_wound_desc] += W.amount
|
||||
continue
|
||||
@@ -389,7 +389,7 @@
|
||||
msg += "<span class='warning'><b>[src] has blood running from under [t_his] gloves!</b></span>\n"
|
||||
|
||||
for(var/implant in get_visible_implants(1))
|
||||
msg += "<span class='warning'><b>[src] has \a [implant] sticking out of their flesh!</span>\n"
|
||||
msg += "<span class='warning'><b>[src] has \a [implant] sticking out of [t_his] flesh!</span>\n"
|
||||
if(digitalcamo)
|
||||
msg += "[t_He] [t_is] repulsively uncanny!\n"
|
||||
|
||||
|
||||
@@ -1220,7 +1220,7 @@
|
||||
return
|
||||
|
||||
usr << "Don't move until counting is finished."
|
||||
var/time = world.timeofday
|
||||
var/time = world.time
|
||||
sleep(60)
|
||||
if(usr.l_move_time >= time) //checks if our mob has moved during the sleep()
|
||||
usr << "You moved while counting. Try again."
|
||||
|
||||
@@ -65,13 +65,13 @@
|
||||
|
||||
if (organ_name in organs_by_name)
|
||||
var/datum/organ/external/O = get_organ(organ_name)
|
||||
|
||||
|
||||
if(amount > 0)
|
||||
O.take_damage(amount, 0, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
|
||||
else
|
||||
//if you don't want to heal robot organs, they you will have to check that yourself before using this proc.
|
||||
O.heal_damage(-amount, 0, internal=0, robo_repair=(O.status & ORGAN_ROBOT))
|
||||
|
||||
|
||||
hud_updateflag |= 1 << HEALTH_HUD
|
||||
|
||||
/mob/living/carbon/human/proc/adjustFireLossByPart(var/amount, var/organ_name, var/obj/damage_source = null)
|
||||
@@ -80,13 +80,13 @@
|
||||
|
||||
if (organ_name in organs_by_name)
|
||||
var/datum/organ/external/O = get_organ(organ_name)
|
||||
|
||||
|
||||
if(amount > 0)
|
||||
O.take_damage(0, amount, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
|
||||
else
|
||||
//if you don't want to heal robot organs, they you will have to check that yourself before using this proc.
|
||||
O.heal_damage(0, -amount, internal=0, robo_repair=(O.status & ORGAN_ROBOT))
|
||||
|
||||
|
||||
hud_updateflag |= 1 << HEALTH_HUD
|
||||
|
||||
/mob/living/carbon/human/Stun(amount)
|
||||
@@ -302,14 +302,6 @@ This function restores all organs.
|
||||
if(istype(used_weapon,/obj/item/weapon))
|
||||
var/obj/item/weapon/W = used_weapon //Sharp objects will always embed if they do enough damage.
|
||||
if( (damage > (10*W.w_class)) && ( (sharp && !ismob(W.loc)) || prob(damage/W.w_class) ) )
|
||||
organ.implants += W
|
||||
visible_message("<span class='danger'>\The [W] sticks in the wound!</span>")
|
||||
embedded_flag = 1
|
||||
src.verbs += /mob/proc/yank_out_object
|
||||
W.add_blood(src)
|
||||
if(ismob(W.loc))
|
||||
var/mob/living/H = W.loc
|
||||
H.drop_item()
|
||||
W.loc = src
|
||||
organ.embed(W)
|
||||
|
||||
return 1
|
||||
|
||||
@@ -98,11 +98,7 @@ emp_act
|
||||
(SP.name) = "[P.name] shrapnel"
|
||||
(SP.desc) = "[SP.desc] It looks like it was fired from [P.shot_from]."
|
||||
(SP.loc) = organ
|
||||
organ.implants += SP
|
||||
visible_message("<span class='danger'>The projectile sticks in the wound!</span>")
|
||||
embedded_flag = 1
|
||||
src.verbs += /mob/proc/yank_out_object
|
||||
SP.add_blood(src)
|
||||
organ.embed(SP)
|
||||
|
||||
return (..(P , def_zone))
|
||||
|
||||
@@ -236,7 +232,7 @@ emp_act
|
||||
if ((weapon_sharp || weapon_edge) && prob(getarmor(def_zone, "melee")))
|
||||
weapon_sharp = 0
|
||||
weapon_edge = 0
|
||||
|
||||
|
||||
if(armor >= 2) return 0
|
||||
if(!I.force) return 0
|
||||
|
||||
@@ -314,4 +310,4 @@ emp_act
|
||||
var/obj/item/clothing/suit/space/SS = wear_suit
|
||||
var/penetrated_dam = max(0,(damage - max(0,(SS.breach_threshold - SS.damage))))
|
||||
|
||||
if(penetrated_dam) SS.create_breaches(damtype, penetrated_dam)
|
||||
if(penetrated_dam) SS.create_breaches(damtype, penetrated_dam)
|
||||
|
||||
@@ -129,12 +129,10 @@
|
||||
G.process()
|
||||
|
||||
|
||||
/mob/living/carbon/human/calculate_affecting_pressure(var/pressure)
|
||||
..()
|
||||
var/pressure_difference = abs( pressure - ONE_ATMOSPHERE )
|
||||
|
||||
//Much like get_heat_protection(), this returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
|
||||
/mob/living/carbon/human/proc/get_pressure_protection()
|
||||
var/pressure_adjustment_coefficient = 1 //Determins how much the clothing you are wearing protects you in percent.
|
||||
|
||||
|
||||
if(head && (head.flags & STOPSPRESSUREDMAGE))
|
||||
pressure_adjustment_coefficient -= PRESSURE_HEAD_REDUCTION_COEFFICIENT
|
||||
|
||||
@@ -147,10 +145,16 @@
|
||||
if(S.can_breach && S.damage)
|
||||
var/pressure_loss = S.damage * 0.1
|
||||
pressure_adjustment_coefficient += pressure_loss
|
||||
|
||||
|
||||
pressure_adjustment_coefficient = min(1,max(pressure_adjustment_coefficient,0)) //So it isn't less than 0 or larger than 1.
|
||||
|
||||
return 1 - pressure_adjustment_coefficient //want 0 to be bad protection, 1 to be good protection
|
||||
|
||||
pressure_difference = pressure_difference * pressure_adjustment_coefficient
|
||||
/mob/living/carbon/human/calculate_affecting_pressure(var/pressure)
|
||||
..()
|
||||
var/pressure_difference = abs( pressure - ONE_ATMOSPHERE )
|
||||
|
||||
pressure_difference = pressure_difference * (1 - get_pressure_protection())
|
||||
|
||||
if(pressure > ONE_ATMOSPHERE)
|
||||
return ONE_ATMOSPHERE + pressure_difference
|
||||
@@ -316,16 +320,13 @@
|
||||
if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return
|
||||
if(species && (species.flags & NO_BREATHE || species.flags & IS_SYNTHETIC)) return
|
||||
|
||||
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 < config.health_threshold_crit && !reagents.has_reagent("inaprovaline"))
|
||||
losebreath++
|
||||
|
||||
|
||||
if(losebreath>0) //Suffocating so do not take a breath
|
||||
losebreath--
|
||||
if (prob(10)) //Gasp per 10 ticks? Sounds about right.
|
||||
@@ -619,14 +620,14 @@
|
||||
adjustOxyLoss(-5)
|
||||
|
||||
// Hot air hurts :(
|
||||
if( (abs(310.15 - breath.temperature) > 50) && !(COLD_RESISTANCE in mutations))
|
||||
if( (breath.temperature < species.cold_level_1 || breath.temperature > species.heat_level_1) && !(COLD_RESISTANCE in mutations))
|
||||
|
||||
if(status_flags & GODMODE)
|
||||
return 1
|
||||
|
||||
if(breath.temperature < species.cold_level_1)
|
||||
if(prob(20))
|
||||
src << "\red You feel your face freezing and an icicle forming in your lungs!"
|
||||
src << "\red You feel your face freezing and icicles forming in your lungs!"
|
||||
else if(breath.temperature > species.heat_level_1)
|
||||
if(prob(20))
|
||||
src << "\red You feel your face burning and a searing heat in your lungs!"
|
||||
@@ -650,9 +651,21 @@
|
||||
if(species.heat_level_3 to INFINITY)
|
||||
apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Heat")
|
||||
fire_alert = max(fire_alert, 2)
|
||||
|
||||
//Temporary fixes to the alerts.
|
||||
|
||||
|
||||
//breathing in hot/cold air also heats/cools you a bit
|
||||
var/temp_adj = breath.temperature - bodytemperature
|
||||
if (temp_adj < 0)
|
||||
temp_adj /= (BODYTEMP_COLD_DIVISOR * 5) //don't raise temperature as much as if we were directly exposed
|
||||
else
|
||||
temp_adj /= (BODYTEMP_HEAT_DIVISOR * 5) //don't raise temperature as much as if we were directly exposed
|
||||
|
||||
var/relative_density = breath.total_moles() / (MOLES_CELLSTANDARD * BREATH_PERCENTAGE)
|
||||
temp_adj *= relative_density
|
||||
|
||||
if (temp_adj > BODYTEMP_HEATING_MAX) temp_adj = BODYTEMP_HEATING_MAX
|
||||
if (temp_adj < BODYTEMP_COOLING_MAX) temp_adj = BODYTEMP_COOLING_MAX
|
||||
//world << "Breath: [breath.temperature], [src]: [bodytemperature], Adjusting: [temp_adj]"
|
||||
bodytemperature += temp_adj
|
||||
return 1
|
||||
|
||||
proc/handle_environment(datum/gas_mixture/environment)
|
||||
@@ -668,60 +681,63 @@
|
||||
if(istype(loc, /obj/mecha))
|
||||
var/obj/mecha/M = loc
|
||||
loc_temp = M.return_temperature()
|
||||
else if(istype(get_turf(src), /turf/space))
|
||||
else if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
|
||||
loc_temp = loc:air_contents.temperature
|
||||
else
|
||||
loc_temp = environment.temperature
|
||||
|
||||
if(adjusted_pressure < species.warning_low_pressure && adjusted_pressure > species.warning_low_pressure && abs(loc_temp - 293.15) < 20 && abs(bodytemperature - 310.14) < 0.5 && environment.phoron < MOLES_PHORON_VISIBLE)
|
||||
if(adjusted_pressure < species.warning_high_pressure && adjusted_pressure > species.warning_low_pressure && abs(loc_temp - bodytemperature) < 20 && bodytemperature < species.heat_level_1 && bodytemperature > species.cold_level_1 && environment.phoron < MOLES_PHORON_VISIBLE)
|
||||
return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp
|
||||
|
||||
//Body temperature is adjusted in two steps. Firstly your body tries to stabilize itself a bit.
|
||||
if(stat != 2)
|
||||
stabilize_temperature_from_calories()
|
||||
|
||||
//After then, it reacts to the surrounding atmosphere based on your thermal protection
|
||||
if(loc_temp < BODYTEMP_COLD_DAMAGE_LIMIT) //Place is colder than we are
|
||||
//Body temperature adjusts depending on surrounding atmosphere based on your thermal protection
|
||||
var/temp_adj = 0
|
||||
if(loc_temp < bodytemperature) //Place is colder than we are
|
||||
var/thermal_protection = get_cold_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
|
||||
if(thermal_protection < 1)
|
||||
var/amt = min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX)
|
||||
bodytemperature += amt
|
||||
else if (loc_temp > BODYTEMP_HEAT_DAMAGE_LIMIT) //Place is hotter than we are
|
||||
temp_adj = (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR) //this will be negative
|
||||
else if (loc_temp > bodytemperature) //Place is hotter than we are
|
||||
var/thermal_protection = get_heat_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
|
||||
if(thermal_protection < 1)
|
||||
var/amt = min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX)
|
||||
bodytemperature += amt
|
||||
temp_adj = (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR)
|
||||
|
||||
//Use heat transfer as proportional to the gas density. However, we only care about the relative density vs standard 101 kPa/20 C air. Therefore we can use mole ratios
|
||||
var/relative_density = environment.total_moles() / MOLES_CELLSTANDARD
|
||||
temp_adj *= relative_density
|
||||
|
||||
if (temp_adj > BODYTEMP_HEATING_MAX) temp_adj = BODYTEMP_HEATING_MAX
|
||||
if (temp_adj < BODYTEMP_COOLING_MAX) temp_adj = BODYTEMP_COOLING_MAX
|
||||
//world << "Environment: [loc_temp], [src]: [bodytemperature], Adjusting: [temp_adj]"
|
||||
bodytemperature += temp_adj
|
||||
|
||||
// +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt.
|
||||
if(bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT)
|
||||
if(bodytemperature > species.heat_level_1)
|
||||
//Body temperature is too hot.
|
||||
fire_alert = max(fire_alert, 1)
|
||||
if(status_flags & GODMODE) return 1 //godmode
|
||||
switch(bodytemperature)
|
||||
if(360 to 400)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_1, BURN, used_weapon = "High Body Temperature")
|
||||
if(species.heat_level_1 to species.heat_level_2)
|
||||
take_overall_damage(burn=HEAT_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature")
|
||||
fire_alert = max(fire_alert, 2)
|
||||
if(400 to 1000)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN, used_weapon = "High Body Temperature")
|
||||
if(species.heat_level_2 to species.heat_level_3)
|
||||
take_overall_damage(burn=HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
|
||||
fire_alert = max(fire_alert, 2)
|
||||
if(1000 to INFINITY)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_3, BURN, used_weapon = "High Body Temperature")
|
||||
if(species.heat_level_3 to INFINITY)
|
||||
take_overall_damage(burn=HEAT_DAMAGE_LEVEL_3, used_weapon = "High Body Temperature")
|
||||
fire_alert = max(fire_alert, 2)
|
||||
|
||||
else if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
else if(bodytemperature < species.cold_level_1)
|
||||
fire_alert = max(fire_alert, 1)
|
||||
if(status_flags & GODMODE) return 1 //godmode
|
||||
if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
|
||||
switch(bodytemperature)
|
||||
if(200 to 260)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_1, BURN, used_weapon = "Low Body Temperature")
|
||||
if(species.cold_level_2 to species.cold_level_1)
|
||||
take_overall_damage(burn=COLD_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature")
|
||||
fire_alert = max(fire_alert, 1)
|
||||
if(120 to 200)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_2, BURN, used_weapon = "Low Body Temperature")
|
||||
if(species.cold_level_3 to species.cold_level_2)
|
||||
take_overall_damage(burn=COLD_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
|
||||
fire_alert = max(fire_alert, 1)
|
||||
if(-INFINITY to 120)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_3, BURN, used_weapon = "Low Body Temperature")
|
||||
if(-INFINITY to species.cold_level_3)
|
||||
take_overall_damage(burn=COLD_DAMAGE_LEVEL_3, used_weapon = "High Body Temperature")
|
||||
fire_alert = max(fire_alert, 1)
|
||||
|
||||
// Account for massive pressure differences. Done by Polymorph
|
||||
@@ -729,7 +745,8 @@
|
||||
if(status_flags & GODMODE) return 1 //godmode
|
||||
|
||||
if(adjusted_pressure >= species.hazard_high_pressure)
|
||||
adjustBruteLoss( min( ( (adjusted_pressure / species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) )
|
||||
var/pressure_damage = min( ( (adjusted_pressure / species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE)
|
||||
take_overall_damage(brute=pressure_damage, used_weapon = "High Pressure")
|
||||
pressure_alert = 2
|
||||
else if(adjusted_pressure >= species.warning_high_pressure)
|
||||
pressure_alert = 1
|
||||
@@ -737,17 +754,9 @@
|
||||
pressure_alert = 0
|
||||
else if(adjusted_pressure >= species.hazard_low_pressure)
|
||||
pressure_alert = -1
|
||||
|
||||
if(species && species.flags & IS_SYNTHETIC)
|
||||
bodytemperature += 0.5 * TEMPERATURE_DAMAGE_COEFFICIENT //Synthetics suffer overheating in a vaccuum. ~Z
|
||||
|
||||
else
|
||||
|
||||
if(species && species.flags & IS_SYNTHETIC)
|
||||
bodytemperature += 1 * TEMPERATURE_DAMAGE_COEFFICIENT
|
||||
|
||||
if( !(COLD_RESISTANCE in mutations))
|
||||
adjustBruteLoss( LOW_PRESSURE_DAMAGE )
|
||||
take_overall_damage(brute=LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure")
|
||||
pressure_alert = -2
|
||||
else
|
||||
pressure_alert = -1
|
||||
@@ -774,27 +783,35 @@
|
||||
temp_change = (temperature - current)
|
||||
return temp_change
|
||||
*/
|
||||
|
||||
proc/stabilize_temperature_from_calories()
|
||||
var/body_temperature_difference = 310.15 - bodytemperature
|
||||
|
||||
proc/stabilize_body_temperature()
|
||||
if (species.flags & IS_SYNTHETIC)
|
||||
bodytemperature += species.synth_temp_gain //just keep putting out heat.
|
||||
return
|
||||
|
||||
var/body_temperature_difference = species.body_temperature - bodytemperature
|
||||
|
||||
if (abs(body_temperature_difference) < 0.5)
|
||||
return //fuck this precision
|
||||
switch(bodytemperature)
|
||||
if(-INFINITY to 260.15) //260.15 is 310.15 - 50, the temperature where you start to feel effects.
|
||||
if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up.
|
||||
nutrition -= 2
|
||||
var/recovery_amt = max((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM)
|
||||
|
||||
if(bodytemperature < species.cold_level_1) //260.15 is 310.15 - 50, the temperature where you start to feel effects.
|
||||
if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up.
|
||||
nutrition -= 2
|
||||
var/recovery_amt = max((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM)
|
||||
//world << "Cold. Difference = [body_temperature_difference]. Recovering [recovery_amt]"
|
||||
// log_debug("Cold. Difference = [body_temperature_difference]. Recovering [recovery_amt]")
|
||||
bodytemperature += recovery_amt
|
||||
if(260.15 to 360.15)
|
||||
var/recovery_amt = body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR
|
||||
bodytemperature += recovery_amt
|
||||
else if(species.cold_level_1 <= bodytemperature && bodytemperature <= species.heat_level_1)
|
||||
var/recovery_amt = body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR
|
||||
//world << "Norm. Difference = [body_temperature_difference]. Recovering [recovery_amt]"
|
||||
// log_debug("Norm. Difference = [body_temperature_difference]. Recovering [recovery_amt]")
|
||||
bodytemperature += recovery_amt
|
||||
if(360.15 to INFINITY) //360.15 is 310.15 + 50, the temperature where you start to feel effects.
|
||||
//We totally need a sweat system cause it totally makes sense...~
|
||||
var/recovery_amt = min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers
|
||||
bodytemperature += recovery_amt
|
||||
else if(bodytemperature > species.heat_level_1) //360.15 is 310.15 + 50, the temperature where you start to feel effects.
|
||||
//We totally need a sweat system cause it totally makes sense...~
|
||||
var/recovery_amt = min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers
|
||||
//world << "Hot. Difference = [body_temperature_difference]. Recovering [recovery_amt]"
|
||||
// log_debug("Hot. Difference = [body_temperature_difference]. Recovering [recovery_amt]")
|
||||
bodytemperature += recovery_amt
|
||||
bodytemperature += recovery_amt
|
||||
|
||||
//This proc returns a number made up of the flags for body parts which you are protected on. (such as HEAD, UPPER_TORSO, LOWER_TORSO, etc. See setup.dm for the full list)
|
||||
proc/get_heat_protection_flags(temperature) //Temperature is the temperature you're being exposed to.
|
||||
@@ -1074,12 +1091,6 @@
|
||||
|
||||
if(!(species.flags & IS_SYNTHETIC)) handle_trace_chems()
|
||||
|
||||
var/datum/organ/internal/liver/liver = internal_organs["liver"]
|
||||
liver.process()
|
||||
|
||||
var/datum/organ/internal/eyes/eyes = internal_organs["eyes"]
|
||||
eyes.process()
|
||||
|
||||
updatehealth()
|
||||
|
||||
return //TODO: DEFERRED
|
||||
@@ -1091,6 +1102,7 @@
|
||||
else //ALIVE. LIGHTS ARE ON
|
||||
updatehealth() //TODO
|
||||
if(!in_stasis)
|
||||
stabilize_body_temperature() //Body temperature adjusts itself
|
||||
handle_organs() //Optimized.
|
||||
handle_blood()
|
||||
|
||||
@@ -1215,14 +1227,11 @@
|
||||
|
||||
if(druggy)
|
||||
druggy = max(druggy-1, 0)
|
||||
/*
|
||||
// Increase germ_level regularly
|
||||
if(prob(40))
|
||||
germ_level += 1
|
||||
|
||||
// If you're dirty, your gloves will become dirty, too.
|
||||
if(gloves && germ_level > gloves.germ_level && prob(10))
|
||||
gloves.germ_level += 1
|
||||
*/
|
||||
|
||||
return 1
|
||||
|
||||
proc/handle_regular_hud_updates()
|
||||
@@ -1449,17 +1458,46 @@
|
||||
else fire.icon_state = "fire0"
|
||||
|
||||
if(bodytemp)
|
||||
switch(bodytemperature) //310.055 optimal body temp
|
||||
if(370 to INFINITY) bodytemp.icon_state = "temp4"
|
||||
if(350 to 370) bodytemp.icon_state = "temp3"
|
||||
if(335 to 350) bodytemp.icon_state = "temp2"
|
||||
if(320 to 335) bodytemp.icon_state = "temp1"
|
||||
if(300 to 320) bodytemp.icon_state = "temp0"
|
||||
if(295 to 300) bodytemp.icon_state = "temp-1"
|
||||
if(280 to 295) bodytemp.icon_state = "temp-2"
|
||||
if(260 to 280) bodytemp.icon_state = "temp-3"
|
||||
else bodytemp.icon_state = "temp-4"
|
||||
|
||||
if (!species)
|
||||
switch(bodytemperature) //310.055 optimal body temp
|
||||
if(370 to INFINITY) bodytemp.icon_state = "temp4"
|
||||
if(350 to 370) bodytemp.icon_state = "temp3"
|
||||
if(335 to 350) bodytemp.icon_state = "temp2"
|
||||
if(320 to 335) bodytemp.icon_state = "temp1"
|
||||
if(300 to 320) bodytemp.icon_state = "temp0"
|
||||
if(295 to 300) bodytemp.icon_state = "temp-1"
|
||||
if(280 to 295) bodytemp.icon_state = "temp-2"
|
||||
if(260 to 280) bodytemp.icon_state = "temp-3"
|
||||
else bodytemp.icon_state = "temp-4"
|
||||
else
|
||||
var/temp_step
|
||||
if (bodytemperature >= species.body_temperature)
|
||||
temp_step = (species.heat_level_1 - species.body_temperature)/4
|
||||
|
||||
if (bodytemperature >= species.heat_level_1)
|
||||
bodytemp.icon_state = "temp4"
|
||||
else if (bodytemperature >= species.body_temperature + temp_step*3)
|
||||
bodytemp.icon_state = "temp3"
|
||||
else if (bodytemperature >= species.body_temperature + temp_step*2)
|
||||
bodytemp.icon_state = "temp2"
|
||||
else if (bodytemperature >= species.body_temperature + temp_step*1)
|
||||
bodytemp.icon_state = "temp1"
|
||||
else
|
||||
bodytemp.icon_state = "temp0"
|
||||
|
||||
else if (bodytemperature < species.body_temperature)
|
||||
temp_step = (species.body_temperature - species.cold_level_1)/4
|
||||
|
||||
if (bodytemperature <= species.cold_level_1)
|
||||
bodytemp.icon_state = "temp-4"
|
||||
else if (bodytemperature <= species.body_temperature - temp_step*3)
|
||||
bodytemp.icon_state = "temp-3"
|
||||
else if (bodytemperature <= species.body_temperature - temp_step*2)
|
||||
bodytemp.icon_state = "temp-2"
|
||||
else if (bodytemperature <= species.body_temperature - temp_step*1)
|
||||
bodytemp.icon_state = "temp-1"
|
||||
else
|
||||
bodytemp.icon_state = "temp0"
|
||||
if(blind)
|
||||
if(blinded) blind.layer = 18
|
||||
else blind.layer = 0
|
||||
@@ -1520,21 +1558,21 @@
|
||||
for (var/ID in virus2)
|
||||
var/datum/disease2/disease/V = virus2[ID]
|
||||
V.cure(src)
|
||||
if(life_tick % 3) //don't spam checks over all objects in view every tick.
|
||||
for(var/obj/effect/decal/cleanable/O in view(1,src))
|
||||
if(istype(O,/obj/effect/decal/cleanable/blood))
|
||||
var/obj/effect/decal/cleanable/blood/B = O
|
||||
if(B.virus2.len)
|
||||
for (var/ID in B.virus2)
|
||||
var/datum/disease2/disease/V = B.virus2[ID]
|
||||
infect_virus2(src,V.getcopy())
|
||||
|
||||
for(var/obj/effect/decal/cleanable/O in view(1,src))
|
||||
if(istype(O,/obj/effect/decal/cleanable/blood))
|
||||
var/obj/effect/decal/cleanable/blood/B = O
|
||||
if(B.virus2.len)
|
||||
for (var/ID in B.virus2)
|
||||
var/datum/disease2/disease/V = B.virus2[ID]
|
||||
infect_virus2(src,V)
|
||||
|
||||
else if(istype(O,/obj/effect/decal/cleanable/mucus))
|
||||
var/obj/effect/decal/cleanable/mucus/M = O
|
||||
if(M.virus2.len)
|
||||
for (var/ID in M.virus2)
|
||||
var/datum/disease2/disease/V = M.virus2[ID]
|
||||
infect_virus2(src,V)
|
||||
else if(istype(O,/obj/effect/decal/cleanable/mucus))
|
||||
var/obj/effect/decal/cleanable/mucus/M = O
|
||||
if(M.virus2.len)
|
||||
for (var/ID in M.virus2)
|
||||
var/datum/disease2/disease/V = M.virus2[ID]
|
||||
infect_virus2(src,V.getcopy())
|
||||
|
||||
|
||||
if(virus2.len)
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
icon_state = "nymph1"
|
||||
var/list/donors = list()
|
||||
var/ready_evolve = 0
|
||||
universal_understand = 0 // Dionaea do not need to speak to people
|
||||
universal_speak = 0 // before becoming an adult. Use *chirp.
|
||||
|
||||
/mob/living/carbon/monkey/diona/attack_hand(mob/living/carbon/human/M as mob)
|
||||
|
||||
@@ -207,7 +209,7 @@
|
||||
src.visible_message("\red [src] flicks out a feeler and neatly steals a sample of [M]'s blood.","\red You flick out a feeler and neatly steal a sample of [M]'s blood.")
|
||||
donors += M.real_name
|
||||
for(var/datum/language/L in M.languages)
|
||||
languages += L
|
||||
languages |= L
|
||||
|
||||
spawn(25)
|
||||
update_progression()
|
||||
@@ -245,14 +247,11 @@
|
||||
|
||||
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
|
||||
|
||||
|
||||
if(stat == 2)
|
||||
return say_dead(message)
|
||||
|
||||
var/datum/language/speaking = null
|
||||
|
||||
|
||||
|
||||
if(length(message) >= 2)
|
||||
var/channel_prefix = copytext(message, 1 ,3)
|
||||
if(languages.len)
|
||||
@@ -270,6 +269,4 @@
|
||||
if(!message || stat)
|
||||
return
|
||||
|
||||
|
||||
|
||||
..(message, speaking, verb, null, null, message_range, null)
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
var/heat_level_1 = 360 // Heat damage level 1 above this point.
|
||||
var/heat_level_2 = 400 // Heat damage level 2 above this point.
|
||||
var/heat_level_3 = 1000 // Heat damage level 2 above this point.
|
||||
|
||||
var/body_temperature = 310.15 //non-IS_SYNTHETIC species will try to stabilize at this temperature. (also affects temperature processing)
|
||||
var/synth_temp_gain = 0 //IS_SYNTHETIC species will gain this much temperature every second
|
||||
|
||||
var/darksight = 2
|
||||
var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure.
|
||||
@@ -279,6 +282,8 @@
|
||||
heat_level_2 = 3000
|
||||
heat_level_3 = 4000
|
||||
|
||||
body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not
|
||||
|
||||
flags = IS_WHITELISTED | NO_BREATHE | REQUIRE_LIGHT | NO_SCAN | IS_PLANT | RAD_ABSORB | NO_BLOOD | IS_SLOW | NO_PAIN
|
||||
|
||||
blood_color = "#004400"
|
||||
@@ -317,15 +322,17 @@
|
||||
burn_mod = 1
|
||||
|
||||
warning_low_pressure = 50
|
||||
hazard_low_pressure = 10
|
||||
hazard_low_pressure = 0
|
||||
|
||||
cold_level_1 = 50
|
||||
cold_level_2 = -1
|
||||
cold_level_3 = -1
|
||||
|
||||
heat_level_1 = 2000
|
||||
heat_level_2 = 3000
|
||||
heat_level_3 = 4000
|
||||
heat_level_1 = 500 //gives them about 25 seconds in space before taking damage
|
||||
heat_level_2 = 1000
|
||||
heat_level_3 = 2000
|
||||
|
||||
synth_temp_gain = 10 //this should cause IPCs to stabilize at ~80 C in a 20 C environment.
|
||||
|
||||
flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | IS_SYNTHETIC
|
||||
|
||||
|
||||
@@ -431,7 +431,8 @@
|
||||
else
|
||||
stop_pulling()
|
||||
. = ..()
|
||||
if ((s_active && !( s_active in contents ) ))
|
||||
|
||||
if (s_active && !( s_active in contents ) && get_turf(s_active) != get_turf(src)) //check !( s_active in contents ) first so we hopefully don't have to call get_turf() so much.
|
||||
s_active.close(src)
|
||||
|
||||
if(update_slimes)
|
||||
|
||||
@@ -103,7 +103,7 @@ var/list/department_radio_keys = list(
|
||||
var/obj/O = I
|
||||
hearturfs += O.locs[1]
|
||||
objects |= O
|
||||
|
||||
|
||||
for(var/mob/M in player_list)
|
||||
if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS))
|
||||
listening |= M
|
||||
@@ -113,7 +113,8 @@ var/list/department_radio_keys = list(
|
||||
|
||||
for(var/obj/O in objects)
|
||||
spawn(0)
|
||||
O.hear_talk(src, message, verb, speaking)
|
||||
if(O) //It's possible that it could be deleted in the meantime.
|
||||
O.hear_talk(src, message, verb, speaking)
|
||||
|
||||
var/speech_bubble_test = say_test(message)
|
||||
var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]")
|
||||
|
||||
@@ -250,13 +250,13 @@ var/list/ai_list = list()
|
||||
for (var/area_name in alarmlist)
|
||||
var/datum/alarm/alarm = alarmlist[area_name]
|
||||
dat += "<NOBR>"
|
||||
|
||||
|
||||
var/cameratext = ""
|
||||
if (alarm.cameras)
|
||||
for (var/obj/machinery/camera/I in alarm.cameras)
|
||||
cameratext += text("[]<A HREF=?src=\ref[];switchcamera=\ref[]>[]</A>", (cameratext=="") ? "" : " | ", src, I, I.c_tag)
|
||||
dat += text("-- [] ([])", alarm.area.name, (cameratext)? cameratext : "No Camera")
|
||||
|
||||
|
||||
if (alarm.sources.len > 1)
|
||||
dat += text(" - [] sources", alarm.sources.len)
|
||||
dat += "</NOBR><BR>\n"
|
||||
@@ -407,23 +407,11 @@ var/list/ai_list = list()
|
||||
|
||||
if (href_list["track"])
|
||||
var/mob/target = locate(href_list["track"]) in mob_list
|
||||
/*
|
||||
var/mob/living/silicon/ai/A = locate(href_list["track2"]) in mob_list
|
||||
if(A && target)
|
||||
A.ai_actual_track(target)
|
||||
*/
|
||||
|
||||
//Strip off any "(as Derplord)".
|
||||
//If there's a way to do this via a var that doesn't give the AI extra info, please let me know.
|
||||
var/seeking = target.name
|
||||
var/index = findtext(seeking, "(as ")
|
||||
if(index)
|
||||
seeking = copytext(seeking, 1, index-1)
|
||||
|
||||
if(target && html_decode(href_list["trackname"]) == seeking)
|
||||
if(target && (!istype(target, /mob/living/carbon/human) || html_decode(href_list["trackname"]) == target:get_face_name()))
|
||||
ai_actual_track(target)
|
||||
else
|
||||
src << "\red System error. Cannot locate [html_decode(href_list["trackname"])]."
|
||||
|
||||
src << "\red System error. Cannot locate [html_decode(href_list["trackname"])]."
|
||||
return
|
||||
|
||||
else if (href_list["faketrack"])
|
||||
@@ -539,24 +527,24 @@ var/list/ai_list = list()
|
||||
/mob/living/silicon/ai/triggerAlarm(var/class, area/A, list/cameralist, var/source)
|
||||
if (stat == 2)
|
||||
return 1
|
||||
|
||||
|
||||
..()
|
||||
|
||||
|
||||
var/cameratext = ""
|
||||
for (var/obj/machinery/camera/C in cameralist)
|
||||
cameratext += "[(cameratext == "")? "" : "|"]<A HREF=?src=\ref[src];switchcamera=\ref[C]>[C.c_tag]</A>"
|
||||
|
||||
|
||||
queueAlarm("--- [class] alarm detected in [A.name]! ([(cameratext)? cameratext : "No Camera"])", class)
|
||||
|
||||
|
||||
if (viewalerts) ai_alerts()
|
||||
|
||||
/mob/living/silicon/ai/cancelAlarm(var/class, area/A as area, var/source)
|
||||
var/has_alarm = ..()
|
||||
|
||||
|
||||
if (!has_alarm)
|
||||
queueAlarm(text("--- [] alarm in [] has been cleared.", class, A.name), class, 0)
|
||||
if (viewalerts) ai_alerts()
|
||||
|
||||
|
||||
return has_alarm
|
||||
|
||||
/mob/living/silicon/ai/cancel_camera()
|
||||
|
||||
@@ -188,7 +188,7 @@
|
||||
if(!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
|
||||
user << "\red You don't have the dexterity to do this!"
|
||||
return
|
||||
if(!istype(M, /mob/living/silicon/robot))
|
||||
if(!istype(M, /mob/living/silicon/robot) && !(ishuman(M) && (M:species.flags & IS_SYNTHETIC)))
|
||||
user << "\red You can't analyze non-robotic things!"
|
||||
return
|
||||
|
||||
@@ -200,22 +200,39 @@
|
||||
user.show_message("\t Damage Specifics: <font color='#FFA500'>[BU]</font> - <font color='red'>[BR]</font>")
|
||||
if(M.tod && M.stat == DEAD)
|
||||
user.show_message("\blue Time of Disable: [M.tod]")
|
||||
|
||||
var/mob/living/silicon/robot/H = M
|
||||
var/list/damaged = H.get_damaged_components(1,1,1)
|
||||
user.show_message("\blue Localized Damage:",1)
|
||||
if(length(damaged)>0)
|
||||
for(var/datum/robot_component/org in damaged)
|
||||
user.show_message(text("\blue \t []: [][] - [] - [] - []", \
|
||||
capitalize(org.name), \
|
||||
(org.installed == -1) ? "<font color='red'><b>DESTROYED</b></font> " :"",\
|
||||
(org.electronics_damage > 0) ? "<font color='#FFA500'>[org.electronics_damage]</font>" :0, \
|
||||
(org.brute_damage > 0) ? "<font color='red'>[org.brute_damage]</font>" :0, \
|
||||
(org.toggled) ? "Toggled ON" : "<font color='red'>Toggled OFF</font>",\
|
||||
(org.powered) ? "Power ON" : "<font color='red'>Power OFF</font>"),1)
|
||||
else
|
||||
user.show_message("\blue \t Components are OK.",1)
|
||||
if(H.emagged && prob(5))
|
||||
user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1)
|
||||
|
||||
if (istype(M, /mob/living/silicon/robot))
|
||||
var/mob/living/silicon/robot/H = M
|
||||
var/list/damaged = H.get_damaged_components(1,1,1)
|
||||
user.show_message("\blue Localized Damage:",1)
|
||||
if(length(damaged)>0)
|
||||
for(var/datum/robot_component/org in damaged)
|
||||
user.show_message(text("\blue \t []: [][] - [] - [] - []", \
|
||||
capitalize(org.name), \
|
||||
(org.installed == -1) ? "<font color='red'><b>DESTROYED</b></font> " :"",\
|
||||
(org.electronics_damage > 0) ? "<font color='#FFA500'>[org.electronics_damage]</font>" :0, \
|
||||
(org.brute_damage > 0) ? "<font color='red'>[org.brute_damage]</font>" :0, \
|
||||
(org.toggled) ? "Toggled ON" : "<font color='red'>Toggled OFF</font>",\
|
||||
(org.powered) ? "Power ON" : "<font color='red'>Power OFF</font>"),1)
|
||||
else
|
||||
user.show_message("\blue \t Components are OK.",1)
|
||||
if(H.emagged && prob(5))
|
||||
user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1)
|
||||
|
||||
if (ishuman(M) && (M:species.flags & IS_SYNTHETIC))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/list/damaged = H.get_damaged_organs(1,1)
|
||||
user.show_message("\blue Localized Damage, Brute/Electronics:",1)
|
||||
if(length(damaged)>0)
|
||||
for(var/datum/organ/external/org in damaged)
|
||||
user.show_message(text("\blue \t []: [] - []", \
|
||||
capitalize(org.display_name), \
|
||||
(org.brute_dam > 0) ? "\red [org.brute_dam]" :0, \
|
||||
(org.burn_dam > 0) ? "<font color='#FFA500'>[org.burn_dam]</font>" :0),1)
|
||||
else
|
||||
user.show_message("\blue \t Components are OK.",1)
|
||||
|
||||
user.show_message("\blue Operating Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1)
|
||||
|
||||
src.add_fingerprint(user)
|
||||
return
|
||||
|
||||
@@ -760,6 +760,12 @@ note dizziness decrements automatically in the mob's Life() proc.
|
||||
canmove = 0
|
||||
if( istype(buckled,/obj/structure/stool/bed/chair) )
|
||||
lying = 0
|
||||
else if(istype(buckled, /obj/vehicle))
|
||||
var/obj/vehicle/V = buckled
|
||||
if(V.standing_mob)
|
||||
lying = 0
|
||||
else
|
||||
lying = 1
|
||||
else
|
||||
lying = 1
|
||||
else if( stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH))
|
||||
|
||||
@@ -199,7 +199,7 @@
|
||||
|
||||
|
||||
if(!mob.canmove)
|
||||
if (mob.buckled && (istype(mob.buckled, /obj/structure/stool/bed/chair/wheelchair))) // Exception for wheelchairs
|
||||
if (mob.buckled && (istype(mob.buckled, /obj/structure/stool/bed/chair/wheelchair) || istype(mob.buckled, /obj/vehicle))) // Exception for wheelchairs
|
||||
else return
|
||||
|
||||
//if(istype(mob.loc, /turf/space) || (mob.flags & NOGRAV))
|
||||
@@ -246,7 +246,9 @@
|
||||
move_delay -= 1.3
|
||||
var/tickcomp = ((1/(world.tick_lag))*1.3)
|
||||
move_delay = move_delay + tickcomp
|
||||
|
||||
|
||||
if(istype(mob.buckled, /obj/vehicle))
|
||||
return mob.buckled.relaymove(mob,direct)
|
||||
|
||||
if(mob.pulledby || mob.buckled) // Wheelchair driving!
|
||||
if(istype(mob.loc, /turf/space))
|
||||
|
||||
@@ -198,12 +198,7 @@ datum/preferences
|
||||
preview_icon.Blend(new /icon(icobase, "groin_[g]"), ICON_OVERLAY)
|
||||
preview_icon.Blend(new /icon(icobase, "head_[g]"), ICON_OVERLAY)
|
||||
|
||||
for(var/name in list("l_arm","r_arm","l_leg","r_leg","l_foot","r_foot","l_hand","r_hand"))
|
||||
// make sure the organ is added to the list so it's drawn
|
||||
if(organ_data[name] == null)
|
||||
organ_data[name] = null
|
||||
|
||||
for(var/name in organ_data)
|
||||
for(var/name in list("r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","l_arm","l_hand"))
|
||||
if(organ_data[name] == "amputated") continue
|
||||
|
||||
var/icon/temp = new /icon(icobase, "[name]")
|
||||
@@ -212,6 +207,11 @@ datum/preferences
|
||||
|
||||
preview_icon.Blend(temp, ICON_OVERLAY)
|
||||
|
||||
//Tail
|
||||
if(current_species && (current_species.flags & HAS_TAIL))
|
||||
var/icon/temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[current_species.tail]_s")
|
||||
preview_icon.Blend(temp, ICON_OVERLAY)
|
||||
|
||||
// Skin color
|
||||
if(current_species && (current_species.flags & HAS_SKIN_COLOR))
|
||||
preview_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
|
||||
|
||||
@@ -159,6 +159,9 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
|
||||
this.icon_state = pick(iconL)
|
||||
this.blood_DNA = list()
|
||||
this.blood_DNA[dna.unique_enzymes] = dna.b_type
|
||||
for (var/ID in virus2)
|
||||
var/datum/disease2/disease/V = virus2[ID]
|
||||
this.virus2[ID] = V.getcopy()
|
||||
if (species) this.basecolor = species.blood_color
|
||||
this.update_icon()
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
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
|
||||
|
||||
var/germ_level = 0 // INTERNAL germs inside the organ, this is BAD if it's greater than INFECTION_LEVEL_ONE
|
||||
|
||||
proc/process()
|
||||
return 0
|
||||
|
||||
@@ -46,13 +49,18 @@
|
||||
if(damage_this_tick > last_dam)
|
||||
force_process = 1
|
||||
last_dam = damage_this_tick
|
||||
if(!force_process && !bad_external_organs.len)
|
||||
return
|
||||
if(force_process)
|
||||
bad_external_organs.Cut()
|
||||
for(var/datum/organ/external/Ex in organs)
|
||||
bad_external_organs += Ex
|
||||
|
||||
|
||||
//processing internal organs is pretty cheap, do that first.
|
||||
for(var/datum/organ/internal/I in internal_organs)
|
||||
I.process()
|
||||
|
||||
if(!force_process && !bad_external_organs.len)
|
||||
return
|
||||
|
||||
for(var/datum/organ/external/E in bad_external_organs)
|
||||
if(!E)
|
||||
continue
|
||||
@@ -62,53 +70,24 @@
|
||||
else
|
||||
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) )
|
||||
broken = 1
|
||||
|
||||
if (!lying && world.time - l_move_time < 15)
|
||||
//Moving around with fractured ribs won't do you any good
|
||||
if (broken && E.internal_organs && prob(15))
|
||||
if (!lying && world.timeofday - l_move_time < 15)
|
||||
if (E.is_broken() && E.internal_organs && prob(15))
|
||||
var/datum/organ/internal/I = pick(E.internal_organs)
|
||||
custom_pain("You feel broken bones moving in your [E.display_name]!", 1)
|
||||
I.take_damage(rand(3,5))
|
||||
|
||||
//Moving makes open wounds get infected much faster
|
||||
if (E.wounds.len)
|
||||
for(var/datum/wound/W in E.wounds)
|
||||
if (W.infection_check())
|
||||
W.germ_level += 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
|
||||
var/hand
|
||||
if(E.name == "l_hand" || E.name == "l_arm")
|
||||
c_hand = l_hand
|
||||
hand = "left hand"
|
||||
if(E.name == "r_hand" || E.name == "r_arm")
|
||||
c_hand = r_hand
|
||||
hand = "right hand"
|
||||
if (c_hand)
|
||||
|
||||
if(broken)
|
||||
u_equip(c_hand)
|
||||
var/emote_scream = pick("screams in pain and", "let's out a sharp hiss and", "cries out and")
|
||||
emote("me", 1, "[(species && species.flags & NO_PAIN) ? "" : emote_scream ] drops what they were holding in their [hand]!")
|
||||
if(malfunction)
|
||||
u_equip(c_hand)
|
||||
emote("me", 1, "drops what they were holding, their [hand] 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.is_usable() || malfunction || (broken && !(E.status & ORGAN_SPLINTED)))
|
||||
if(E.name in list("l_leg","l_foot","r_leg","r_foot") && !lying)
|
||||
if (!E.is_usable() || E.is_malfunctioning() || (E.is_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))
|
||||
if(species && species.flags & NO_PAIN)
|
||||
|
||||
@@ -40,8 +40,6 @@
|
||||
|
||||
var/obj/item/hidden = null
|
||||
var/list/implants = list()
|
||||
// INTERNAL germs inside the organ, this is BAD if it's greater 0
|
||||
var/germ_level = 0
|
||||
|
||||
// how often wounds should be updated, a higher number means less often
|
||||
var/wound_update_accuracy = 1
|
||||
@@ -239,28 +237,31 @@ This function completely restores a damaged organ to perfect condition.
|
||||
for (var/datum/wound/W in wounds)
|
||||
if (W.can_worsen(type, damage))
|
||||
compatible_wounds += W
|
||||
|
||||
var/datum/wound/W = pick(compatible_wounds)
|
||||
W.open_wound(damage)
|
||||
if(prob(25))
|
||||
//maybe have a separate message for BRUISE type damage?
|
||||
owner.visible_message("\red The wound on [owner.name]'s [display_name] widens with a nasty ripping voice.",\
|
||||
"\red The wound on your [display_name] widens with a nasty ripping voice.",\
|
||||
"You hear a nasty ripping noise, as if flesh is being torn apart.")
|
||||
return
|
||||
|
||||
if(compatible_wounds.len)
|
||||
var/datum/wound/W = pick(compatible_wounds)
|
||||
W.open_wound(damage)
|
||||
if(prob(25))
|
||||
//maybe have a separate message for BRUISE type damage?
|
||||
owner.visible_message("\red The wound on [owner.name]'s [display_name] widens with a nasty ripping voice.",\
|
||||
"\red The wound on your [display_name] widens with a nasty ripping voice.",\
|
||||
"You hear a nasty ripping noise, as if flesh is being torn apart.")
|
||||
return
|
||||
|
||||
//Creating wound
|
||||
var/wound_type = get_wound_type(type, damage)
|
||||
var/datum/wound/W = new wound_type(damage)
|
||||
|
||||
//Check whether we can add the wound to an existing wound
|
||||
for(var/datum/wound/other in wounds)
|
||||
if(other.can_merge(W))
|
||||
other.merge_wound(W)
|
||||
W = null // to signify that the wound was added
|
||||
break
|
||||
if(W)
|
||||
wounds += W
|
||||
if(wound_type)
|
||||
var/datum/wound/W = new wound_type(damage)
|
||||
|
||||
//Check whether we can add the wound to an existing wound
|
||||
for(var/datum/wound/other in wounds)
|
||||
if(other.can_merge(W))
|
||||
other.merge_wound(W)
|
||||
W = null // to signify that the wound was added
|
||||
break
|
||||
if(W)
|
||||
wounds += W
|
||||
|
||||
/datum/organ/external/proc/get_wound_type(var/type = CUT, var/damage)
|
||||
//if you look a the names in the wound's stages list for each wound type you will see the logic behind these values
|
||||
@@ -279,7 +280,7 @@ This function completely restores a damaged organ to perfect condition.
|
||||
if (damage <= 15) return /datum/wound/burn/large
|
||||
if (damage <= 30) return /datum/wound/burn/severe
|
||||
if (damage <= 40) return /datum/wound/burn/deep
|
||||
if (damage <= 50) return /datum/wound/burn/carbonised
|
||||
return /datum/wound/burn/carbonised
|
||||
|
||||
/****************************************************
|
||||
PROCESSING & UPDATING
|
||||
@@ -295,7 +296,10 @@ This function completely restores a damaged organ to perfect condition.
|
||||
if(last_dam != brute_dam + burn_dam) // Process when we are fully healed up.
|
||||
last_dam = brute_dam + burn_dam
|
||||
return 1
|
||||
last_dam = brute_dam + burn_dam
|
||||
else
|
||||
last_dam = brute_dam + burn_dam
|
||||
if(germ_level)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/organ/external/process()
|
||||
@@ -327,50 +331,89 @@ This function completely restores a damaged organ to perfect condition.
|
||||
if(!(status & ORGAN_BROKEN))
|
||||
perma_injury = 0
|
||||
|
||||
//Infections
|
||||
update_germs()
|
||||
return
|
||||
|
||||
//Updating germ levels. Handles organ germ levels and necrosis.
|
||||
#define GANGREN_LEVEL_ONE 100
|
||||
#define GANGREN_LEVEL_TWO 1000
|
||||
#define GANGREN_LEVEL_TERMINAL 2500
|
||||
#define GERM_TRANSFER_AMOUNT germ_level/500
|
||||
/*
|
||||
The INFECTION_LEVEL values defined in setup.dm control the time it takes to reach the different
|
||||
infection levels. Since infection growth is exponential, you can adjust the time it takes to get
|
||||
from one germ_level to another using the rough formula:
|
||||
|
||||
desired_germ_level = initial_germ_level*e^(desired_time_in_seconds/1000)
|
||||
|
||||
So if I wanted it to take an average of 15 minutes to get from level one (100) to level two
|
||||
I would set INFECTION_LEVEL_TWO to 100*e^(15*60/1000) = 245. Note that this is the average time,
|
||||
the actual time is dependent on RNG.
|
||||
|
||||
INFECTION_LEVEL_ONE below this germ level nothing happens, and the infection doesn't grow
|
||||
INFECTION_LEVEL_TWO above this germ level the infection will start to spread to internal and adjacent organs
|
||||
INFECTION_LEVEL_THREE above this germ level the player will take additional toxin damage per second, and will die in minutes without
|
||||
antitox. also, above this germ level you will need to overdose on spaceacillin to reduce the germ_level.
|
||||
|
||||
Note that amputating the affected organ does in fact remove the infection from the
|
||||
player's body, though, antitox and spaceacillin are easy enough to get I doubt it will ever be needed.
|
||||
*/
|
||||
/datum/organ/external/proc/update_germs()
|
||||
|
||||
if(status & ORGAN_ROBOT|ORGAN_DESTROYED) //Robotic limbs shouldn't be infected, nor should nonexistant limbs.
|
||||
if(status & (ORGAN_ROBOT|ORGAN_DESTROYED)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs.
|
||||
germ_level = 0
|
||||
return
|
||||
|
||||
if(germ_level > 0 && owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
|
||||
if(owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
|
||||
//Syncing germ levels with external wounds
|
||||
for(var/datum/wound/W in wounds)
|
||||
if(!W.bandaged && !W.salved)
|
||||
W.germ_level = max(W.germ_level, germ_level) //Wounds get all the germs
|
||||
if (W.germ_level > germ_level) //Badly infected wounds raise internal germ levels
|
||||
germ_level++
|
||||
//Open wounds can become infected
|
||||
if (owner.germ_level > W.germ_level && W.infection_check())
|
||||
W.germ_level++
|
||||
|
||||
//Infected wounds raise the organ's germ level
|
||||
W.germ_level = max(W.germ_level, germ_level) //Wounds get all the germs
|
||||
if (W.germ_level > germ_level) //Badly infected wounds raise internal germ levels
|
||||
germ_level++
|
||||
|
||||
if(germ_level > GANGREN_LEVEL_ONE && prob(round(germ_level/100)))
|
||||
germ_level++
|
||||
owner.adjustToxLoss(1)
|
||||
|
||||
if(germ_level > GANGREN_LEVEL_TWO)
|
||||
germ_level++
|
||||
owner.adjustToxLoss(1)
|
||||
/*
|
||||
if(germ_level > GANGREN_LEVEL_TERMINAL)
|
||||
var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
|
||||
if (germ_level > 0 && antibiotics > 5)
|
||||
if (prob(4*antibiotics)) germ_level-- //the higher the germ level the more antibiotics you'll need.
|
||||
|
||||
if(germ_level >= INFECTION_LEVEL_ONE)
|
||||
//having an infection raises your body temperature
|
||||
var/fever_temperature = (owner.species.heat_level_1 - owner.species.body_temperature - 1)* min(germ_level/INFECTION_LEVEL_THREE, 1) + owner.species.body_temperature
|
||||
if (owner.bodytemperature < fever_temperature)
|
||||
//world << "fever: [owner.bodytemperature] < [fever_temperature], raising temperature."
|
||||
owner.bodytemperature++
|
||||
|
||||
if(prob(round(germ_level/10)))
|
||||
germ_level++
|
||||
if (prob(5)) //adjust this to tweak how fast people take toxin damage from infections
|
||||
owner.adjustToxLoss(1)
|
||||
|
||||
if(germ_level >= INFECTION_LEVEL_TWO)
|
||||
//spread the infection
|
||||
for (var/datum/organ/internal/I in internal_organs)
|
||||
if (I.germ_level < germ_level)
|
||||
I.germ_level++
|
||||
|
||||
if (children) //To child organs
|
||||
for (var/datum/organ/external/child in children)
|
||||
if (child.germ_level < germ_level && !(child.status & ORGAN_ROBOT))
|
||||
if (child.germ_level < INFECTION_LEVEL_ONE*2 || prob(30))
|
||||
child.germ_level++
|
||||
|
||||
if (parent)
|
||||
if (parent.germ_level < germ_level && !(parent.status & ORGAN_ROBOT))
|
||||
if (parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30))
|
||||
parent.germ_level++
|
||||
|
||||
if(germ_level >= INFECTION_LEVEL_THREE && antibiotics < 30) //overdosing is necessary to stop severe infections
|
||||
if (!(status & ORGAN_DEAD))
|
||||
status |= ORGAN_DEAD
|
||||
owner << "<span class='notice'>You can't feel your [display_name] anymore...</span>"
|
||||
owner.update_body(1)
|
||||
if (prob(10)) //Spreading the fun
|
||||
if (children) //To child organs
|
||||
for (var/datum/organ/external/child in children)
|
||||
if (!(child.status & (ORGAN_DEAD|ORGAN_DESTROYED|ORGAN_ROBOT)))
|
||||
child.germ_level += round(GERM_TRANSFER_AMOUNT)
|
||||
if (parent)
|
||||
if (!(parent.status & (ORGAN_DEAD|ORGAN_DESTROYED|ORGAN_ROBOT)))
|
||||
parent.germ_level += round(GERM_TRANSFER_AMOUNT)
|
||||
*/
|
||||
|
||||
germ_level++
|
||||
owner.adjustToxLoss(1)
|
||||
|
||||
|
||||
//Updating wounds. Handles wound natural I had some free spachealing, internal bleedings and infections
|
||||
/datum/organ/external/proc/update_wounds()
|
||||
@@ -681,9 +724,9 @@ This function completely restores a damaged organ to perfect condition.
|
||||
/datum/organ/external/proc/get_damage() //returns total damage
|
||||
return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use health?
|
||||
|
||||
/datum/organ/external/proc/is_infected()
|
||||
/datum/organ/external/proc/has_infected_wound()
|
||||
for(var/datum/wound/W in wounds)
|
||||
if(W.germ_level > 100)
|
||||
if(W.germ_level > 150)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -700,7 +743,42 @@ This function completely restores a damaged organ to perfect condition.
|
||||
/datum/organ/external/proc/is_usable()
|
||||
return !(status & (ORGAN_DESTROYED|ORGAN_MUTATED|ORGAN_DEAD))
|
||||
|
||||
/****************************************************
|
||||
/datum/organ/external/proc/is_broken()
|
||||
return ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED))
|
||||
|
||||
/datum/organ/external/proc/is_malfunctioning()
|
||||
return ((status & ORGAN_ROBOT) && prob(brute_dam + burn_dam))
|
||||
|
||||
//for arms and hands
|
||||
/datum/organ/external/proc/process_grasp(var/obj/item/c_hand, var/hand_name)
|
||||
if (!c_hand)
|
||||
return
|
||||
|
||||
if(is_broken())
|
||||
owner.u_equip(c_hand)
|
||||
var/emote_scream = pick("screams in pain and", "lets out a sharp cry and", "cries out and")
|
||||
owner.emote("me", 1, "[(owner.species && owner.species.flags & NO_PAIN) ? "" : emote_scream ] drops what they were holding in their [hand_name]!")
|
||||
if(is_malfunctioning())
|
||||
owner.u_equip(c_hand)
|
||||
owner.emote("me", 1, "drops what they were holding, their [hand_name] 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)
|
||||
|
||||
/datum/organ/external/proc/embed(var/obj/item/weapon/W, var/silent = 0)
|
||||
if(!silent)
|
||||
owner.visible_message("<span class='danger'>\The [W] sticks in the wound!</span>")
|
||||
implants += W
|
||||
owner.embedded_flag = 1
|
||||
owner.verbs += /mob/proc/yank_out_object
|
||||
W.add_blood(owner)
|
||||
if(ismob(W.loc))
|
||||
var/mob/living/H = W.loc
|
||||
H.drop_item()
|
||||
W.loc = owner/****************************************************
|
||||
ORGAN DEFINES
|
||||
****************************************************/
|
||||
|
||||
@@ -728,6 +806,10 @@ This function completely restores a damaged organ to perfect condition.
|
||||
max_damage = 50
|
||||
min_broken_damage = 20
|
||||
body_part = ARM_LEFT
|
||||
|
||||
process()
|
||||
..()
|
||||
process_grasp(owner.l_hand, "left hand")
|
||||
|
||||
/datum/organ/external/l_leg
|
||||
name = "l_leg"
|
||||
@@ -745,6 +827,10 @@ This function completely restores a damaged organ to perfect condition.
|
||||
max_damage = 50
|
||||
min_broken_damage = 20
|
||||
body_part = ARM_RIGHT
|
||||
|
||||
process()
|
||||
..()
|
||||
process_grasp(owner.r_hand, "right hand")
|
||||
|
||||
/datum/organ/external/r_leg
|
||||
name = "r_leg"
|
||||
@@ -780,6 +866,10 @@ This function completely restores a damaged organ to perfect condition.
|
||||
max_damage = 30
|
||||
min_broken_damage = 15
|
||||
body_part = HAND_RIGHT
|
||||
|
||||
process()
|
||||
..()
|
||||
process_grasp(owner.r_hand, "right hand")
|
||||
|
||||
/datum/organ/external/l_hand
|
||||
name = "l_hand"
|
||||
@@ -788,6 +878,10 @@ This function completely restores a damaged organ to perfect condition.
|
||||
max_damage = 30
|
||||
min_broken_damage = 15
|
||||
body_part = HAND_LEFT
|
||||
|
||||
process()
|
||||
..()
|
||||
process_grasp(owner.l_hand, "left hand")
|
||||
|
||||
/datum/organ/external/head
|
||||
name = "head"
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
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]
|
||||
@@ -30,6 +31,37 @@
|
||||
H.internal_organs[src.name] = src
|
||||
src.owner = H
|
||||
|
||||
/datum/organ/internal/process()
|
||||
|
||||
//Process infections
|
||||
if (!germ_level)
|
||||
return
|
||||
|
||||
if (robotic >= 2) //TODO make robotic internal and external organs separate types of organ instead of a flag
|
||||
germ_level = 0
|
||||
return
|
||||
|
||||
var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
|
||||
|
||||
if (germ_level > 0 && antibiotics > 5)
|
||||
if (prob(4*antibiotics)) germ_level--
|
||||
if (antibiotics > 30) germ_level--
|
||||
|
||||
if (germ_level >= INFECTION_LEVEL_ONE/2)
|
||||
if(prob(round(germ_level/6))) //aiming for germ level to go from ambient to INFECTION_LEVEL_TWO in an average of 15 minutes
|
||||
germ_level++
|
||||
if(prob(1))
|
||||
take_damage(1,silent=0)
|
||||
|
||||
if (germ_level >= INFECTION_LEVEL_TWO)
|
||||
var/datum/organ/external/parent = owner.get_organ(parent_organ)
|
||||
if (parent.germ_level < germ_level && ( parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30) ))
|
||||
parent.germ_level++
|
||||
|
||||
if (prob(5)) //about once every 20 seconds
|
||||
take_damage(1,silent=prob(30))
|
||||
|
||||
|
||||
/datum/organ/internal/proc/take_damage(amount, var/silent=0)
|
||||
if(src.robotic == 2)
|
||||
src.damage += (amount * 0.8)
|
||||
@@ -40,7 +72,6 @@
|
||||
if (!silent)
|
||||
owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1)
|
||||
|
||||
|
||||
/datum/organ/internal/proc/emp_act(severity)
|
||||
switch(robotic)
|
||||
if(0)
|
||||
@@ -96,7 +127,7 @@
|
||||
owner.drip(10)
|
||||
if(prob(4))
|
||||
spawn owner.emote("me", 1, "gasps for air!")
|
||||
owner.losebreath += 5
|
||||
owner.losebreath += 15
|
||||
|
||||
/datum/organ/internal/liver
|
||||
name = "liver"
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
|
||||
// checks if wound is considered open for external infections
|
||||
// untreated cuts (and bleeding bruises) and burns are possibly infectable, chance higher if wound is bigger
|
||||
proc/can_infect()
|
||||
proc/infection_check()
|
||||
if (is_treated() && damage < 10)
|
||||
return 0
|
||||
if (disinfected)
|
||||
|
||||
@@ -228,6 +228,8 @@
|
||||
src.amount = length
|
||||
if (param_color)
|
||||
color = param_color
|
||||
else
|
||||
color = item_color
|
||||
pixel_x = rand(-2,2)
|
||||
pixel_y = rand(-2,2)
|
||||
updateicon()
|
||||
@@ -236,6 +238,7 @@
|
||||
/obj/item/weapon/cable_coil/proc/updateicon()
|
||||
if (!color)
|
||||
color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_ORANGE, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
|
||||
item_color = color
|
||||
if(amount == 1)
|
||||
icon_state = "coil1"
|
||||
name = "cable piece"
|
||||
|
||||
@@ -356,6 +356,7 @@
|
||||
switchcount = L.switchcount
|
||||
rigged = L.rigged
|
||||
brightness = L.brightness
|
||||
l_color = L.color
|
||||
on = has_power()
|
||||
update()
|
||||
|
||||
@@ -514,6 +515,7 @@
|
||||
L.status = status
|
||||
L.rigged = rigged
|
||||
L.brightness = src.brightness
|
||||
L.color = l_color
|
||||
|
||||
// light item inherits the switchcount, then zero it
|
||||
L.switchcount = switchcount
|
||||
@@ -539,6 +541,7 @@
|
||||
L.status = status
|
||||
L.rigged = rigged
|
||||
L.brightness = brightness
|
||||
L.color = l_color
|
||||
|
||||
// light item inherits the switchcount, then zero it
|
||||
L.switchcount = switchcount
|
||||
@@ -618,7 +621,7 @@
|
||||
|
||||
// called when on fire
|
||||
|
||||
/obj/machinery/light/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
/obj/machinery/light/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(prob(max(0, exposed_temperature - 673))) //0% at <400C, 100% at >500C
|
||||
broken()
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
var/blue = mixOneColor(weight,bluecolor)
|
||||
|
||||
//assemble all the pieces
|
||||
var/finalcolor = "#[red][green][blue]"
|
||||
var/finalcolor = rgb(red, green, blue)
|
||||
return finalcolor
|
||||
|
||||
/proc/mixOneColor(var/list/weight, var/list/color)
|
||||
@@ -58,10 +58,9 @@
|
||||
mixedcolor = round(mixedcolor)
|
||||
|
||||
//until someone writes a formal proof for this algorithm, let's keep this in
|
||||
if(mixedcolor<0x00 || mixedcolor>0xFF)
|
||||
return 0
|
||||
// if(mixedcolor<0x00 || mixedcolor>0xFF)
|
||||
// return 0
|
||||
//that's not the kind of operation we are running here, nerd
|
||||
mixedcolor=min(max(mixedcolor,0),255)
|
||||
|
||||
var/finalcolor = num2hex(mixedcolor)
|
||||
while(length(finalcolor)<2)
|
||||
finalcolor = text("0[]",finalcolor) //Takes care of leading zeroes
|
||||
return finalcolor
|
||||
return mixedcolor
|
||||
|
||||
@@ -293,6 +293,7 @@
|
||||
var/max_pill_count = 20
|
||||
|
||||
/obj/machinery/chem_master/New()
|
||||
..()
|
||||
var/datum/reagents/R = new/datum/reagents(100)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
|
||||
@@ -118,10 +118,15 @@ datum
|
||||
else //injected
|
||||
M.contract_disease(D, 1, 0)
|
||||
if(self.data && self.data["virus2"] && istype(M, /mob/living/carbon))//infecting...
|
||||
if(method == TOUCH)
|
||||
infect_virus2(M,self.data["virus2"])
|
||||
else
|
||||
infect_virus2(M,self.data["virus2"],1) //injected, force infection!
|
||||
var/list/vlist = self.data["virus2"]
|
||||
if (vlist.len)
|
||||
for (var/ID in vlist)
|
||||
var/datum/disease2/disease/V = vlist[ID]
|
||||
|
||||
if(method == TOUCH)
|
||||
infect_virus2(M,V.getcopy())
|
||||
else
|
||||
infect_virus2(M,V.getcopy(),1) //injected, force infection!
|
||||
if(self.data && self.data["antibodies"] && istype(M, /mob/living/carbon))//... and curing
|
||||
var/mob/living/carbon/C = M
|
||||
C.antibodies |= self.data["antibodies"]
|
||||
@@ -146,6 +151,9 @@ datum
|
||||
blood_prop.viruses += newVirus
|
||||
newVirus.holder = blood_prop
|
||||
|
||||
if(self.data["virus2"])
|
||||
blood_prop.virus2 = virus_copylist(self.data["virus2"])
|
||||
|
||||
|
||||
else if(istype(self.data["donor"], /mob/living/carbon/monkey))
|
||||
var/obj/effect/decal/cleanable/blood/blood_prop = locate() in T
|
||||
@@ -1573,14 +1581,14 @@ datum
|
||||
var/turf/the_turf = get_turf(O)
|
||||
var/datum/gas_mixture/napalm = new
|
||||
var/datum/gas/volatile_fuel/fuel = new
|
||||
fuel.moles = 5
|
||||
fuel.moles = volume
|
||||
napalm.trace_gases += fuel
|
||||
the_turf.assume_air(napalm)
|
||||
reaction_turf(var/turf/T, var/volume)
|
||||
src = null
|
||||
var/datum/gas_mixture/napalm = new
|
||||
var/datum/gas/volatile_fuel/fuel = new
|
||||
fuel.moles = 5
|
||||
fuel.moles = volume
|
||||
napalm.trace_gases += fuel
|
||||
T.assume_air(napalm)
|
||||
return
|
||||
|
||||
@@ -127,8 +127,39 @@
|
||||
..() // -> item/attackby()
|
||||
if(istype(W,/obj/item/weapon/storage))
|
||||
..() // -> item/attackby()
|
||||
|
||||
if(istype(W,/obj/item/weapon/kitchen/utensil))
|
||||
|
||||
var/obj/item/weapon/kitchen/utensil/U = W
|
||||
|
||||
if(!U.reagents)
|
||||
U.create_reagents(5)
|
||||
|
||||
if (U.reagents.total_volume > 0)
|
||||
user << "\red You already have something on your [U]."
|
||||
return
|
||||
|
||||
user.visible_message( \
|
||||
"[user] scoops up some [src] with \the [U]!", \
|
||||
"\blue You scoop up some [src] with \the [U]!" \
|
||||
)
|
||||
|
||||
src.bitecount++
|
||||
U.overlays.Cut()
|
||||
U.loaded = "[src]"
|
||||
var/image/I = new(U.icon, "loadedfood")
|
||||
I.color = src.filling_color
|
||||
U.overlays += I
|
||||
|
||||
reagents.trans_to(U,min(reagents.total_volume,5))
|
||||
|
||||
if (reagents.total_volume <= 0)
|
||||
del(src)
|
||||
return
|
||||
|
||||
if((slices_num <= 0 || !slices_num) || !slice_path)
|
||||
return 0
|
||||
|
||||
var/inaccurate = 0
|
||||
if( \
|
||||
istype(W, /obj/item/weapon/kitchenknife) || \
|
||||
@@ -173,8 +204,8 @@
|
||||
)
|
||||
else
|
||||
user.visible_message( \
|
||||
"\blue [user] inaccurately slices \the [src] with [W]!", \
|
||||
"\blue You inaccurately slice \the [src] with your [W]!" \
|
||||
"\blue [user] crudely slices \the [src] with [W]!", \
|
||||
"\blue You crudely slice \the [src] with your [W]!" \
|
||||
)
|
||||
slices_lost = rand(1,min(1,round(slices_num/2)))
|
||||
var/reagents_per_slice = reagents.total_volume/slices_num
|
||||
@@ -182,6 +213,7 @@
|
||||
var/obj/slice = new slice_path (src.loc)
|
||||
reagents.trans_to(slice,reagents_per_slice)
|
||||
del(src)
|
||||
|
||||
return
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/Del()
|
||||
@@ -876,33 +908,6 @@
|
||||
..()
|
||||
reagents.add_reagent("nutriment", 8)
|
||||
bitesize = 1
|
||||
attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W,/obj/item/weapon/kitchen/utensil/fork))
|
||||
if (W.icon_state == "forkloaded")
|
||||
user << "\red You already have omelette on your fork."
|
||||
return
|
||||
//W.icon = 'icons/obj/kitchen.dmi'
|
||||
W.icon_state = "forkloaded"
|
||||
/*if (herp)
|
||||
world << "[user] takes a piece of omelette with his fork!"*/
|
||||
//Why this unecessary check? Oh I know, because I'm bad >:C
|
||||
// Yes, you are. You griefing my badmin toys. --rastaf0
|
||||
user.visible_message( \
|
||||
"[user] takes a piece of omelette with their fork!", \
|
||||
"\blue You take a piece of omelette with your fork!" \
|
||||
)
|
||||
reagents.remove_reagent("nutriment", 1)
|
||||
if (reagents.total_volume <= 0)
|
||||
del(src)
|
||||
/*
|
||||
* Unsused.
|
||||
/obj/item/weapon/reagent_containers/food/snacks/omeletteforkload
|
||||
name = "Omelette Du Fromage"
|
||||
desc = "That's all you can say!"
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("nutriment", 1)
|
||||
*/
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/muffin
|
||||
name = "Muffin"
|
||||
@@ -1532,7 +1537,7 @@
|
||||
filling_color = "#ADAC7F"
|
||||
|
||||
var/wrapped = 0
|
||||
var/monkey_type = null
|
||||
var/monkey_type = /mob/living/carbon/monkey
|
||||
|
||||
New()
|
||||
..()
|
||||
@@ -1550,19 +1555,46 @@
|
||||
if(wrapped)
|
||||
Unwrap(user)
|
||||
|
||||
On_Consume(var/mob/M)
|
||||
M << "<span class = 'warning'>Something inside of you suddently expands!</span>"
|
||||
|
||||
|
||||
if (istype(M, /mob/living/carbon/human))
|
||||
//Do not try to understand.
|
||||
var/obj/item/weapon/surprise = new/obj/item/weapon(M)
|
||||
var/mob/living/carbon/monkey/ook = new monkey_type(null) //no other way to get access to the vars, alas
|
||||
surprise.icon = ook.icon
|
||||
surprise.icon_state = ook.icon_state
|
||||
surprise.name = "malformed [ook.name]"
|
||||
surprise.desc = "Looks like \a very deformed [ook.name], a little small for its kind. It shows no signs of life."
|
||||
del(ook) //rip nullspace monkey
|
||||
surprise.transform *= 0.6
|
||||
surprise.add_blood(M)
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/datum/organ/external/E = H.get_organ("chest")
|
||||
E.fracture()
|
||||
for (var/datum/organ/internal/I in E.internal_organs)
|
||||
I.take_damage(rand(I.min_bruised_damage, I.min_broken_damage+1))
|
||||
|
||||
if (!E.hidden && prob(60)) //set it snuggly
|
||||
E.hidden = surprise
|
||||
E.cavity = 0
|
||||
else //someone is having a bad day
|
||||
E.createwound(CUT, 30)
|
||||
E.embed(surprise)
|
||||
else if (ismonkey(M))
|
||||
M.visible_message("<span class='danger'>[M] suddenly tears in half!</span>")
|
||||
var/mob/living/carbon/monkey/ook = new monkey_type(M.loc)
|
||||
ook.name = "malformed [ook.name]"
|
||||
ook.transform *= 0.6
|
||||
ook.add_blood(M)
|
||||
M.gib()
|
||||
..()
|
||||
|
||||
proc/Expand()
|
||||
for(var/mob/M in viewers(src,7))
|
||||
M << "\red \The [src] expands!"
|
||||
if(monkey_type)
|
||||
switch(monkey_type)
|
||||
if("tajara")
|
||||
new /mob/living/carbon/monkey/tajara(get_turf(src))
|
||||
if("unathi")
|
||||
new /mob/living/carbon/monkey/unathi(get_turf(src))
|
||||
if("skrell")
|
||||
new /mob/living/carbon/monkey/skrell(get_turf(src))
|
||||
else
|
||||
new /mob/living/carbon/monkey(get_turf(src))
|
||||
new monkey_type(src)
|
||||
del(src)
|
||||
|
||||
proc/Unwrap(mob/user as mob)
|
||||
@@ -1580,18 +1612,18 @@
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/farwacube
|
||||
name = "farwa cube"
|
||||
monkey_type ="tajara"
|
||||
monkey_type = /mob/living/carbon/monkey/tajara
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/farwacube
|
||||
name = "farwa cube"
|
||||
monkey_type ="tajara"
|
||||
monkey_type =/mob/living/carbon/monkey/tajara
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/stokcube
|
||||
name = "stok cube"
|
||||
monkey_type ="unathi"
|
||||
monkey_type = /mob/living/carbon/monkey/unathi
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/stokcube
|
||||
name = "stok cube"
|
||||
monkey_type ="unathi"
|
||||
monkey_type =/mob/living/carbon/monkey/unathi
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/neaeracube
|
||||
@@ -1599,7 +1631,7 @@
|
||||
monkey_type ="skrell"
|
||||
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/neaeracube
|
||||
name = "neaera cube"
|
||||
monkey_type ="skrell"
|
||||
monkey_type =/mob/living/carbon/monkey/skrell
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/spellburger
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
if(src)
|
||||
del(src)
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/temperature_expose(datum/gas_mixture/air, temperature, volume)
|
||||
/obj/structure/reagent_dispensers/fueltank/fire_act(datum/gas_mixture/air, temperature, volume)
|
||||
if(temperature > T0C+500)
|
||||
explode()
|
||||
return ..()
|
||||
|
||||
@@ -234,20 +234,8 @@
|
||||
flush()
|
||||
flushing = 1
|
||||
flick("intake-closing", src)
|
||||
var/deliveryCheck = 0
|
||||
var/obj/structure/disposalholder/H = new() // virtual holder object which actually
|
||||
// travels through the pipes.
|
||||
for(var/obj/structure/bigDelivery/O in src)
|
||||
deliveryCheck = 1
|
||||
if(O.sortTag == 0)
|
||||
O.sortTag = 1
|
||||
for(var/obj/item/smallDelivery/O in src)
|
||||
deliveryCheck = 1
|
||||
if (O.sortTag == 0)
|
||||
O.sortTag = 1
|
||||
if(deliveryCheck == 0)
|
||||
H.destinationTag = 1
|
||||
|
||||
air_contents = new() // new empty gas resv.
|
||||
|
||||
sleep(10)
|
||||
|
||||
@@ -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)]"
|
||||
|
||||
203
code/modules/research/xenoarchaeology/finds/finds_special.dm
Normal file
203
code/modules/research/xenoarchaeology/finds/finds_special.dm
Normal file
@@ -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)
|
||||
319
code/modules/research/xenoarchaeology/genetics/reconstitutor.dm
Normal file
319
code/modules/research/xenoarchaeology/genetics/reconstitutor.dm
Normal file
@@ -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)
|
||||
|
||||
145
code/modules/research/xenoarchaeology/master_controller.dm
Normal file
145
code/modules/research/xenoarchaeology/master_controller.dm
Normal file
@@ -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,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])" )
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
icon_state = "cespace_suit"
|
||||
item_state = "cespace_suit"
|
||||
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 100)
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank)
|
||||
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/anomaly
|
||||
name = "Excavation hood"
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -44,6 +44,10 @@
|
||||
var/emergency_alert = "CRYSTAL DELAMINATION IMMINENT."
|
||||
var/explosion_point = 1000
|
||||
|
||||
l_color = "#8A8A00"
|
||||
var/warning_color = "#B8B800"
|
||||
var/emergency_color = "#D9D900"
|
||||
|
||||
var/grav_pulling = 0
|
||||
var/pull_radius = 14
|
||||
|
||||
@@ -99,6 +103,13 @@
|
||||
del src
|
||||
return
|
||||
|
||||
//Changes color and luminosity of the light to these values if they were not already set
|
||||
/obj/machinery/power/supermatter/proc/shift_light(var/lum, var/clr)
|
||||
if(l_color != clr)
|
||||
l_color = clr
|
||||
if(luminosity != lum)
|
||||
SetLuminosity(lum)
|
||||
|
||||
/obj/machinery/power/supermatter/process()
|
||||
|
||||
var/turf/L = loc
|
||||
@@ -109,12 +120,15 @@
|
||||
if(!istype(L)) //We are in a crate or somewhere that isn't turf, if we return to turf resume processing but for now.
|
||||
return //Yeah just stop.
|
||||
|
||||
|
||||
if(damage > warning_point) // while the core is still damaged and it's still worth noting its status
|
||||
|
||||
shift_light(5, warning_color)
|
||||
if((world.timeofday - lastwarning) / 10 >= WARNING_DELAY)
|
||||
var/stability = num2text(round((damage / explosion_point) * 100))
|
||||
|
||||
if(damage > emergency_point)
|
||||
|
||||
shift_light(7, emergency_color)
|
||||
radio.autosay(addtext(emergency_alert, " Instability: ",stability,"%"), "Supermatter Monitor")
|
||||
lastwarning = world.timeofday
|
||||
|
||||
@@ -135,7 +149,8 @@
|
||||
mob.apply_effect(rads, IRRADIATE)
|
||||
|
||||
explode()
|
||||
|
||||
else
|
||||
shift_light(4,initial(l_color))
|
||||
if(grav_pulling)
|
||||
supermatter_pull()
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
can_infect = 1
|
||||
blood_level = 1
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
if (!hasorgans(target))
|
||||
return 0
|
||||
if (target_zone != "groin")
|
||||
return 0
|
||||
var/datum/organ/external/groin = target.get_organ("groin")
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
max_duration = 60
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
if (!hasorgans(target))
|
||||
return 0
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.open == 2 && affected.stage == 0
|
||||
|
||||
@@ -47,6 +49,8 @@
|
||||
max_duration = 70
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
if (!hasorgans(target))
|
||||
return 0
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.name != "head" && affected.open == 2 && affected.stage == 1
|
||||
|
||||
@@ -84,6 +88,8 @@
|
||||
max_duration = 70
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
if (!hasorgans(target))
|
||||
return 0
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.name == "head" && affected.open == 2 && affected.stage == 1
|
||||
|
||||
@@ -118,6 +124,8 @@
|
||||
max_duration = 60
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
if (!hasorgans(target))
|
||||
return 0
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.open == 2 && affected.stage == 2
|
||||
|
||||
|
||||
@@ -35,8 +35,9 @@
|
||||
max_duration = 110
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && affected.open == 0 && target_zone != "mouth"
|
||||
if(..())
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.open == 0 && target_zone != "mouth"
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
@@ -74,8 +75,9 @@
|
||||
max_duration = 120
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && affected.open == 0 && target_zone != "mouth"
|
||||
if(..())
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.open == 0 && target_zone != "mouth"
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
@@ -114,10 +116,9 @@
|
||||
max_duration = 110
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
if(isslime(target))
|
||||
return 0
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && affected.open == 0 && target_zone != "mouth"
|
||||
if(..())
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.open == 0 && target_zone != "mouth"
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
@@ -153,8 +154,9 @@
|
||||
max_duration = 60
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && affected.open && (affected.status & ORGAN_BLEEDING)
|
||||
if(..())
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.open && (affected.status & ORGAN_BLEEDING)
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
@@ -187,8 +189,9 @@
|
||||
max_duration = 40
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && affected.open == 1 && !(affected.status & ORGAN_BLEEDING)
|
||||
if(..())
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.open == 1 && !(affected.status & ORGAN_BLEEDING)
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
@@ -242,8 +245,9 @@
|
||||
max_duration = 100
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && affected.open && target_zone != "mouth"
|
||||
if(..())
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.open && target_zone != "mouth"
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
|
||||
@@ -28,8 +28,9 @@
|
||||
max_duration = 100
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && !(affected.status & ORGAN_CUT_AWAY)
|
||||
if(..())
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return !(affected.status & ORGAN_CUT_AWAY)
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
user.visible_message("[user] starts peeling back tattered flesh where [target]'s head used to be with \the [tool].", \
|
||||
@@ -61,8 +62,9 @@
|
||||
max_duration = 100
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && affected.status & ORGAN_CUT_AWAY && affected.open < 3 && !(affected.status & ORGAN_ATTACHABLE)
|
||||
if(..())
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.status & ORGAN_CUT_AWAY && affected.open < 3 && !(affected.status & ORGAN_ATTACHABLE)
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
@@ -94,8 +96,9 @@
|
||||
max_duration = 100
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && affected.open == 3
|
||||
if(..())
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.open == 3
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
user.visible_message("[user] is stapling and suturing flesh into place in [target]'s esophagal and vocal region with \the [tool].", \
|
||||
@@ -128,8 +131,9 @@
|
||||
max_duration = 70
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && affected.open == 4
|
||||
if(..())
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.open == 4
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
user.visible_message("[user] starts adjusting area around [target]'s neck with \the [tool].", \
|
||||
@@ -162,8 +166,9 @@
|
||||
max_duration = 100
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/head = target.get_organ(target_zone)
|
||||
return ..() && head.status & ORGAN_ATTACHABLE
|
||||
if(..())
|
||||
var/datum/organ/external/head = target.get_organ(target_zone)
|
||||
return head.status & ORGAN_ATTACHABLE
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
user.visible_message("[user] starts attaching [tool] to [target]'s reshaped neck.", \
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
/datum/surgery_step/cavity
|
||||
priority = 1
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
if(!hasorgans(target))
|
||||
return 0
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.open == 2 && !(affected.status & ORGAN_BLEEDING) && (target_zone != "chest" || target.op_stage.ribcage == 2)
|
||||
|
||||
@@ -41,8 +43,9 @@
|
||||
max_duration = 80
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && !affected.cavity && !affected.hidden
|
||||
if(..())
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return !affected.cavity && !affected.hidden
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
@@ -76,8 +79,9 @@
|
||||
max_duration = 80
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && affected.cavity
|
||||
if(..())
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.cavity
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
@@ -106,11 +110,9 @@
|
||||
max_duration = 100
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
if(isslime(target))
|
||||
return 0
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
var/can_fit = !affected.hidden && affected.cavity && tool.w_class <= get_max_wclass(affected)
|
||||
return ..() && can_fit
|
||||
if(..())
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return !affected.hidden && affected.cavity && tool.w_class <= get_max_wclass(affected)
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
@@ -185,7 +187,7 @@
|
||||
affected.implants -= obj
|
||||
|
||||
target.hud_updateflag |= 1 << IMPLOYAL_HUD
|
||||
|
||||
|
||||
//Handle possessive brain borers.
|
||||
if(istype(obj,/mob/living/simple_animal/borer))
|
||||
var/mob/living/simple_animal/borer/worm = obj
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
max_duration = 90
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
if(!hasorgans(target))
|
||||
return 0
|
||||
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
|
||||
var/internal_bleeding = 0
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
max_duration = 70
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
if (!istype(target))
|
||||
if (!hasorgans(target))
|
||||
return
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && target.op_stage.ribcage == 0 && affected.open >= 2
|
||||
@@ -197,6 +197,9 @@
|
||||
max_duration = 90
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
if(!hasorgans(target))
|
||||
return 0
|
||||
|
||||
var/is_chest_organ_damaged = 0
|
||||
var/datum/organ/external/chest/chest = target.get_organ("chest")
|
||||
for(var/datum/organ/internal/I in chest.internal_organs) if(I.damage > 0)
|
||||
@@ -278,6 +281,9 @@
|
||||
max_duration = 90
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
if(!hasorgans(target))
|
||||
return 0
|
||||
|
||||
var/is_chest_organ_damaged = 0
|
||||
var/datum/organ/internal/heart/heart = target.internal_organs["heart"]
|
||||
var/datum/organ/external/chest/chest = target.get_organ("chest")
|
||||
|
||||
@@ -30,8 +30,9 @@
|
||||
max_duration = 100
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && !(affected.status & ORGAN_CUT_AWAY)
|
||||
if(..())
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return !(affected.status & ORGAN_CUT_AWAY)
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
@@ -64,8 +65,9 @@
|
||||
max_duration = 100
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && affected.status & ORGAN_CUT_AWAY && affected.open < 3 && !(affected.status & ORGAN_ATTACHABLE)
|
||||
if(..())
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.status & ORGAN_CUT_AWAY && affected.open < 3 && !(affected.status & ORGAN_ATTACHABLE)
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
@@ -100,8 +102,9 @@
|
||||
max_duration = 70
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && affected.open == 3
|
||||
if(..())
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.open == 3
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
@@ -134,12 +137,13 @@
|
||||
max_duration = 100
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/obj/item/robot_parts/p = tool
|
||||
if (p.part)
|
||||
if (!(target_zone in p.part))
|
||||
return 0
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && affected.status & ORGAN_ATTACHABLE
|
||||
if(..())
|
||||
var/obj/item/robot_parts/p = tool
|
||||
if (p.part)
|
||||
if (!(target_zone in p.part))
|
||||
return 0
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected.status & ORGAN_ATTACHABLE
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/datum/organ/external/affected = target.get_organ(target_zone)
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
/obj/vehicle/train/cargo/engine
|
||||
name = "cargo train tug"
|
||||
desc = "A ridable electric car designed for pulling cargo trolleys."
|
||||
icon = 'icons/obj/aibots.dmi'
|
||||
icon_state = "mulebot1" //mulebot icons until I get some proper icons
|
||||
on = 1
|
||||
on = 0
|
||||
powered = 1
|
||||
locked = 0
|
||||
|
||||
standing_mob = 1
|
||||
load_item_visible = 1
|
||||
load_offset_x = 0
|
||||
load_offset_y = 9
|
||||
|
||||
var/car_limit = 3 //how many cars an engine can pull before performance degrades
|
||||
var/lead_engine = 1 //if the engine is the lead engine - set automatically
|
||||
active_engines = 1
|
||||
var/obj/item/weapon/key/cargo_train/key
|
||||
|
||||
/obj/item/weapon/key/cargo_train
|
||||
name = "key"
|
||||
desc = "A keyring with a small steel key, and a yellow fob reading \"Choo Choo!\"."
|
||||
icon = 'icons/obj/vehicles.dmi'
|
||||
icon_state = "train_keys"
|
||||
w_class = 1
|
||||
|
||||
/obj/vehicle/train/cargo/trolley
|
||||
name = "cargo train trolley"
|
||||
@@ -22,6 +31,7 @@
|
||||
passenger_allowed = 0
|
||||
locked = 0
|
||||
|
||||
standing_mob = 1
|
||||
load_item_visible = 1
|
||||
load_offset_x = 0
|
||||
load_offset_y = 9
|
||||
@@ -33,17 +43,16 @@
|
||||
..()
|
||||
cell = new /obj/item/weapon/cell/high
|
||||
verbs -= /atom/movable/verb/pull
|
||||
|
||||
/obj/vehicle/train/cargo/engine/initialize()
|
||||
..()
|
||||
key = new()
|
||||
|
||||
/obj/vehicle/train/cargo/engine/Move()
|
||||
if(on && cell.charge < power_use)
|
||||
turn_off()
|
||||
update_stats()
|
||||
if(load && lead_engine)
|
||||
load << "The drive motor briefly whines, then crawls to a stop."
|
||||
if(lead_engine && !on)
|
||||
if(load && is_train_head())
|
||||
load << "The drive motor briefly whines, then drones to a stop."
|
||||
|
||||
if(is_train_head() && !on)
|
||||
return 0
|
||||
|
||||
return ..()
|
||||
@@ -55,6 +64,16 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/vehicle/train/cargo/engine/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/weapon/key/cargo_train))
|
||||
if(!key)
|
||||
user.drop_item()
|
||||
key = W
|
||||
W.loc = src
|
||||
verbs += /obj/vehicle/train/cargo/engine/verb/remove_key
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/vehicle/train/cargo/update_icon()
|
||||
if(open)
|
||||
icon_state = "mulebot-hatch"
|
||||
@@ -92,6 +111,13 @@
|
||||
//-------------------------------------------
|
||||
// Train procs
|
||||
//-------------------------------------------
|
||||
/obj/vehicle/train/cargo/engine/turn_on()
|
||||
if(!key)
|
||||
return
|
||||
else
|
||||
..()
|
||||
update_stats()
|
||||
|
||||
/obj/vehicle/train/cargo/RunOver(var/mob/living/carbon/human/H)
|
||||
var/list/parts = list("head", "chest", "l_leg", "r_leg", "l_arm", "r_arm")
|
||||
|
||||
@@ -106,7 +132,7 @@
|
||||
/obj/vehicle/train/cargo/engine/RunOver(var/mob/living/carbon/human/H)
|
||||
..()
|
||||
|
||||
if(lead_engine && istype(load, /mob/living/carbon/human))
|
||||
if(is_train_head() && istype(load, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/D = load
|
||||
D << "\red \b You ran over [H]!"
|
||||
visible_message("<B>\red \The [src] ran over [H]!</B>")
|
||||
@@ -119,44 +145,11 @@
|
||||
//-------------------------------------------
|
||||
// Interaction procs
|
||||
//-------------------------------------------
|
||||
/obj/vehicle/train/cargo/trolley/verb/rotate()
|
||||
set name = "Rotate"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if(anchored)
|
||||
usr << "You cannot turn the trolley while it is latched onto a train."
|
||||
return
|
||||
|
||||
var/cur_dir = null
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
cur_dir = "North"
|
||||
if(SOUTH)
|
||||
cur_dir = "South"
|
||||
if(EAST)
|
||||
cur_dir = "East"
|
||||
if(WEST)
|
||||
cur_dir = "West"
|
||||
|
||||
var/new_dir = input("Select a new direction:", "Rotate", cur_dir) in list("North", "South", "East", "West")
|
||||
|
||||
switch(new_dir)
|
||||
if("North")
|
||||
dir = NORTH
|
||||
if("South")
|
||||
dir = SOUTH
|
||||
if("East")
|
||||
dir = EAST
|
||||
if("West")
|
||||
dir = WEST
|
||||
|
||||
|
||||
/obj/vehicle/train/cargo/engine/relaymove(mob/user, direction)
|
||||
if(user != load)
|
||||
return 0
|
||||
|
||||
if(lead_engine)
|
||||
if(is_train_head())
|
||||
if(direction == reverse_direction(dir))
|
||||
return 0
|
||||
if(Move(get_step(src, direction)))
|
||||
@@ -165,70 +158,86 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/vehicle/train/cargo/engine/examine()
|
||||
..()
|
||||
|
||||
if(!istype(usr, /mob/living/carbon/human))
|
||||
return
|
||||
|
||||
if(get_dist(usr,src) <= 1)
|
||||
usr << "The power light is [on ? "on" : "off"].\nThere are[key ? "" : " no"] keys in the ignition."
|
||||
|
||||
/obj/vehicle/train/cargo/engine/verb/check_power()
|
||||
set name = "Check power level"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if(!istype(usr, /mob/living/carbon/human))
|
||||
return
|
||||
|
||||
if(!cell)
|
||||
usr << "There is no power cell installed in [src]."
|
||||
return
|
||||
|
||||
usr << "The power meter reads [round(cell.percent(), 0.01)]%"
|
||||
|
||||
/obj/vehicle/train/cargo/engine/verb/start_engine()
|
||||
set name = "Start engine"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if(!istype(usr, /mob/living/carbon/human))
|
||||
return
|
||||
|
||||
if(on)
|
||||
usr << "The engine is already running."
|
||||
return
|
||||
|
||||
if(turn_on())
|
||||
usr << "You start [src]."
|
||||
turn_on()
|
||||
if (on)
|
||||
usr << "You start [src]'s engine."
|
||||
else
|
||||
if(cell.charge < power_use)
|
||||
usr << "[src] is out of power."
|
||||
else
|
||||
usr << "[src] won't start."
|
||||
usr << "[src]'s engine won't start."
|
||||
|
||||
//-------------------------------------------
|
||||
// Latching/unlatching procs
|
||||
//-------------------------------------------
|
||||
/obj/vehicle/train/cargo/trolley/latch(var/obj/vehicle/train/T)
|
||||
if(..())
|
||||
//if this is a trolley, and is now part of a train, anchor it so it cant be pushed around
|
||||
if(lead)
|
||||
anchored = 1
|
||||
lead.anchored = 1
|
||||
if(tow)
|
||||
anchored = 1
|
||||
tow.anchored = 1
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
/obj/vehicle/train/cargo/engine/verb/stop_engine()
|
||||
set name = "Stop engine"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if(!istype(usr, /mob/living/carbon/human))
|
||||
return
|
||||
|
||||
if(!on)
|
||||
usr << "The engine is already stopped."
|
||||
return
|
||||
|
||||
/obj/vehicle/train/cargo/trolley/unlatch()
|
||||
if(..())
|
||||
//if this carraige isn't part of a train anymore; unanchor it so it can be pushed around
|
||||
if(!tow && !lead)
|
||||
anchored = 0
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
turn_off()
|
||||
if (!on)
|
||||
usr << "You stop [src]'s engine."
|
||||
|
||||
/obj/vehicle/train/cargo/engine/verb/remove_key()
|
||||
set name = "Remove key"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
/obj/vehicle/train/cargo/engine/latch(var/obj/vehicle/train/T)
|
||||
if(..())
|
||||
//check if this is not the lead engine
|
||||
if(lead)
|
||||
lead_engine = 0
|
||||
if(tow)
|
||||
tow.anchored = 1
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
if(!istype(usr, /mob/living/carbon/human))
|
||||
return
|
||||
|
||||
if(!key || (load && load != usr))
|
||||
return
|
||||
|
||||
if(on)
|
||||
turn_off()
|
||||
|
||||
/obj/vehicle/train/cargo/engine/unlatch()
|
||||
if(..())
|
||||
//check if this is now the lead engine
|
||||
if(!lead)
|
||||
lead_engine = 1
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
key.loc = usr.loc
|
||||
if(!usr.get_active_hand())
|
||||
usr.put_in_hands(key)
|
||||
key = null
|
||||
|
||||
verbs -= /obj/vehicle/train/cargo/engine/verb/remove_key
|
||||
|
||||
//-------------------------------------------
|
||||
// Loading/unloading procs
|
||||
@@ -262,13 +271,23 @@
|
||||
/obj/vehicle/train/cargo/engine/update_train_stats()
|
||||
..()
|
||||
|
||||
speed_calc()
|
||||
update_move_delay()
|
||||
|
||||
if(!lead) //check if this is the lead engine
|
||||
lead_engine = 1
|
||||
/obj/vehicle/train/cargo/trolley/update_train_stats()
|
||||
..()
|
||||
|
||||
if(!lead && !tow)
|
||||
anchored = 0
|
||||
if(verbs.Find(/atom/movable/verb/pull))
|
||||
return
|
||||
else
|
||||
verbs += /atom/movable/verb/pull
|
||||
else
|
||||
anchored = 1
|
||||
verbs -= /atom/movable/verb/pull
|
||||
|
||||
/obj/vehicle/train/cargo/engine/proc/speed_calc()
|
||||
if(!lead_engine)
|
||||
/obj/vehicle/train/cargo/engine/proc/update_move_delay()
|
||||
if(!is_train_head() || !on)
|
||||
move_delay = initial(move_delay) //so that engines that have been turned off don't lag behind
|
||||
else
|
||||
move_delay = max(0, (-car_limit * active_engines) + train_length - active_engines) //limits base overweight so you cant overspeed trains
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
msg_admin_attack("[D.name] ([D.ckey]) hit [M.name] ([M.ckey]) with [src]. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)")
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------
|
||||
// Interaction procs
|
||||
//-------------------------------------------
|
||||
@@ -66,8 +67,9 @@
|
||||
return 0
|
||||
|
||||
if(user != load)
|
||||
if(user in src) //for handling players stuck in src
|
||||
unload(user, direction, 1)
|
||||
if(user in src) //for handling players stuck in src - this shouldn't happen - but just in case it does
|
||||
user.loc = T
|
||||
contents -= user
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -80,23 +82,19 @@
|
||||
/obj/vehicle/train/MouseDrop_T(var/atom/movable/C, mob/user as mob)
|
||||
if(!usr.canmove || usr.stat || usr.restrained() || !Adjacent(usr) || !user.Adjacent(C))
|
||||
return
|
||||
|
||||
if(istype(C,/obj/vehicle/train))
|
||||
if(latch(C))
|
||||
user << "\blue You successfully connect the [C] to [src]."
|
||||
else
|
||||
user << "\red You were unable to connect the [C] to [src]."
|
||||
return
|
||||
|
||||
if(!load(C))
|
||||
user << "\red You were unable to load [C] on [src]."
|
||||
latch(C, user)
|
||||
else
|
||||
if(!load(C))
|
||||
user << "\red You were unable to load [C] on [src]."
|
||||
|
||||
/obj/vehicle/train/attack_hand(mob/user as mob)
|
||||
if(!user.canmove || user.stat || user.restrained() || !Adjacent(user))
|
||||
if(user.stat || user.restrained() || !Adjacent(user))
|
||||
return 0
|
||||
|
||||
if(user != load && (user in src))
|
||||
unload(user, null, 1) //for handling players stuck in src
|
||||
user.loc = loc //for handling players stuck in src
|
||||
contents -= user
|
||||
else if(load)
|
||||
unload(user) //unload if loaded
|
||||
else if(!load)
|
||||
@@ -106,74 +104,78 @@
|
||||
|
||||
/obj/vehicle/train/verb/unlatch_v()
|
||||
set name = "Unlatch"
|
||||
set desc = "Unhitches this train from the one in front of it."
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
|
||||
if(!istype(usr, /mob/living/carbon/human))
|
||||
return
|
||||
|
||||
if(!usr.canmove || usr.stat || usr.restrained() || !Adjacent(usr))
|
||||
return
|
||||
|
||||
if(unlatch())
|
||||
usr << "\blue You unlatch [src]."
|
||||
else
|
||||
usr << "\red [src] is already unlatched."
|
||||
unattach(usr)
|
||||
|
||||
|
||||
//-------------------------------------------
|
||||
// Latching/unlatching procs
|
||||
//-------------------------------------------
|
||||
/obj/vehicle/train/proc/latch(var/obj/vehicle/train/T)
|
||||
|
||||
//attempts to attach src as a follower of the train T
|
||||
/obj/vehicle/train/proc/attach_to(obj/vehicle/train/T, mob/user)
|
||||
if (get_dist(src, T) > 1)
|
||||
user << "\red [src] is too far away from [T] to hitch them together."
|
||||
return
|
||||
|
||||
if (lead)
|
||||
user << "\red [src] is already hitched to something."
|
||||
return
|
||||
|
||||
if (T.tow)
|
||||
user << "\red [T] is already towing something."
|
||||
return
|
||||
//latch with src as the follower
|
||||
lead = T
|
||||
T.tow = src
|
||||
dir = lead.dir
|
||||
|
||||
if(user)
|
||||
user << "\blue You hitch [src] to [T]."
|
||||
|
||||
update_stats()
|
||||
|
||||
|
||||
//detaches the train from whatever is towing it
|
||||
/obj/vehicle/train/proc/unattach(mob/user)
|
||||
if (!lead)
|
||||
user << "\red [src] is not hitched to anything."
|
||||
return
|
||||
|
||||
lead.tow = null
|
||||
lead.update_stats()
|
||||
|
||||
user << "\blue You unhitch [src] from [lead]."
|
||||
lead = null
|
||||
|
||||
update_stats()
|
||||
|
||||
/obj/vehicle/train/proc/latch(obj/vehicle/train/T, mob/user)
|
||||
if(!istype(T) || !Adjacent(T))
|
||||
return 0
|
||||
|
||||
/* --- commented out until we get directional sprites ---
|
||||
if(dir != T.dir) //cars need to be inline to latch
|
||||
var/T_dir = get_dir(src, T) //figure out where T is wrt src
|
||||
|
||||
if(dir == T_dir) //if car is ahead
|
||||
src.attach_to(T, user)
|
||||
else if(reverse_direction(dir) == T_dir) //else if car is behind
|
||||
T.attach_to(src, user)
|
||||
|
||||
//returns 1 if this is the lead car of the train
|
||||
/obj/vehicle/train/proc/is_train_head()
|
||||
if (lead)
|
||||
return 0
|
||||
*/
|
||||
|
||||
var/T_dir = get_dir(src, T)
|
||||
|
||||
if(dir & T_dir) //if car is ahead
|
||||
if(!lead && !T.tow)
|
||||
lead = T
|
||||
T.tow = src
|
||||
else
|
||||
return 0
|
||||
else if(reverse_direction(dir) & T_dir) //else if car is behind
|
||||
if(!tow && !T.lead)
|
||||
tow = T
|
||||
T.lead = src
|
||||
else
|
||||
return 0
|
||||
else
|
||||
return 0
|
||||
|
||||
update_stats()
|
||||
|
||||
return 1
|
||||
|
||||
/obj/vehicle/train/proc/unlatch(var/obj/vehicle/train/T)
|
||||
if(!lead && !tow)
|
||||
return 0
|
||||
|
||||
if(T)
|
||||
if(T == tow)
|
||||
tow = null
|
||||
else if(T == lead)
|
||||
lead = null
|
||||
else
|
||||
if(tow)
|
||||
tow.unlatch(src)
|
||||
tow = null
|
||||
if(lead)
|
||||
lead.unlatch(src)
|
||||
lead = null
|
||||
|
||||
update_stats()
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Stat update procs
|
||||
//
|
||||
@@ -182,10 +184,10 @@
|
||||
// size of the train, to limit super long trains.
|
||||
//-------------------------------------------------------
|
||||
/obj/vehicle/train/update_stats()
|
||||
if(!tow)
|
||||
update_train_stats()
|
||||
if(tow)
|
||||
return tow.update_stats() //take us to the very end
|
||||
else
|
||||
return tow.update_stats()
|
||||
update_train_stats() //we're at the end
|
||||
|
||||
/obj/vehicle/train/proc/update_train_stats()
|
||||
if(powered && on)
|
||||
@@ -195,10 +197,10 @@
|
||||
|
||||
train_length = 1
|
||||
|
||||
if(tow)
|
||||
if(istype(tow))
|
||||
active_engines += tow.active_engines
|
||||
train_length += tow.train_length
|
||||
|
||||
//update the next section of train ahead of us
|
||||
if(lead)
|
||||
if(istype(lead))
|
||||
lead.update_train_stats()
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/vehicle
|
||||
name = "vehicle"
|
||||
icon = 'icons/obj/vehicles.dmi'
|
||||
layer = MOB_LAYER
|
||||
layer = MOB_LAYER + 0.1 //so it sits above objects including mobs
|
||||
density = 1
|
||||
anchored = 1
|
||||
animate_movement=1
|
||||
@@ -23,6 +23,7 @@
|
||||
var/obj/item/weapon/cell/cell
|
||||
var/power_use = 5 //set this to adjust the amount of power the vehicle uses per move
|
||||
|
||||
var/standing_mob = 0 //if a mob loaded on the vehicle should be standing
|
||||
var/atom/movable/load //all vehicles can take a load, since they should all be a least drivable
|
||||
var/load_item_visible = 1 //set if the loaded item should be overlayed on the vehicle sprite
|
||||
var/load_offset_x = 0 //pixel_x offset for item overlay
|
||||
@@ -36,7 +37,7 @@
|
||||
//spawn the cell you want in each vehicle
|
||||
|
||||
/obj/vehicle/Move()
|
||||
if(world.timeofday > l_move_time + move_delay)
|
||||
if(world.time > l_move_time + move_delay)
|
||||
if(on && powered && cell.charge < power_use)
|
||||
turn_off()
|
||||
|
||||
@@ -46,6 +47,10 @@
|
||||
if(on && powered)
|
||||
cell.use(power_use)
|
||||
anchored = init_anc
|
||||
|
||||
if(load)
|
||||
load.loc = loc
|
||||
load.dir = dir
|
||||
|
||||
return 1
|
||||
else
|
||||
@@ -262,49 +267,28 @@
|
||||
crate.close()
|
||||
|
||||
C.loc = loc
|
||||
sleep(2)
|
||||
if(C.loc != loc) //To prevent you from going onto more than one train.
|
||||
return 0
|
||||
C.loc = src
|
||||
C.dir = dir
|
||||
C.anchored = 1
|
||||
|
||||
load = C
|
||||
|
||||
if(load_item_visible)
|
||||
C.pixel_x += load_offset_x
|
||||
C.pixel_y += load_offset_y
|
||||
C.layer = layer
|
||||
|
||||
overlays += C
|
||||
|
||||
//we can set these back now since we have already cloned the icon into the overlay
|
||||
C.pixel_x = initial(C.pixel_x)
|
||||
C.pixel_y = initial(C.pixel_y)
|
||||
C.layer = initial(C.layer)
|
||||
C.layer = layer + 0.1 //so it sits above the vehicle
|
||||
|
||||
if(ismob(C))
|
||||
var/mob/M = C
|
||||
if(M.client)
|
||||
M.client.perspective = EYE_PERSPECTIVE
|
||||
M.client.eye = src
|
||||
M.buckled = src
|
||||
M.update_canmove()
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
/obj/vehicle/proc/unload(var/mob/user, var/direction, var/exception = 0)
|
||||
/obj/vehicle/proc/unload(var/mob/user, var/direction)
|
||||
if(!load)
|
||||
// in case non-load items end up in contents, dump everything else too
|
||||
for(var/atom/movable/AM in src)
|
||||
AM.loc = get_turf(src)
|
||||
AM.pixel_x = initial(AM.pixel_x)
|
||||
AM.pixel_y = initial(AM.pixel_y)
|
||||
AM.layer = initial(AM.layer)
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
if(M.client)
|
||||
M.client.perspective = MOB_PERSPECTIVE
|
||||
M.client.eye = src
|
||||
return 0
|
||||
|
||||
return
|
||||
|
||||
var/turf/dest = null
|
||||
|
||||
//find a turf to unload to
|
||||
@@ -332,42 +316,21 @@
|
||||
return 0
|
||||
|
||||
|
||||
if(exception) //for handling any players that end up in src.contents that are trying to climb off
|
||||
user.loc = dest
|
||||
user.pixel_x = initial(user.pixel_x)
|
||||
user.pixel_y = initial(user.pixel_y)
|
||||
user.layer = initial(user.layer)
|
||||
|
||||
if(ismob(user))
|
||||
var/mob/M = user
|
||||
if(M.client)
|
||||
M.client.perspective = MOB_PERSPECTIVE
|
||||
M.client.eye = src
|
||||
|
||||
src.contents -= user
|
||||
|
||||
return 1
|
||||
|
||||
overlays.Cut()
|
||||
|
||||
load.loc = dest
|
||||
|
||||
/*
|
||||
load.dir = get_dir(loc, dest)
|
||||
load.anchored = initial(load.anchored)
|
||||
load.pixel_x = initial(load.pixel_x)
|
||||
load.pixel_y = initial(load.pixel_y)
|
||||
load.layer = initial(load.layer)
|
||||
*/
|
||||
|
||||
if(ismob(load))
|
||||
var/mob/M = load
|
||||
if(M.client)
|
||||
M.client.perspective = MOB_PERSPECTIVE
|
||||
M.client.eye = src
|
||||
M.buckled = null
|
||||
M.anchored = initial(M.anchored)
|
||||
M.update_canmove()
|
||||
|
||||
load = null
|
||||
|
||||
unload() //recursive check for anything left in contents
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
@@ -68,10 +68,11 @@ proc/airborne_can_reach(turf/source, turf/target)
|
||||
if ("[disease.uniqueID]" in M.virus2)
|
||||
return
|
||||
// if one of the antibodies in the mob's body matches one of the disease's antigens, don't infect
|
||||
if(M.antibodies & disease.antigen != 0)
|
||||
if((M.antibodies & disease.antigen) != 0)
|
||||
return
|
||||
if(M.reagents.has_reagent("spaceacillin"))
|
||||
return
|
||||
|
||||
if(istype(M,/mob/living/carbon/monkey))
|
||||
var/mob/living/carbon/monkey/chimp = M
|
||||
if (!(chimp.greaterform in disease.affected_species))
|
||||
|
||||
Reference in New Issue
Block a user