mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 12:41:09 +01:00
Merge remote-tracking branch 'upstream/master' into smoothlattice
This commit is contained in:
@@ -267,144 +267,4 @@ var/pipenetwarnings = 10
|
||||
corresponding = new trace_gas.type()
|
||||
G.trace_gases += corresponding
|
||||
|
||||
corresponding.moles = trace_gas.moles*G.volume/total_volume
|
||||
|
||||
|
||||
/*
|
||||
/datum/pipeline/proc/mingle_with_turf(turf/simulated/target, mingle_volume)
|
||||
var/datum/gas_mixture/air_sample = air.remove_ratio(mingle_volume/air.volume)
|
||||
air_sample.volume = mingle_volume
|
||||
|
||||
var/datum/gas_mixture/turf_air = target.return_air()
|
||||
|
||||
equalize_gases(list(air_sample, turf_air))
|
||||
air.merge(air_sample)
|
||||
//turf_air already modified by equalize_gases()
|
||||
|
||||
if(istype(target))
|
||||
if(target.air)
|
||||
if(target.air.check_tile_graphic())
|
||||
target.update_visuals(target.air)
|
||||
update = 1
|
||||
|
||||
/datum/pipeline/proc/reconcile_air()
|
||||
//Perfectly equalize all gases members instantly
|
||||
|
||||
//Calculate totals from individual components
|
||||
var/total_thermal_energy = 0
|
||||
var/total_heat_capacity = 0
|
||||
var/datum/gas_mixture/air_transient = new()
|
||||
var/list/gases = list(air)
|
||||
gases.Add(other_airs)
|
||||
for(var/datum/gas_mixture/gas in gases)
|
||||
air_transient.volume += gas.volume
|
||||
total_thermal_energy += gas.thermal_energy()
|
||||
total_heat_capacity += gas.heat_capacity()
|
||||
|
||||
air_transient.oxygen += gas.oxygen
|
||||
air_transient.nitrogen += gas.nitrogen
|
||||
air_transient.toxins += gas.toxins
|
||||
air_transient.carbon_dioxide += gas.carbon_dioxide
|
||||
|
||||
if(gas.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in gas.trace_gases)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in air_transient.trace_gases
|
||||
if(!corresponding)
|
||||
corresponding = new trace_gas.type()
|
||||
air_transient.trace_gases += corresponding
|
||||
|
||||
corresponding.moles += trace_gas.moles
|
||||
|
||||
if(air_transient.volume > 0)
|
||||
|
||||
if(total_heat_capacity > 0)
|
||||
air_transient.temperature = total_thermal_energy/total_heat_capacity
|
||||
|
||||
//Allow air mixture to react
|
||||
if(air_transient.react())
|
||||
update = 1
|
||||
|
||||
else
|
||||
air_transient.temperature = 0
|
||||
|
||||
//Update individual gas_mixtures by volume ratio
|
||||
for(var/datum/gas_mixture/gas in gases)
|
||||
gas.oxygen = air_transient.oxygen*gas.volume/air_transient.volume
|
||||
gas.nitrogen = air_transient.nitrogen*gas.volume/air_transient.volume
|
||||
gas.toxins = air_transient.toxins*gas.volume/air_transient.volume
|
||||
gas.carbon_dioxide = air_transient.carbon_dioxide*gas.volume/air_transient.volume
|
||||
|
||||
gas.temperature = air_transient.temperature
|
||||
|
||||
if(air_transient.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in air_transient.trace_gases)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in gas.trace_gases
|
||||
if(!corresponding)
|
||||
corresponding = new trace_gas.type()
|
||||
gas.trace_gases += corresponding
|
||||
|
||||
corresponding.moles = trace_gas.moles*gas.volume/air_transient.volume
|
||||
return 1
|
||||
|
||||
/proc/equalize_gases(datum/gas_mixture/list/gases)
|
||||
//Perfectly equalize all gases members instantly
|
||||
|
||||
//Calculate totals from individual components
|
||||
var/total_volume = 0
|
||||
var/total_thermal_energy = 0
|
||||
var/total_heat_capacity = 0
|
||||
|
||||
var/total_oxygen = 0
|
||||
var/total_nitrogen = 0
|
||||
var/total_toxins = 0
|
||||
var/total_carbon_dioxide = 0
|
||||
|
||||
var/list/total_trace_gases = list()
|
||||
|
||||
for(var/datum/gas_mixture/gas in gases)
|
||||
total_volume += gas.volume
|
||||
total_thermal_energy += gas.thermal_energy()
|
||||
total_heat_capacity += gas.heat_capacity()
|
||||
|
||||
total_oxygen += gas.oxygen
|
||||
total_nitrogen += gas.nitrogen
|
||||
total_toxins += gas.toxins
|
||||
total_carbon_dioxide += gas.carbon_dioxide
|
||||
|
||||
if(gas.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in gas.trace_gases)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in total_trace_gases
|
||||
if(!corresponding)
|
||||
corresponding = new trace_gas.type()
|
||||
total_trace_gases += corresponding
|
||||
|
||||
corresponding.moles += trace_gas.moles
|
||||
|
||||
if(total_volume > 0)
|
||||
|
||||
//Calculate temperature
|
||||
var/temperature = 0
|
||||
|
||||
if(total_heat_capacity > 0)
|
||||
temperature = total_thermal_energy/total_heat_capacity
|
||||
|
||||
//Update individual gas_mixtures by volume ratio
|
||||
for(var/datum/gas_mixture/gas in gases)
|
||||
gas.oxygen = total_oxygen*gas.volume/total_volume
|
||||
gas.nitrogen = total_nitrogen*gas.volume/total_volume
|
||||
gas.toxins = total_toxins*gas.volume/total_volume
|
||||
gas.carbon_dioxide = total_carbon_dioxide*gas.volume/total_volume
|
||||
|
||||
gas.temperature = temperature
|
||||
|
||||
if(total_trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in total_trace_gases)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in gas.trace_gases
|
||||
if(!corresponding)
|
||||
corresponding = new trace_gas.type()
|
||||
gas.trace_gases += corresponding
|
||||
|
||||
corresponding.moles = trace_gas.moles*gas.volume/total_volume
|
||||
|
||||
return 1
|
||||
*/
|
||||
corresponding.moles = trace_gas.moles*G.volume/total_volume
|
||||
@@ -55,18 +55,20 @@
|
||||
|
||||
/turf/simulated/New()
|
||||
..()
|
||||
|
||||
levelupdate()
|
||||
if(smooth)
|
||||
smooth_icon(src)
|
||||
visibilityChanged()
|
||||
if(!blocks_air)
|
||||
air = new
|
||||
|
||||
air.oxygen = oxygen
|
||||
air.carbon_dioxide = carbon_dioxide
|
||||
air.nitrogen = nitrogen
|
||||
air.toxins = toxins
|
||||
|
||||
air.temperature = temperature
|
||||
|
||||
/turf/simulated/Del()
|
||||
visibilityChanged()
|
||||
if(active_hotspot)
|
||||
active_hotspot.Kill()
|
||||
..()
|
||||
|
||||
@@ -23,12 +23,13 @@
|
||||
#define FRIDAY_13TH "Friday the 13th"
|
||||
|
||||
//Human Overlays Indexes/////////
|
||||
#define SPECIES_LAYER 26 // mutantrace colors... these are on a seperate layer in order to prvent
|
||||
#define SPECIES_LAYER 27 // mutantrace colors... these are on a seperate layer in order to prvent
|
||||
#define MUTATIONS_LAYER 26 //mutations. Hulk, Tk headglows, etc
|
||||
#define BODY_BEHIND_LAYER 25
|
||||
#define BODY_LAYER 24 //underwear, undershirts, socks, eyes, lips(makeup)
|
||||
#define BODY_ADJ_LAYER 23
|
||||
#define MUTATIONS_LAYER 22 //Tk headglows etc.
|
||||
#define AUGMENTS_LAYER 21
|
||||
#define AUGMENTS_LAYER 22
|
||||
#define FRONT_MUTATIONS_LAYER 21 //mutations that should appear above body and augments layer (e.g. laser eyes)
|
||||
#define DAMAGE_LAYER 20 //damage indicators (cuts and burns)
|
||||
#define UNIFORM_LAYER 19
|
||||
#define ID_LAYER 18
|
||||
@@ -49,7 +50,7 @@
|
||||
#define R_HAND_LAYER 3 //Having the two hands seperate seems rather silly, merge them together? It'll allow for code to be reused on mobs with arbitarily many hands
|
||||
#define BODY_FRONT_LAYER 2
|
||||
#define FIRE_LAYER 1 //If you're on fire
|
||||
#define TOTAL_LAYERS 26 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
|
||||
#define TOTAL_LAYERS 27 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
|
||||
|
||||
//Human Overlay Index Shortcuts for alternate_worn_layer, layers
|
||||
//Because I *KNOW* somebody will think layer+1 means "above"
|
||||
|
||||
@@ -380,3 +380,56 @@
|
||||
|
||||
return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y)
|
||||
|
||||
/proc/pollCandidates(var/Question, var/jobbanType, var/datum/game_mode/gametypeCheck, var/be_special_flag = 0, var/poll_time = 300)
|
||||
var/list/mob/dead/observer/candidates = list()
|
||||
var/time_passed = world.time
|
||||
if (!Question)
|
||||
Question = "Would you like to be a special role?"
|
||||
|
||||
for(var/mob/dead/observer/G in player_list)
|
||||
if(!G.key || !G.client)
|
||||
continue
|
||||
if(be_special_flag)
|
||||
if(!(G.client.prefs.be_special & be_special_flag))
|
||||
continue
|
||||
if (gametypeCheck)
|
||||
if(!gametypeCheck.age_check(G.client))
|
||||
continue
|
||||
if (jobbanType)
|
||||
if(jobban_isbanned(G, jobbanType) || jobban_isbanned(G, "Syndicate"))
|
||||
continue
|
||||
spawn(0)
|
||||
G << 'sound/misc/notice2.ogg' //Alerting them to their consideration
|
||||
switch(alert(G,Question,"Please answer in [poll_time/10] seconds!","Yes","No"))
|
||||
if("Yes")
|
||||
G << "<span class='notice'>Choice registered: Yes.</span>"
|
||||
if((world.time-time_passed)>poll_time)//If more than 30 game seconds passed.
|
||||
G << "<span class='danger'>Sorry, you were too late for the consideration!</span>"
|
||||
G << 'sound/machines/buzz-sigh.ogg'
|
||||
return
|
||||
candidates += G
|
||||
if("No")
|
||||
G << "<span class='danger'>Choice registered: No.</span>"
|
||||
return
|
||||
else
|
||||
return
|
||||
sleep(poll_time)
|
||||
|
||||
//Check all our candidates, to make sure they didn't log off during the 30 second wait period.
|
||||
for(var/mob/dead/observer/G in candidates)
|
||||
if(!G.key || !G.client)
|
||||
candidates.Remove(G)
|
||||
|
||||
return candidates
|
||||
|
||||
/proc/makeBody(mob/dead/observer/G_found) // Uses stripped down and bastardized code from respawn character
|
||||
if(!G_found || !G_found.key) return
|
||||
|
||||
//First we spawn a dude.
|
||||
var/mob/living/carbon/human/new_character = new(pick(latejoin))//The mob being spawned.
|
||||
|
||||
G_found.client.prefs.copy_to(new_character)
|
||||
new_character.dna.update_dna_identity()
|
||||
new_character.key = G_found.key
|
||||
|
||||
return new_character
|
||||
|
||||
@@ -1415,26 +1415,32 @@ B --><-- A
|
||||
*/
|
||||
|
||||
|
||||
/atom/movable/var/atom/orbiting = null
|
||||
//This is just so you can stop an orbit.
|
||||
//orbit() can run without it (swap orbiting for A)
|
||||
//but then you can never stop it and that's just silly.
|
||||
/atom/movable/var/atom/orbiting = null
|
||||
//we raise this each time orbit is called to prevent mutiple calls in a short time frame from breaking things
|
||||
/atom/movable/var/orbitid = 0
|
||||
|
||||
/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = 1, angle_increment = 15)
|
||||
/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = 1, angle_increment = 15, lockinorbit = 0)
|
||||
if(!istype(A))
|
||||
return
|
||||
orbitid++
|
||||
var/myid = orbitid
|
||||
if (orbiting)
|
||||
stop_orbit()
|
||||
sleep(1) //sadly this is the only way to ensure the original orbit proc stops and resets the atom's transform.
|
||||
if (orbiting || !istype(A)) //post sleep re-check
|
||||
return
|
||||
//sadly this is the only way to ensure the original orbit proc stops and resets the atom's transform.
|
||||
sleep(1)
|
||||
if (orbiting || !istype(A) || orbitid != myid) //post sleep re-check
|
||||
return
|
||||
orbiting = A
|
||||
var/lastloc = loc
|
||||
var/angle = 0
|
||||
var/matrix/initial_transform = matrix(transform)
|
||||
spawn
|
||||
while(orbiting && orbiting.loc)
|
||||
loc = orbiting.loc
|
||||
|
||||
while(orbiting && orbiting.loc && orbitid == myid && (!lockinorbit || loc == lastloc))
|
||||
loc = get_turf(orbiting.loc)
|
||||
lastloc = loc
|
||||
angle += angle_increment
|
||||
|
||||
var/matrix/shift = matrix(initial_transform)
|
||||
@@ -1489,4 +1495,4 @@ B --><-- A
|
||||
I.pixel_x = x_offset
|
||||
I.pixel_y = y_offset
|
||||
|
||||
return I
|
||||
return I
|
||||
|
||||
@@ -14,4 +14,5 @@ var/global/list/chemical_reagents_list //list of all /datum/reagent datums in
|
||||
var/global/list/surgeries_list = list() //list of all surgeries by name, associated with their path.
|
||||
var/global/list/table_recipes = list() //list of all table craft recipes
|
||||
var/global/list/rcd_list = list() //list of Rapid Construction Devices.
|
||||
var/global/list/apcs_list = list() //list of all Area Power Controller machines, seperate from machines for powernet speeeeeeed.
|
||||
var/global/list/apcs_list = list() //list of all Area Power Controller machines, seperate from machines for powernet speeeeeeed.
|
||||
var/global/list/tracking_implants = list() //list of all tracking implants to work out what treks everyone are on. Sadly not on lavaworld not implemented...
|
||||
@@ -5,8 +5,10 @@
|
||||
recieving object instead, so that's the default action. This allows you to drag
|
||||
almost anything into a trash can.
|
||||
*/
|
||||
/atom/MouseDrop(atom/over)
|
||||
/atom/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params)
|
||||
if(!usr || !over) return
|
||||
if(over == src)
|
||||
return usr.client.Click(src, src_location, src_control, params)
|
||||
if(!Adjacent(usr) || !over.Adjacent(usr)) return // should stop you from dragging through windows
|
||||
|
||||
over.MouseDrop_T(src,usr)
|
||||
|
||||
@@ -64,6 +64,8 @@ var/datum/subsystem/events/SSevent
|
||||
for(var/datum/round_event_control/E in control)
|
||||
if(E.occurrences >= E.max_occurrences) continue
|
||||
if(E.earliest_start >= world.time) continue
|
||||
if(ticker.mode.config_tag in E.gamemode_blacklist) continue
|
||||
if(E.gamemode_whitelist && !(ticker.mode.config_tag in E.gamemode_whitelist)) continue
|
||||
if(E.holidayID)
|
||||
if(!holidays || !holidays[E.holidayID]) continue
|
||||
if(E.weight < 0) //for round-start events etc.
|
||||
@@ -81,6 +83,8 @@ var/datum/subsystem/events/SSevent
|
||||
for(var/datum/round_event_control/E in control)
|
||||
if(E.occurrences >= E.max_occurrences) continue
|
||||
if(E.earliest_start >= world.time) continue
|
||||
if(ticker.mode.config_tag in E.gamemode_blacklist) continue
|
||||
if(E.gamemode_whitelist && !(ticker.mode.config_tag in E.gamemode_whitelist)) continue
|
||||
if(E.holidayID)
|
||||
if(!holidays || !holidays[E.holidayID]) continue
|
||||
sum_of_weights -= E.weight
|
||||
|
||||
@@ -15,6 +15,7 @@ var/datum/subsystem/objects/SSobj
|
||||
NEW_SS_GLOBAL(SSobj)
|
||||
|
||||
/datum/subsystem/objects/Initialize(timeofday, zlevel)
|
||||
setupGenetics()
|
||||
for(var/atom/movable/AM in world)
|
||||
if (zlevel && AM.z != zlevel)
|
||||
continue
|
||||
|
||||
@@ -59,7 +59,6 @@ var/datum/subsystem/ticker/ticker
|
||||
return ..()
|
||||
if(!syndicate_code_phrase) syndicate_code_phrase = generate_code_phrase()
|
||||
if(!syndicate_code_response) syndicate_code_response = generate_code_phrase()
|
||||
setupGenetics()
|
||||
setupFactions()
|
||||
..()
|
||||
|
||||
|
||||
@@ -252,6 +252,7 @@
|
||||
body += "<option value='?_src_=vars;direct_control=\ref[D]'>Assume Direct Control</option>"
|
||||
body += "<option value='?_src_=vars;drop_everything=\ref[D]'>Drop Everything</option>"
|
||||
body += "<option value='?_src_=vars;regenerateicons=\ref[D]'>Regenerate Icons</option>"
|
||||
body += "<option value='?_src_=vars;offer_control=\ref[D]'>Offer Control to Ghosts</option>"
|
||||
if(iscarbon(D))
|
||||
body += "<option value>---</option>"
|
||||
body += "<option value='?_src_=vars;editorgans=\ref[D]'>Modify organs</option>"
|
||||
@@ -592,6 +593,29 @@ body
|
||||
if(usr.client)
|
||||
usr.client.cmd_assume_direct_control(M)
|
||||
|
||||
else if(href_list["offer_control"])
|
||||
if(!check_rights(0)) return
|
||||
|
||||
var/mob/M = locate(href_list["offer_control"])
|
||||
if(!istype(M))
|
||||
usr << "This can only be used on instances of type /mob"
|
||||
return
|
||||
M << "Control of your mob has been offered to dead players."
|
||||
log_admin("[key_name(usr)] has offered control of ([key_name(M)]) to ghosts.")
|
||||
message_admins("[key_name_admin(usr)] has offered control of ([key_name_admin(M)]) to ghosts")
|
||||
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as [M.real_name]?", "pAI", null, FALSE, 100)
|
||||
var/mob/dead/observer/theghost = null
|
||||
|
||||
if(candidates.len)
|
||||
theghost = pick(candidates)
|
||||
M << "Your mob has been taken over by a ghost!"
|
||||
message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(M)])")
|
||||
M.ghostize()
|
||||
M.key = theghost.key
|
||||
else
|
||||
M << "There were no ghosts willing to take control."
|
||||
message_admins("No ghosts were willing to take control of [key_name_admin(M)])")
|
||||
|
||||
else if(href_list["delall"])
|
||||
if(!check_rights(R_DEBUG|R_SERVER)) return
|
||||
|
||||
@@ -813,8 +837,7 @@ body
|
||||
|
||||
if(result)
|
||||
var/newtype = species_list[result]
|
||||
hardset_dna(H, null, null, null, null, newtype)
|
||||
H.regenerate_icons()
|
||||
H.set_species(newtype)
|
||||
|
||||
else if(href_list["purrbation"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
@@ -828,7 +851,7 @@ body
|
||||
usr << "Mob doesn't exist anymore"
|
||||
return
|
||||
|
||||
if(H.dna && H.dna.species.id == "human")
|
||||
if(H.dna.species.id == "human")
|
||||
if(H.dna.features["tail_human"] == "None" || H.dna.features["ears"] == "None")
|
||||
usr << "Put [H] on purrbation."
|
||||
H << "You suddenly feel valid."
|
||||
|
||||
@@ -35,6 +35,6 @@ Bonus
|
||||
M << "<span class='notice'>[pick("You feel confused.", "You forgot what you were thinking about.")]</span>"
|
||||
else
|
||||
M << "<span class='notice'>You are unable to think straight!</span>"
|
||||
M.confused = min(100, M.confused + 2)
|
||||
M.confused = min(100, M.confused + 8)
|
||||
|
||||
return
|
||||
|
||||
@@ -31,7 +31,8 @@ Bonus
|
||||
..()
|
||||
if(prob(SYMPTOM_ACTIVATION_PROB * 5)) // 15% chance
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
if(!check_dna_integrity(M)) return
|
||||
if(!M.has_dna())
|
||||
return
|
||||
switch(A.stage)
|
||||
if(4, 5)
|
||||
M << "<span class='notice'>[pick("Your skin feels itchy.", "You feel light headed.")]</span>"
|
||||
@@ -44,7 +45,7 @@ Bonus
|
||||
possible_mutations = (bad_mutations | not_good_mutations) - mutations_list[RACEMUT]
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
if(M)
|
||||
if(!check_dna_integrity(M))
|
||||
if(!M.has_dna())
|
||||
return
|
||||
archived_dna = M.dna.struc_enzymes
|
||||
|
||||
@@ -52,10 +53,10 @@ Bonus
|
||||
/datum/symptom/genetic_mutation/End(datum/disease/advance/A)
|
||||
var/mob/living/carbon/M = A.affected_mob
|
||||
if(M && archived_dna)
|
||||
if(!check_dna_integrity(M))
|
||||
if(!M.has_dna())
|
||||
return
|
||||
hardset_dna(M, se = archived_dna)
|
||||
domutcheck(M)
|
||||
M.dna.struc_enzymes = archived_dna
|
||||
M.domutcheck()
|
||||
/*
|
||||
//////////////////////////////////////
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
affected_mob.adjustToxLoss(2)
|
||||
affected_mob.updatehealth()
|
||||
if(4)
|
||||
if(!src.transformed && !src.carrier)
|
||||
if(!transformed && !carrier)
|
||||
//Save original dna for when the disease is cured.
|
||||
original_dna = new affected_mob.dna.type
|
||||
affected_mob.dna.copy_dna(original_dna)
|
||||
@@ -51,24 +51,22 @@
|
||||
affected_mob << "<span class='danger'>You don't feel like yourself..</span>"
|
||||
var/datum/dna/transform_dna = strain_data["dna"]
|
||||
|
||||
transform_dna.transfer_identity(affected_mob)
|
||||
transform_dna.transfer_identity(affected_mob, transfer_SE = 1)
|
||||
affected_mob.real_name = affected_mob.dna.real_name
|
||||
affected_mob.updateappearance(mutcolor_update=1)
|
||||
affected_mob.domutcheck()
|
||||
|
||||
updateappearance(affected_mob)
|
||||
domutcheck(affected_mob)
|
||||
|
||||
src.transformed = 1
|
||||
src.carrier = 1 //Just chill out at stage 4
|
||||
transformed = 1
|
||||
carrier = 1 //Just chill out at stage 4
|
||||
|
||||
return
|
||||
|
||||
/datum/disease/dnaspread/Del()
|
||||
if (original_dna && transformed && affected_mob)
|
||||
original_dna.transfer_identity(affected_mob)
|
||||
original_dna.transfer_identity(affected_mob, transfer_SE = 1)
|
||||
affected_mob.real_name = affected_mob.dna.real_name
|
||||
|
||||
updateappearance(affected_mob)
|
||||
domutcheck(affected_mob)
|
||||
affected_mob.updateappearance(mutcolor_update=1)
|
||||
affected_mob.domutcheck()
|
||||
|
||||
affected_mob << "<span class='notice'>You feel more like yourself.</span>"
|
||||
..()
|
||||
@@ -201,9 +201,8 @@
|
||||
if(3)
|
||||
if(ishuman(affected_mob))
|
||||
var/mob/living/carbon/human/human = affected_mob
|
||||
if(human.dna && human.dna.species.id != "slime")
|
||||
hardset_dna(human, null, null, null, null, /datum/species/slime)
|
||||
human.regenerate_icons()
|
||||
if(human.dna.species.id != "slime")
|
||||
human.set_species(/datum/species/slime)
|
||||
|
||||
/datum/disease/transformation/corgi
|
||||
name = "The Barkening"
|
||||
|
||||
+13
-31
@@ -27,34 +27,22 @@
|
||||
/datum/martial_art/proc/basic_hit(mob/living/carbon/human/A,mob/living/carbon/human/D)
|
||||
|
||||
A.do_attack_animation(D)
|
||||
var/damage = rand(0,9)
|
||||
var/damage = rand(0,9) + A.dna.species.punchmod
|
||||
|
||||
var/atk_verb = "punch"
|
||||
var/atk_verb = A.dna.species.attack_verb
|
||||
if(D.lying)
|
||||
atk_verb = "kick"
|
||||
else if(A.dna)
|
||||
atk_verb = A.dna.species.attack_verb
|
||||
|
||||
if(A.dna)
|
||||
damage += A.dna.species.punchmod
|
||||
|
||||
if(!damage)
|
||||
if(A.dna)
|
||||
playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1)
|
||||
else
|
||||
playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
D.visible_message("<span class='warning'>[A] has attempted to [atk_verb] [D]!</span>")
|
||||
add_logs(A, D, "attempted to [atk_verb]")
|
||||
return 0
|
||||
playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1)
|
||||
D.visible_message("<span class='warning'>[A] has attempted to [atk_verb] [D]!</span>")
|
||||
add_logs(A, D, "attempted to [atk_verb]")
|
||||
return 0
|
||||
|
||||
var/obj/item/organ/limb/affecting = D.get_organ(ran_zone(A.zone_sel.selecting))
|
||||
var/armor_block = D.run_armor_check(affecting, "melee")
|
||||
|
||||
if(A.dna)
|
||||
playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1)
|
||||
else
|
||||
playsound(D.loc, 'sound/weapons/punch1.ogg', 25, 1, -1)
|
||||
|
||||
playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1)
|
||||
D.visible_message("<span class='danger'>[A] has [atk_verb]ed [D]!</span>", \
|
||||
"<span class='userdanger'>[A] has [atk_verb]ed [D]!</span>")
|
||||
|
||||
@@ -104,24 +92,18 @@
|
||||
|
||||
var/atk_verb = pick("left hook","right hook","straight punch")
|
||||
|
||||
var/damage = rand(5,8)
|
||||
if(A.dna)
|
||||
damage += A.dna.species.punchmod
|
||||
var/damage = rand(5,8) + A.dna.species.punchmod
|
||||
if(!damage)
|
||||
if(A.dna)
|
||||
playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1)
|
||||
else
|
||||
playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
D.visible_message("<span class='warning'>[A] has attempted to hit [D] with a [atk_verb]!</span>")
|
||||
add_logs(A, D, "attempted to hit", atk_verb)
|
||||
return 0
|
||||
playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1)
|
||||
D.visible_message("<span class='warning'>[A] has attempted to hit [D] with a [atk_verb]!</span>")
|
||||
add_logs(A, D, "attempted to hit", atk_verb)
|
||||
return 0
|
||||
|
||||
|
||||
var/obj/item/organ/limb/affecting = D.get_organ(ran_zone(A.zone_sel.selecting))
|
||||
var/armor_block = D.run_armor_check(affecting, "melee")
|
||||
|
||||
playsound(D.loc, 'sound/weapons/punch1.ogg', 25, 1, -1)
|
||||
|
||||
playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1)
|
||||
|
||||
D.visible_message("<span class='danger'>[A] has hit [D] with a [atk_verb]!</span>", \
|
||||
"<span class='userdanger'>[A] has hit [D] with a [atk_verb]!</span>")
|
||||
|
||||
+4
-4
@@ -976,10 +976,10 @@
|
||||
usr << "<span class='danger'>Resetting DNA failed!</span>"
|
||||
else
|
||||
var/mob/living/carbon/C = current
|
||||
C.dna = changeling.first_prof.dna
|
||||
changeling.first_prof.dna.transfer_identity(C, transfer_SE=1)
|
||||
C.real_name = changeling.first_prof.name
|
||||
updateappearance(C)
|
||||
domutcheck(C)
|
||||
C.updateappearance(mutcolor_update=1)
|
||||
C.domutcheck()
|
||||
|
||||
else if (href_list["nuclear"])
|
||||
switch(href_list["nuclear"])
|
||||
@@ -1409,7 +1409,7 @@
|
||||
|
||||
var/mob/living/carbon/human/H = current
|
||||
|
||||
hardset_dna(H,null,null,null,null,/datum/species/abductor,null)
|
||||
H.set_species(/datum/species/abductor)
|
||||
var/datum/species/abductor/S = H.dna.species
|
||||
|
||||
switch(role)
|
||||
|
||||
+52
-22
@@ -16,6 +16,9 @@
|
||||
var/text_gain_indication = ""
|
||||
var/text_lose_indication = ""
|
||||
var/list/visual_indicators = list()
|
||||
var/layer_used = MUTATIONS_LAYER //which mutation layer to use
|
||||
var/list/species_allowed = list() //to restrict mutation to only certain species
|
||||
var/health_req //minimum health required to acquire the mutation
|
||||
|
||||
/datum/mutation/human/proc/force_give(mob/living/carbon/human/owner)
|
||||
set_block(owner)
|
||||
@@ -33,7 +36,7 @@
|
||||
return before + injection + after
|
||||
|
||||
/datum/mutation/human/proc/set_block(mob/living/carbon/owner, on = 1)
|
||||
if(owner && istype(owner) && owner.dna)
|
||||
if(owner && owner.has_dna())
|
||||
owner.dna.struc_enzymes = set_se(owner.dna.struc_enzymes, on)
|
||||
|
||||
/datum/mutation/human/proc/check_block_string(se_string)
|
||||
@@ -51,17 +54,25 @@
|
||||
/datum/mutation/human/proc/on_acquiring(mob/living/carbon/human/owner)
|
||||
if(!owner || !istype(owner) || (src in owner.dna.mutations))
|
||||
return 1
|
||||
if(species_allowed.len && !species_allowed.Find(owner.dna.species.id))
|
||||
return 1
|
||||
if(health_req && owner.health < health_req)
|
||||
return 1
|
||||
owner.dna.mutations.Add(src)
|
||||
owner << text_gain_indication
|
||||
if(text_gain_indication)
|
||||
owner << text_gain_indication
|
||||
if(visual_indicators.len)
|
||||
owner.update_mutation_overlays()
|
||||
var/list/mut_overlay = list(get_visual_indicator(owner))
|
||||
if(owner.overlays_standing[layer_used])
|
||||
mut_overlay = owner.overlays_standing[layer_used]
|
||||
mut_overlay |= get_visual_indicator(owner)
|
||||
owner.remove_overlay(layer_used)
|
||||
owner.overlays_standing[layer_used] = mut_overlay
|
||||
owner.apply_overlay(layer_used)
|
||||
|
||||
/datum/mutation/human/proc/get_visual_indicator(mob/living/carbon/human/owner)
|
||||
return
|
||||
|
||||
/datum/mutation/human/proc/lose_indication(mob/living/carbon/human/owner)
|
||||
owner.overlays.Remove(visual_indicators)
|
||||
|
||||
/datum/mutation/human/proc/on_attack_hand(mob/living/carbon/human/owner, atom/target)
|
||||
return
|
||||
|
||||
@@ -76,9 +87,16 @@
|
||||
|
||||
/datum/mutation/human/proc/on_losing(mob/living/carbon/human/owner)
|
||||
if(owner && istype(owner) && (owner.dna.mutations.Remove(src)))
|
||||
owner << text_lose_indication
|
||||
if(text_lose_indication)
|
||||
owner << text_lose_indication
|
||||
if(visual_indicators.len)
|
||||
owner.update_mutation_overlays()
|
||||
var/list/mut_overlay = list()
|
||||
if(owner.overlays_standing[layer_used])
|
||||
mut_overlay = owner.overlays_standing[layer_used]
|
||||
owner.remove_overlay(layer_used)
|
||||
mut_overlay.Remove(get_visual_indicator(owner))
|
||||
owner.overlays_standing[layer_used] = mut_overlay
|
||||
owner.apply_overlay(layer_used)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -96,6 +114,8 @@
|
||||
get_chance = 15
|
||||
lowest_value = 256 * 12
|
||||
text_gain_indication = "<span class='notice'>Your muscles hurt!</span>"
|
||||
species_allowed = list("human") //no skeleton/lizard hulk
|
||||
health_req = 25
|
||||
|
||||
/datum/mutation/human/hulk/New()
|
||||
..()
|
||||
@@ -583,32 +603,42 @@
|
||||
message = replacetext(message," muh valids "," getting my kicks ")
|
||||
return trim(message)
|
||||
|
||||
|
||||
/datum/mutation/human/laser_eyes
|
||||
|
||||
name = "Laser Eyes"
|
||||
quality = POSITIVE
|
||||
dna_block = NON_SCANNABLE
|
||||
text_gain_indication = "<span class='notice'>You feel pressure building up behind your eyes.</span>"
|
||||
layer_used = FRONT_MUTATIONS_LAYER
|
||||
|
||||
/datum/mutation/human/laser_eyes/New()
|
||||
..()
|
||||
visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="lasereyes_s", "layer"=-FRONT_MUTATIONS_LAYER)
|
||||
|
||||
/datum/mutation/human/laser_eyes/get_visual_indicator(mob/living/carbon/human/owner)
|
||||
return visual_indicators[1]
|
||||
|
||||
/datum/mutation/human/laser_eyes/on_ranged_attack(mob/living/carbon/human/owner, atom/target)
|
||||
if(owner.a_intent == "harm")
|
||||
owner.LaserEyes(target)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/update_mutation_overlays()
|
||||
remove_overlay(MUTATIONS_LAYER)
|
||||
var/image/standing
|
||||
/mob/living/carbon/proc/update_mutations_overlay()
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/update_mutations_overlay()
|
||||
for(var/datum/mutation/human/CM in dna.mutations)
|
||||
if(CM.species_allowed.len && !CM.species_allowed.Find(dna.species.id))
|
||||
CM.force_lose(src) //shouldn't have that mutation at all
|
||||
continue
|
||||
if(CM.visual_indicators.len)
|
||||
var/list/mut_overlay = list()
|
||||
if(overlays_standing[CM.layer_used])
|
||||
mut_overlay = overlays_standing[CM.layer_used]
|
||||
var/image/V = CM.get_visual_indicator(src)
|
||||
if(!standing)
|
||||
standing = V
|
||||
else
|
||||
standing.overlays += V
|
||||
|
||||
if(standing)
|
||||
overlays_standing[MUTATIONS_LAYER] = standing
|
||||
apply_overlay(MUTATIONS_LAYER)
|
||||
|
||||
if(!mut_overlay.Find(V)) //either we lack the visual indicator or we have the wrong one
|
||||
remove_overlay(CM.layer_used)
|
||||
for(var/image/I in CM.visual_indicators)
|
||||
mut_overlay.Remove(I)
|
||||
mut_overlay |= V
|
||||
overlays_standing[CM.layer_used] = mut_overlay
|
||||
apply_overlay(CM.layer_used)
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
/obj/effect/proc_holder/spell/bloodcrawl
|
||||
name = "Blood crawl"
|
||||
desc = "Use blood to travel."
|
||||
charge_max = 10
|
||||
name = "Blood Crawl"
|
||||
desc = "Use pools of blood to phase out of existence."
|
||||
charge_max = 0
|
||||
clothes_req = 0
|
||||
selection_type = "range"
|
||||
range = 1
|
||||
cooldown_min = 0
|
||||
overlay = null
|
||||
action_icon_state = "bloodcrawl"
|
||||
action_background_icon_state = "bg_demon"
|
||||
var/phased = 0
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/choose_targets(mob/user = usr)
|
||||
@@ -16,7 +17,7 @@
|
||||
perform(target)
|
||||
return
|
||||
revert_cast()
|
||||
user << "<span class='warning'>You need blood to blood crawl.</span>"
|
||||
user << "<span class='warning'>There must be a nearby source of blood!</span>"
|
||||
|
||||
/obj/effect/proc_holder/spell/bloodcrawl/perform(obj/effect/decal/cleanable/target, recharge = 1, mob/living/user = usr)
|
||||
if(istype(user))
|
||||
@@ -24,9 +25,9 @@
|
||||
if(user.phasein(target))
|
||||
phased = 0
|
||||
else
|
||||
user.phaseout(target)
|
||||
phased = 1
|
||||
if(user.phaseout(target))
|
||||
phased = 1
|
||||
start_recharge()
|
||||
return
|
||||
revert_cast()
|
||||
user << "<span class='warning'>You cannot blood crawl.</span>"
|
||||
user << "<span class='warning'>You are unable to blood crawl!</span>"
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
lich.real_name = user.mind.name
|
||||
user.mind.transfer_to(lich)
|
||||
hardset_dna(lich,null,null,lich.real_name,null,/datum/species/skeleton)
|
||||
lich.hardset_dna(null,null,lich.real_name,null,/datum/species/skeleton)
|
||||
lich << "<span class='warning'>Your bones clatter and shutter as they're pulled back into this world!</span>"
|
||||
charge_max += 600
|
||||
var/mob/old_body = current_body
|
||||
@@ -98,7 +98,7 @@
|
||||
marked_item.desc = "A terrible aura surrounds this item, its very existence is offensive to life itself..."
|
||||
marked_item.color = "#003300"
|
||||
user << "<span class='userdanger'>With a hideous feeling of emptiness you watch in horrified fascination as skin sloughs off bone! Blood boils, nerves disintegrate, eyes boil in their sockets! As your organs crumble to dust in your fleshless chest you come to terms with your choice. You're a lich!</span>"
|
||||
hardset_dna(user, null, null, null, null, /datum/species/skeleton)
|
||||
user.set_species(/datum/species/skeleton)
|
||||
current_body = user.mind.current
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
clothes_req = 1
|
||||
invocation = "BIRUZ BENNAR"
|
||||
invocation_type = "shout"
|
||||
message = "<span class='notice'>You feel strong! You feel a pressure building behind your eyes!</span>"
|
||||
range = -1
|
||||
include_user = 1
|
||||
centcom_cancast = 0
|
||||
@@ -248,7 +247,7 @@
|
||||
sound="sound/magic/Blind.ogg"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/genetic/blind
|
||||
disabilities = 1
|
||||
disabilities = BLIND
|
||||
duration = 300
|
||||
sound="sound/magic/Blind.ogg"
|
||||
|
||||
|
||||
+3
-3
@@ -280,11 +280,11 @@ var/list/blood_splatter_icons = list()
|
||||
|
||||
//returns 1 if made bloody, returns 0 otherwise
|
||||
/atom/proc/add_blood(mob/living/carbon/M)
|
||||
if(ishuman(M) && M.dna)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(NOBLOOD in H.dna.species.specflags)
|
||||
return 0
|
||||
if(rejects_blood() || !istype(M) || !check_dna_integrity(M))
|
||||
if(rejects_blood() || !M.has_dna())
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -358,7 +358,7 @@ var/list/blood_splatter_icons = list()
|
||||
// Only adds blood on the floor -- Skie
|
||||
/atom/proc/add_blood_floor(mob/living/carbon/M)
|
||||
if(istype(src, /turf/simulated))
|
||||
if(check_dna_integrity(M)) //mobs with dna = (monkeys + humans at time of writing)
|
||||
if(M.has_dna()) //mobs with dna = (monkeys + humans at time of writing)
|
||||
var/obj/effect/decal/cleanable/blood/B = locate() in contents
|
||||
if(!B)
|
||||
blood_splatter(src,M,1)
|
||||
|
||||
+175
-809
File diff suppressed because it is too large
Load Diff
@@ -107,7 +107,7 @@
|
||||
H = agent.current
|
||||
L = agent_landmarks[team_number]
|
||||
H.loc = L.loc
|
||||
hardset_dna(H, null, null, null, null, /datum/species/abductor)
|
||||
H.set_species(/datum/species/abductor)
|
||||
S = H.dna.species
|
||||
S.agent = 1
|
||||
S.team = team_number
|
||||
@@ -115,13 +115,12 @@
|
||||
equip_common(H,team_number)
|
||||
equip_agent(H,team_number)
|
||||
greet_agent(agent,team_number)
|
||||
H.regenerate_icons()
|
||||
|
||||
scientist = scientists[team_number]
|
||||
H = scientist.current
|
||||
L = scientist_landmarks[team_number]
|
||||
H.loc = L.loc
|
||||
hardset_dna(H, null, null, null, null, /datum/species/abductor)
|
||||
H.set_species(/datum/species/abductor)
|
||||
S = H.dna.species
|
||||
S.scientist = 1
|
||||
S.team = team_number
|
||||
@@ -129,7 +128,6 @@
|
||||
equip_common(H,team_number)
|
||||
equip_scientist(H,team_number)
|
||||
greet_scientist(scientist,team_number)
|
||||
H.regenerate_icons()
|
||||
return ..()
|
||||
|
||||
//Used for create antag buttons
|
||||
@@ -156,7 +154,7 @@
|
||||
H = agent.current
|
||||
L = agent_landmarks[team_number]
|
||||
H.loc = L.loc
|
||||
hardset_dna(H, null, null, null, null, /datum/species/abductor)
|
||||
H.set_species(/datum/species/abductor)
|
||||
S = H.dna.species
|
||||
S.agent = 1
|
||||
S.team = team_number
|
||||
@@ -164,13 +162,13 @@
|
||||
equip_common(H,team_number)
|
||||
equip_agent(H,team_number)
|
||||
greet_agent(agent,team_number)
|
||||
H.regenerate_icons()
|
||||
|
||||
|
||||
scientist = scientists[team_number]
|
||||
H = scientist.current
|
||||
L = scientist_landmarks[team_number]
|
||||
H.loc = L.loc
|
||||
hardset_dna(H, null, null, null, null, /datum/species/abductor)
|
||||
H.set_species(/datum/species/abductor)
|
||||
S = H.dna.species
|
||||
S.scientist = 1
|
||||
S.team = team_number
|
||||
@@ -178,7 +176,7 @@
|
||||
equip_common(H,team_number)
|
||||
equip_scientist(H,team_number)
|
||||
greet_scientist(scientist,team_number)
|
||||
H.regenerate_icons()
|
||||
|
||||
|
||||
|
||||
/datum/game_mode/abduction/proc/greet_agent(datum/mind/abductor,team_number)
|
||||
@@ -332,7 +330,7 @@
|
||||
if(!owner.current || !ishuman(owner.current))
|
||||
return 0
|
||||
var/mob/living/carbon/human/H = owner.current
|
||||
if(!H.dna || !H.dna.species || !(H.dna.species.id == "abductor"))
|
||||
if(H.dna.species.id != "abductor")
|
||||
return 0
|
||||
var/datum/species/abductor/S = H.dna.species
|
||||
ab_team = S.team
|
||||
|
||||
@@ -288,7 +288,7 @@
|
||||
var/obj/machinery/abductor/console/console
|
||||
if(ishuman(source))
|
||||
var/mob/living/carbon/human/H = source
|
||||
if(H.dna && istype(H.dna.species, /datum/species/abductor))
|
||||
if(H.dna.species.id == "abductor")
|
||||
var/datum/species/abductor/S = H.dna.species
|
||||
console = get_team_console(S.team)
|
||||
home = console.pad
|
||||
@@ -405,8 +405,6 @@ Congratulations! You are now trained for xenobiology research!"}
|
||||
if(!ishuman(user))
|
||||
return 0
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!H.dna)
|
||||
return 0
|
||||
if(H.dna.species.id != "abductor")
|
||||
return 0
|
||||
return 1
|
||||
@@ -460,11 +458,16 @@ Congratulations! You are now trained for xenobiology research!"}
|
||||
/obj/item/weapon/abductor_baton/proc/SleepAttack(mob/living/L,mob/living/user)
|
||||
if(L.stunned)
|
||||
L.SetSleeping(60)
|
||||
L.visible_message("<span class='danger'>[user] has induced sleep in [L] with [src]!</span>", \
|
||||
L.visible_message("<span class='danger'>[user] has induced sleep in [L] with [src]!</span>", \
|
||||
"<span class='userdanger'>You suddenly feel very drowsy!</span>")
|
||||
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
|
||||
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
|
||||
|
||||
add_logs(user, L, "put to sleep")
|
||||
add_logs(user, L, "put to sleep")
|
||||
else
|
||||
L.drowsyness += 1
|
||||
user << "<span class='warning'>Sleep inducement works fully only on stunned specimens! </span>"
|
||||
L.visible_message("<span class='danger'>[user] tried to induce sleep in [L] with [src]!</span>", \
|
||||
"<span class='userdanger'>You suddenly feel drowsy!</span>")
|
||||
return
|
||||
|
||||
/obj/item/weapon/abductor_baton/proc/CuffAttack(mob/living/L,mob/living/user)
|
||||
@@ -490,13 +493,21 @@ Congratulations! You are now trained for xenobiology research!"}
|
||||
"<span class='userdanger'>[user] probes you!</span>")
|
||||
|
||||
var/species = "<span class='warning'>Unknown species</span>"
|
||||
var/helptext = "<span class='warning'>Species unsuitable for experiments.</span>"
|
||||
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
if(H.dna && H.dna.species)
|
||||
species = "<span clas=='notice'>[H.dna.species.name]</span>"
|
||||
species = "<span clas=='notice'>[H.dna.species.name]</span>"
|
||||
if(L.mind && L.mind.changeling)
|
||||
species = "<span class='warning'>Changeling lifeform</span>"
|
||||
var/obj/item/organ/internal/gland/temp = locate() in H.internal_organs
|
||||
if(temp)
|
||||
helptext = "<span class='warning'>Experimental gland detected!</span>"
|
||||
else
|
||||
helptext = "<span class='notice'>Subject suitable for experiments.</span>"
|
||||
|
||||
user << "<span class='notice'>Probing result:</span>[species]"
|
||||
user << "[helptext]"
|
||||
|
||||
/obj/item/weapon/restraints/handcuffs/energy
|
||||
name = "hard-light energy field"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
if(!ishuman(user))
|
||||
return 0
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.dna && istype(H.dna.species, /datum/species/abductor))
|
||||
if(H.dna.species.id == "abductor")
|
||||
return 1
|
||||
if((locate(/obj/item/weapon/implant/abductor) in H))
|
||||
return 1
|
||||
|
||||
@@ -120,9 +120,7 @@
|
||||
/obj/item/organ/internal/gland/pop/activate()
|
||||
owner << "<span class='notice'>You feel unlike yourself.</span>"
|
||||
var/species = pick(list(/datum/species/lizard,/datum/species/slime,/datum/species/plant/pod,/datum/species/fly))
|
||||
hardset_dna(owner, null, null, null, null, species)
|
||||
owner.regenerate_icons()
|
||||
return
|
||||
owner.set_species(species)
|
||||
|
||||
/obj/item/organ/internal/gland/ventcrawling
|
||||
origin_tech = "materials=4;biotech=5;bluespace=3"
|
||||
@@ -241,7 +239,7 @@
|
||||
|
||||
/obj/effect/cocoon/abductor/proc/Copy(mob/living/carbon/human/H)
|
||||
var/mob/living/carbon/human/interactive/greytide/clone = new(src)
|
||||
hardset_dna(clone,H.dna.uni_identity,H.dna.struc_enzymes,H.real_name, H.dna.blood_type, H.dna.species.type, H.dna.features)
|
||||
clone.hardset_dna(H.dna.uni_identity,H.dna.struc_enzymes,H.real_name, H.dna.blood_type, H.dna.species.type, H.dna.features)
|
||||
|
||||
//There's no define for this / get all items ?
|
||||
var/list/slots = list(slot_back,slot_w_uniform,slot_wear_suit,\
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
var/team = 0
|
||||
|
||||
/obj/machinery/abductor/proc/IsAbductor(mob/living/carbon/human/H)
|
||||
if(!H.dna)
|
||||
return 0
|
||||
return H.dna.species.id == "abductor"
|
||||
|
||||
/obj/machinery/abductor/proc/IsAgent(mob/living/carbon/human/H)
|
||||
|
||||
@@ -98,6 +98,7 @@
|
||||
M.mind.name = newname
|
||||
M.real_name = newname
|
||||
M.name = newname
|
||||
M.dna.update_dna_identity()
|
||||
var/datum/objective/protect/new_objective = new /datum/objective/protect
|
||||
new_objective.owner = M:mind
|
||||
new_objective:target = usr:mind
|
||||
|
||||
@@ -346,7 +346,8 @@ var/list/slot2type = list("head" = /obj/item/clothing/head/changeling, "wear_mas
|
||||
return
|
||||
if(has_dna(target.dna))
|
||||
user << "<span class='warning'>We already have this DNA in storage!</span>"
|
||||
if(!check_dna_integrity(target))
|
||||
return
|
||||
if(!target.has_dna())
|
||||
user << "<span class='warning'>[target] is not compatible with our biology.</span>"
|
||||
return
|
||||
return 1
|
||||
@@ -405,10 +406,9 @@ var/list/slot2type = list("head" = /obj/item/clothing/head/changeling, "wear_mas
|
||||
/proc/changeling_transform(var/mob/living/carbon/human/user, var/datum/changelingprofile/chosen_prof)
|
||||
var/datum/dna/chosen_dna = chosen_prof.dna
|
||||
user.real_name = chosen_prof.name
|
||||
user.dna = chosen_dna
|
||||
hardset_dna(user, null, null, null, null, chosen_dna.species.type, chosen_dna.features)
|
||||
domutcheck(user)
|
||||
updateappearance(user)
|
||||
chosen_dna.transfer_identity(user, 1)
|
||||
user.updateappearance(mutcolor_update=1)
|
||||
user.domutcheck()
|
||||
|
||||
//vars hackery. not pretty, but better than the alternative.
|
||||
for(var/slot in slots)
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
/obj/effect/proc_holder/changeling/proc/on_purchase(mob/user)
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/changeling/proc/on_refund(mob/user)
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/changeling/Click()
|
||||
var/mob/user = usr
|
||||
if(!user || !user.mind || !user.mind.changeling)
|
||||
|
||||
@@ -388,16 +388,13 @@ var/list/sting_paths
|
||||
/mob/proc/remove_changeling_powers(keep_free_powers=0)
|
||||
if(ishuman(src) || ismonkey(src))
|
||||
if(mind && mind.changeling)
|
||||
digitalcamo = 0
|
||||
digitalinvis = 0
|
||||
mind.changeling.changeling_speak = 0
|
||||
mind.changeling.reset()
|
||||
for(var/obj/effect/proc_holder/changeling/p in mind.changeling.purchasedpowers)
|
||||
if(!(p.dna_cost == 0 && keep_free_powers))
|
||||
mind.changeling.purchasedpowers -= p
|
||||
if(istype(p,/obj/effect/proc_holder/changeling/augmented_eyesight))
|
||||
permanent_sight_flags -= SEE_MOBS
|
||||
sight -= SEE_MOBS
|
||||
if(p.dna_cost == 0 && keep_free_powers)
|
||||
continue
|
||||
mind.changeling.purchasedpowers -= p
|
||||
p.on_refund(src)
|
||||
if(hud_used)
|
||||
hud_used.lingstingdisplay.icon_state = null
|
||||
hud_used.lingstingdisplay.invisibility = 101
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
if((target.disabilities & NOCLONE) || (target.disabilities & HUSK))
|
||||
user << "<span class='warning'>DNA of [target] is ruined beyond usability!</span>"
|
||||
return
|
||||
if(!check_dna_integrity(target) || !ishuman(target))
|
||||
if(!ishuman(target))
|
||||
user << "<span class='warning'>[target] is not compatible with this ability.</span>"
|
||||
return
|
||||
return 1
|
||||
|
||||
@@ -28,3 +28,8 @@
|
||||
user.see_in_dark = 0
|
||||
user.dna.species.invis_sight = initial(user.dna.species.invis_sight)
|
||||
return 1
|
||||
|
||||
|
||||
/obj/effect/proc_holder/changeling/augmented_eyesight/on_refund(mob/user)
|
||||
user.permanent_sight_flags &= ~SEE_MOBS
|
||||
user.sight &= ~SEE_MOBS
|
||||
@@ -10,17 +10,21 @@
|
||||
|
||||
|
||||
/obj/effect/proc_holder/changeling/chameleon_skin/sting_action(mob/user)
|
||||
var/mob/living/carbon/human/H = user //SHOULD always be human, because req_human = 1
|
||||
if(!istype(H))
|
||||
var/mob/living/carbon/human/H = user //SHOULD always be human, because req_human = 1 //phil235 so why is it needd?
|
||||
if(!istype(H)) // req_human could be done in can_sting stuff.
|
||||
return
|
||||
var/datum/mutation/human/HM = mutations_list[CHAMELEON]
|
||||
if(H.dna && H.dna.mutations)
|
||||
if(HM in H.dna.mutations)
|
||||
HM.force_lose(H)
|
||||
else
|
||||
HM.force_give(H)
|
||||
if(HM in H.dna.mutations)
|
||||
HM.force_lose(H)
|
||||
else
|
||||
HM.force_give(H)
|
||||
|
||||
feedback_add_details("changeling_powers","CS")
|
||||
return 1
|
||||
|
||||
|
||||
/obj/effect/proc_holder/changeling/chameleon_skin/on_refund(mob/user)
|
||||
if(user.has_dna())
|
||||
var/mob/living/carbon/C = user
|
||||
var/datum/mutation/human/HM = mutations_list[CHAMELEON]
|
||||
if(HM in C.dna.mutations)
|
||||
HM.force_lose(C)
|
||||
@@ -18,3 +18,7 @@
|
||||
|
||||
feedback_add_details("changeling_powers","CAM")
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/changeling/digitalcamo/on_refund(mob/user)
|
||||
user.digitalcamo = 0
|
||||
user.digitalinvis = 0
|
||||
@@ -24,12 +24,11 @@
|
||||
if(!user || user.notransform)
|
||||
return 0
|
||||
user << "<span class='notice'>We transform our appearance.</span>"
|
||||
|
||||
user.humanize((TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPSRC), chosen_prof.name)
|
||||
|
||||
changeling_transform(user, chosen_prof)
|
||||
|
||||
changeling.purchasedpowers -= src
|
||||
|
||||
var/newmob = user.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS)
|
||||
|
||||
changeling_transform(newmob, chosen_prof)
|
||||
feedback_add_details("changeling_powers","LFT")
|
||||
qdel(user)
|
||||
return 1
|
||||
|
||||
@@ -12,9 +12,7 @@
|
||||
return 0
|
||||
user << "<span class='warning'>Our genes cry out!</span>"
|
||||
|
||||
user.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPSE | TR_KEEPSRC)
|
||||
user.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE)
|
||||
|
||||
// Human-form power now handled in monkeyize()
|
||||
feedback_add_details("changeling_powers","LF")
|
||||
.=1
|
||||
qdel(user)
|
||||
return 1
|
||||
@@ -21,20 +21,23 @@
|
||||
var/weapon_name_simple
|
||||
|
||||
/obj/effect/proc_holder/changeling/weapon/try_to_sting(mob/user, mob/target)
|
||||
if(istype(user.l_hand, weapon_type)) //Not the nicest way to do it, but eh
|
||||
playsound(user, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
qdel(user.l_hand)
|
||||
user.visible_message("<span class='warning'>With a sickening crunch, [user] reforms their [weapon_name_simple] into an arm!</span>", "<span class='notice'>We assimilate the [weapon_name_simple] back into our body.</span>", "<span class='italics>You hear organic matter ripping and tearing!</span>")
|
||||
user.update_inv_l_hand()
|
||||
if(check_weapon(user, user.r_hand, 1))
|
||||
return
|
||||
if(istype(user.r_hand, weapon_type))
|
||||
playsound(user, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
qdel(user.r_hand)
|
||||
user.visible_message("<span class='warning'>With a sickening crunch, [user] reforms their [weapon_name_simple] into an arm!</span>", "<span class='notice'>We assimilate the [weapon_name_simple] back into our body.</span>", "<span class='italics>You hear organic matter ripping and tearing!</span>")
|
||||
user.update_inv_r_hand()
|
||||
if(check_weapon(user, user.l_hand, 0))
|
||||
return
|
||||
..(user, target)
|
||||
|
||||
/obj/effect/proc_holder/changeling/weapon/proc/check_weapon(mob/user, obj/item/hand_item, right_hand=1)
|
||||
if(istype(hand_item, weapon_type))
|
||||
playsound(user, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
qdel(hand_item)
|
||||
user.visible_message("<span class='warning'>With a sickening crunch, [user] reforms their [weapon_name_simple] into an arm!</span>", "<span class='notice'>We assimilate the [weapon_name_simple] back into our body.</span>", "<span class='italics>You hear organic matter ripping and tearing!</span>")
|
||||
if(right_hand)
|
||||
user.update_inv_r_hand()
|
||||
else
|
||||
user.update_inv_l_hand()
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/changeling/weapon/sting_action(mob/user)
|
||||
if(!user.drop_item())
|
||||
user << "<span class='warning'>The [user.get_active_hand()] is stuck to your hand, you cannot grow a [weapon_name_simple] over it!</span>"
|
||||
@@ -44,6 +47,10 @@
|
||||
playsound(user, 'sound/effects/blobattack.ogg', 30, 1)
|
||||
return W
|
||||
|
||||
/obj/effect/proc_holder/changeling/weapon/on_refund(mob/user)
|
||||
check_weapon(user, user.r_hand, 1)
|
||||
check_weapon(user, user.l_hand, 0)
|
||||
|
||||
//Parent to space suits and armor.
|
||||
/obj/effect/proc_holder/changeling/suit
|
||||
name = "Organic Suit"
|
||||
@@ -61,10 +68,16 @@
|
||||
var/blood_on_castoff = 0
|
||||
|
||||
/obj/effect/proc_holder/changeling/suit/try_to_sting(mob/user, mob/target)
|
||||
if(check_suit(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
..(H, target)
|
||||
|
||||
//checks if we already have an organic suit and casts it off.
|
||||
/obj/effect/proc_holder/changeling/suit/proc/check_suit(mob/user)
|
||||
var/datum/changeling/changeling = user.mind.changeling
|
||||
if(!ishuman(user) || !changeling)
|
||||
return
|
||||
|
||||
return 1
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(istype(H.wear_suit, suit_type) || istype(H.head, helmet_type))
|
||||
H.visible_message("<span class='warning'>[H] casts off their [suit_name_simple]!</span>", "<span class='warning'>We cast off our [suit_name_simple][genetic_damage > 0 ? ", temporarily weakening our genomes." : "."]</span>", "<span class='italics'>You hear the organic matter ripping and tearing!</span>")
|
||||
@@ -82,8 +95,13 @@
|
||||
|
||||
changeling.geneticdamage += genetic_damage //Casting off a space suit leaves you weak for a few seconds.
|
||||
changeling.chem_recharge_slowdown -= recharge_slowdown
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/changeling/suit/on_refund(mob/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
..(H, target)
|
||||
var/mob/living/carbon/human/H = user
|
||||
check_suit(H)
|
||||
|
||||
/obj/effect/proc_holder/changeling/suit/sting_action(mob/living/carbon/human/user)
|
||||
if(!user.canUnEquip(user.wear_suit))
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
for(var/datum/disease/D in user.viruses)
|
||||
D.cure()
|
||||
|
||||
for(var/obj/item/organ/internal/I in user)
|
||||
if(istype(I,/obj/item/organ/internal/body_egg/alien_embryo))
|
||||
I.Remove(user)
|
||||
I.loc = get_turf(user)
|
||||
feedback_add_details("changeling_powers","AP")
|
||||
return 1
|
||||
@@ -12,7 +12,7 @@
|
||||
if(iscarbon(M))
|
||||
if(!M.mind || !M.mind.changeling)
|
||||
M.adjustEarDamage(0,30)
|
||||
M.confused += 20
|
||||
M.confused += 25
|
||||
M.Jitter(50)
|
||||
else
|
||||
M << sound('sound/effects/screech.ogg')
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
/obj/effect/proc_holder/changeling/sting/transformation/can_sting(mob/user, mob/target)
|
||||
if(!..())
|
||||
return
|
||||
if((target.disabilities & HUSK) || !check_dna_integrity(target))
|
||||
if((target.disabilities & HUSK) || !target.has_dna())
|
||||
user << "<span class='warning'>Our sting appears ineffective against its DNA.</span>"
|
||||
return 0
|
||||
return 1
|
||||
@@ -92,15 +92,17 @@
|
||||
if(ismonkey(target))
|
||||
user << "<span class='notice'>Our genes cry out as we sting [target.name]!</span>"
|
||||
|
||||
if(iscarbon(target) && (target.status_flags & CANWEAKEN))
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
C.do_jitter_animation(500)
|
||||
C.take_organ_damage(20, 0) //The process is extremely painful
|
||||
if(C.status_flags & CANWEAKEN)
|
||||
C.do_jitter_animation(500)
|
||||
C.take_organ_damage(20, 0) //The process is extremely painful
|
||||
|
||||
target.visible_message("<span class='danger'>[target] begins to violenty convulse!</span>","<span class='userdanger'>You feel a tiny prick and a begin to uncontrollably convulse!</span>")
|
||||
spawn(10)
|
||||
hardset_dna(target, NewDNA.uni_identity, NewDNA.struc_enzymes, NewDNA.real_name, NewDNA.blood_type, NewDNA.species.type, NewDNA.features)
|
||||
updateappearance(target)
|
||||
target.visible_message("<span class='danger'>[target] begins to violenty convulse!</span>","<span class='userdanger'>You feel a tiny prick and a begin to uncontrollably convulse!</span>")
|
||||
spawn(10)
|
||||
NewDNA.transfer_identity(C, transfer_SE=1)
|
||||
C.updateappearance(mutcolor_update=1)
|
||||
C.domutcheck()
|
||||
feedback_add_details("changeling_powers","TS")
|
||||
return 1
|
||||
|
||||
@@ -125,7 +127,7 @@
|
||||
/obj/effect/proc_holder/changeling/sting/false_armblade/can_sting(mob/user, mob/target)
|
||||
if(!..())
|
||||
return
|
||||
if((target.disabilities & HUSK) || !check_dna_integrity(target))
|
||||
if((target.disabilities & HUSK) || !target.has_dna())
|
||||
user << "<span class='warning'>Our sting appears ineffective against its DNA.</span>"
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -92,7 +92,8 @@
|
||||
if(config.protect_assistant_from_antagonist)
|
||||
restricted_jobs += "Assistant"
|
||||
|
||||
acolytes_needed = max(2, round(num_players()/5)) //Scales the escape requirement with the amount of people in the round
|
||||
acolytes_needed = round(num_players()/5,1) //Scales the escape requirement with the amount of people in the round; for every 5 players, one cultist added to the count, i.e. 25 players = 5 to escape
|
||||
acolytes_needed = Clamp(acolytes_needed, 1, 15) //Max at 15 and minimum at 1 - before the update, people rarely got even 15
|
||||
|
||||
for(var/cultists_number = 1 to recommended_enemies)
|
||||
if(!antag_candidates.len)
|
||||
@@ -141,11 +142,11 @@
|
||||
explanation = "Our knowledge must live on. Make sure at least [acolytes_needed] acolytes escape on the shuttle to spread their work on an another station."
|
||||
if("sacrifice")
|
||||
if(sacrifice_target)
|
||||
explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. You will need the Rite of Tribute and three acolytes to do so."
|
||||
explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. You will need the Sacrifice rune and three acolytes to do so."
|
||||
else
|
||||
explanation = "Free objective."
|
||||
if("eldergod")
|
||||
explanation = "Summon Nar-Sie via the use of the Ritual of Dimensional Rending. It will only work if nine cultists stand on and around it."
|
||||
explanation = "Summon Nar-Sie via the rune 'Call Forth The Geometer'. It will only work if nine acolytes stand on and around it."
|
||||
cult_mind.current << "<B>Objective #[obj_count]</B>: [explanation]"
|
||||
cult_mind.memory += "<B>Objective #[obj_count]</B>: [explanation]<BR>"
|
||||
|
||||
@@ -171,7 +172,7 @@
|
||||
if(!where)
|
||||
mob << "Unfortunately, you weren't able to get a talisman. This is very bad and you should adminhelp immediately."
|
||||
else
|
||||
mob << "You have a talisman in your [where], one that will help you start the cult on this station. Use it well, and remember - you are not the only one."
|
||||
mob << "<span class='danger'>You have a talisman in your [where], one that will help you start the cult on this station. Use it well, and remember - you are not the only one.</span>"
|
||||
mob.update_icons()
|
||||
if(where == "backpack")
|
||||
var/obj/item/weapon/storage/B = mob.back
|
||||
@@ -203,13 +204,13 @@
|
||||
cult -= cult_mind
|
||||
cult_mind.current.verbs -= /mob/living/proc/cult_innate_comm
|
||||
cult_mind.current.Paralyse(5)
|
||||
cult_mind.current << "<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of the dark-one and the memories of your time as his servant with it.</span>"
|
||||
cult_mind.current << "<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of the Dark One and all your memories as its servant.</span>"
|
||||
cult_mind.memory = ""
|
||||
update_cult_icons_removed(cult_mind)
|
||||
cult_mind.current.attack_log += "\[[time_stamp()]\] <span class='danger'>Has renounced the cult!</span>"
|
||||
if(show_message)
|
||||
for(var/mob/M in viewers(cult_mind.current))
|
||||
M << "<FONT size = 3>[cult_mind.current] looks like they just reverted to their old faith!</FONT>"
|
||||
M << "<span class='big'>[cult_mind.current] looks like they just reverted to their old faith!</span>"
|
||||
|
||||
/datum/game_mode/proc/update_cult_icons_added(datum/mind/cult_mind)
|
||||
var/datum/atom_hud/antag/culthud = huds[ANTAG_HUD_CULT]
|
||||
@@ -259,7 +260,7 @@
|
||||
if(!check_cult_victory())
|
||||
feedback_set_details("round_end_result","win - cult win")
|
||||
feedback_set("round_end_result",acolytes_survived)
|
||||
world << "<span class='redtext'>The cult wins! It has succeeded in serving its dark masters!</span>"
|
||||
world << "<span class='greentext'>The cult wins! It has succeeded in serving its dark master!</span>"
|
||||
else
|
||||
feedback_set_details("round_end_result","loss - staff stopped the cult")
|
||||
feedback_set("round_end_result",acolytes_survived)
|
||||
|
||||
@@ -138,83 +138,82 @@ It also contains rune words, which are soon to be removed.
|
||||
<i>Rite of Knowledge:</i> \"karazet nahlizet ego\"<br>\
|
||||
<br><br><br>"*/
|
||||
|
||||
text += "<font color='red'><b>Rite of Translocation</b></font><br>The Rite of Translocation is a unique rite in that it requires a keyword before the scribing can begin. When invoked, the rune will \
|
||||
text += "<font color='red'><b>Teleport</b></font><br>The Rite of Translocation is a unique rite in that it requires a keyword before the scribing can begin. When invoked, the rune will \
|
||||
search for other Rites of Translocation with the same keyword. Assuming one is found, the user will be instantaneously transported to the location of the other rune. If more than two runes are scribed \
|
||||
with the same keyword, it will choose randomly between all eligible runes and send the invoker to one of them.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of Forced Translocation</b></font><br>The Rite of Forced Translocation, like the Rite of Translocation, works by teleporting the person on the rune to one of the \
|
||||
text += "<font color='red'><b>Teleport Other</b></font><br>The Rite of Forced Translocation, like the Rite of Translocation, works by teleporting the person on the rune to one of the \
|
||||
same keyword. However, this rune will only work on people other than the user, allowing the user to send any living creature somewhere else.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of Knowledge</b></font><br>The Rite of Knowledge is a simplistic rune. When invoked, it will summon a single arcane tome to the rune's location before vanishing. \
|
||||
text += "<font color='red'><b>Summon Tome</b></font><br>The Rite of Knowledge is a simplistic rune. When invoked, it will summon a single arcane tome to the rune's location before vanishing. \
|
||||
<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of Enlightenment</b></font><br>The Rite of Enlightment is paramount to the success of the cult. It will allow you to convert normal crew members into cultists. \
|
||||
To do this, simply place the crew member upon the rune and invoke it. This may take some time, depending on the amount of cultists nearby. It takes twenty seconds, with each additional cultist shaving \
|
||||
off ten seconds of the conversion. With three or more cultists, conversion is instantaneous. Once invoked, only the original user must remain. If the target is loyalty-implanted or has a null rod in \
|
||||
their possession, this will not work.<br><br>"
|
||||
text += "<font color='red'><b>Convert</b></font><br>The Rite of Enlightment is paramount to the success of the cult. It will allow you to convert normal crew members into cultists. \
|
||||
To do this, simply place the crew member upon the rune and invoke it. This rune requires two acolytes to use. If the target to be converted is loyalty-implanted or a certain assignment, they will \
|
||||
be unable to be converted. People the Geometer wishes sacrificed will also be ineligible for conversion, and anyone with a shielding presence like a null rod will not be converted.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of Tribute</b></font><br>The Rite of Tribute is used to offer sacrifice to the Geometer. Simply place any living creature upon the rune and invoke it (this will not \
|
||||
text += "<font color='red'><b>Sacrifice</b></font><br>The Rite of Tribute is used to offer sacrifice to the Geometer. Simply place any living creature upon the rune and invoke it (this will not \
|
||||
target cultists!). If this creature has a mind, a soul shard will be created and the creature's soul transported to it. This rune is required if the cult's objectives include the sacrifice of a crew \
|
||||
member.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of Resurrection</b></font><br>The Rite of Resurrection is a delicate rite that requires two corpses. To perform the ritual, place the corpse you wish to revive onto \
|
||||
text += "<font color='red'><b>Raise Dead</b></font><br>The Rite of Resurrection is a delicate rite that requires two corpses. To perform the ritual, place the corpse you wish to revive onto \
|
||||
the rune and the offering body adjacent to it. When the rune is invoked, the body to be sacrificed will turn to ashes, the life force flowing into the revival target. Assuming the target is not moved \
|
||||
within a few seconds, they will be brought back to life, healed of all ailments.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of Obscurity</b></font><br>The Rite of Obscurity is a rite that will cause all nearby runes to become invisible. The runes will still be considered by other rites \
|
||||
text += "<font color='red'><b>Veil Runes</b></font><br>The Rite of Obscurity is a rite that will cause all nearby runes to become invisible. The runes will still be considered by other rites \
|
||||
(such as the Rite of Translocation) but is unusuable directly.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of True Sight</b></font><br>The Rite of True Sight is the foil of the Rite of Obscurity. It will turn all invisible runes visible once more, in addition to causing \
|
||||
text += "<font color='red'><b>Reveal Runes</b></font><br>The Rite of True Sight is the foil of the Rite of Obscurity. It will turn all invisible runes visible once more, in addition to causing \
|
||||
all spirits nearby to become partially corporeal.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of False Truths</b></font><br>Many crew men enjoy drawing runes in crayon that resemble spell circles in order to play pranks on their fellow crewmen. The Rite of \
|
||||
text += "<font color='red'><b>Disguise Runes</b></font><br>Many crew men enjoy drawing runes in crayon that resemble spell circles in order to play pranks on their fellow crewmen. The Rite of \
|
||||
False Truths takes advantage of this very joke. When invoked, all nearby runes will appear dull, precisely resembling those drawn in crayon. They still cannot be cleaned by conventional means, so \
|
||||
anyone trying to clean up the rune may become suspicious as it does not respond.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of Disruption</b></font><br>Robotic lifeforms have time and time again been the downfall of fledgling cults. The Rite of Disruption may allow you to gain the upper \
|
||||
text += "<font color='red'><b>Electromagnetic Disruption</b></font><br>Robotic lifeforms have time and time again been the downfall of fledgling cults. The Rite of Disruption may allow you to gain the upper \
|
||||
hand against these pests. By using the rune, a large electromagnetic pulse will be emitted from the rune's location.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of Astral Communion</b></font><br>The Rite of Astral Communion is perhaps the most ingenious rune that is usable by a single person. Upon invoking the rune, the \
|
||||
text += "<font color='red'><b>Astral Communion</b></font><br>The Rite of Astral Communion is perhaps the most ingenious rune that is usable by a single person. Upon invoking the rune, the \
|
||||
user's spirit will be ripped from their body. In this state, the user's physical body will be locked in place to the rune itself - any attempts to move it will result in the rune pulling it back. \
|
||||
The body will also take constant damage while in this form, and may even die. The user's spirit will contain their consciousness, and will allow them to freely wander the station as a ghost. This may \
|
||||
also be used to commune with the dead.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of the Corporeal Shield</b></font><br>While simple, the Rite of the Corporeal Shield serves an important purpose in defense and hindering passage. When invoked, the \
|
||||
text += "<font color='red'><b>Form Shield</b></font><br>While simple, the Rite of the Corporeal Shield serves an important purpose in defense and hindering passage. When invoked, the \
|
||||
rune will draw a small amount of life force from the user and make the space above the rune completely dense, rendering it impassable to all but the most complex means. The rune may be invoked again to \
|
||||
undo this effect and allow passage again.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of the Unheard Whisper</b></font><br>The Rite of the Unheard Whisper is simple. When invoked, it will cause all non-cultists within a radius of seven tiles to become \
|
||||
text += "<font color='red'><b>Deafen</b></font><br>The Rite of the Unheard Whisper is simple. When invoked, it will cause all non-cultists within a radius of seven tiles to become \
|
||||
completely deaf for a large amount of time.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of the Unseen Glance</b></font><br>Much like the Rite of the Unheard Whisper, the Rite of the Unseen Glance serves a single purpose. Any non-cultists who can see \
|
||||
text += "<font color='red'><b>Blind</b></font><br>Much like the Rite of the Unheard Whisper, the Rite of the Unseen Glance serves a single purpose. Any non-cultists who can see \
|
||||
the rune will instantly be blinded for a substantial amount of time.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of Disorientation</b></font><br>A somewhat empowered version of the Rite of the Unseen Glance, this rune will cause any non-cultists that can see the rune to become \
|
||||
text += "<font color='red'><b>Stun</b></font><br>A somewhat empowered version of the Rite of the Unseen Glance, this rune will cause any non-cultists that can see the rune to become \
|
||||
disoriented, disabling them for a short time.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of Joined Souls</b></font><br>The Rite of Joined Souls requires two acolytes to use. When invoked, it will allow the user to summon a single cultist to the rune from \
|
||||
text += "<font color='red'><b>Summon Cultist</b></font><br>The Rite of Joined Souls requires two acolytes to use. When invoked, it will allow the user to summon a single cultist to the rune from \
|
||||
any location. This will deal a moderate amount of damage to all invokers.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of Binding</b></font><br>The Rite of Binding is the only way to create talismans. A blank sheet of paper must be on top of the rune, with a valid rune nearby. After \
|
||||
text += "<font color='red'><b>Imbue Talisman</b></font><br>The Rite of Binding is the only way to create talismans. A blank sheet of paper must be on top of the rune, with a valid rune nearby. After \
|
||||
invoking it, the paper will be converted into a talisman, and the rune inlaid upon it.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of Fabrication</b></font><br>The Rite of Fabrication is the main way of creating construct shells. To use it, one must place five sheets of plasteel on top of the rune \
|
||||
text += "<font color='red'><b>Fabricate Shell</b></font><br>The Rite of Fabrication is the main way of creating construct shells. To use it, one must place five sheets of plasteel on top of the rune \
|
||||
and invoke it. The sheets will them be twisted into a construct shell, ready to recieve a soul to occupy it.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of Arming</b></font><br>The Rite of Arming will equip the user with invoker's robes, a backpack, a Nar-Sian longsword, and a pair of boots. Any items that cannot \
|
||||
text += "<font color='red'><b>Summon Arnaments</b></font><br>The Rite of Arming will equip the user with invoker's robes, a backpack, a Nar-Sian longsword, and a pair of boots. Any items that cannot \
|
||||
be equipped will instead not be summoned regardless.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of Leeching</b></font><br>The Rite of Leeching will drain the life of any non-cultist above the rune and heal the invoker for the same amount.<br><br>"
|
||||
text += "<font color='red'><b>Drain Life</b></font><br>The Rite of Leeching will drain the life of any non-cultist above the rune and heal the invoker for the same amount.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of Boiling Blood</b></font><br>The Rite of Boiling Blood may be considered one of the most dangerous rites composed by the Nar-Sian cult. When invoked, it will do a \
|
||||
text += "<font color='red'><b>Boil Blood</b></font><br>The Rite of Boiling Blood may be considered one of the most dangerous rites composed by the Nar-Sian cult. When invoked, it will do a \
|
||||
massive amount of damage to all non-cultist viewers, but it will also emit an explosion upon invocation. Use with caution<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Rite of Spectral Manifestation</b></font><br>If you wish to bring a spirit back from the dead with a wish for vengeance and desire to serve, the Rite of Spectral \
|
||||
text += "<font color='red'><b>Manifest Spirit</b></font><br>If you wish to bring a spirit back from the dead with a wish for vengeance and desire to serve, the Rite of Spectral \
|
||||
Manifestation can do just that. When invoked, any spirits above the rune will be brought to life as a human wearing nothing that seeks only to serve you and the Geometer. However, the spirit's link \
|
||||
to reality is fragile - you must remain on top of the rune, and you will slowly take damage. Upon stepping off the rune, the spirits will dissipate, dropping their items to the ground. You may manifest \
|
||||
multiple spirits with one rune, but you will rapidly take damage in doing so.<br><br>"
|
||||
|
||||
text += "<font color='red'><b><i>Ritual of Dimensional Rending</i></b></font><br>There is only one way to summon the avatar of Nar-Sie, and that is the Ritual of Dimensional Rending. This ritual, in \
|
||||
text += "<font color='red'><b><i>Call Forth The Geometer</i></b></font><br>There is only one way to summon the avatar of Nar-Sie, and that is the Ritual of Dimensional Rending. This ritual, in \
|
||||
comparison to other runes, is very large, requiring a 3x3 space of empty tiles to create. To invoke the rune, nine cultists must stand on the rune, so that all of them are within its circle. Then, \
|
||||
simply invoke it. A brief tearing will be heard as the barrier between dimensions is torn open, and the avatar will come forth.<br><br><br>"
|
||||
|
||||
@@ -222,17 +221,17 @@ It also contains rune words, which are soon to be removed.
|
||||
rune inlaid within it. The words of the rune can be whispered in order to invoke its effects, although usually to a lesser extent. To create a talisman, simply use a Rite of Binding as described above. \
|
||||
Unless stated otherwise, talismans are invoked by activating them in your hand. A list of valid rites, as well as the effects of their talisman form, can be found below.<br><br><br>"
|
||||
|
||||
text += "<font color='red'><b>Talisman of Translocation</b></font><br>The talisman form of the Rite of Translocation will transport the invoker to a randomly chosen rune of the same keyword, then \
|
||||
text += "<font color='red'><b>Talisman of Teleportation</b></font><br>The talisman form of the Rite of Translocation will transport the invoker to a randomly chosen rune of the same keyword, then \
|
||||
disappear.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Talisman of Knowledge</b></font><br>This talisman functions identically to the rune. It can be used once, then disappears.<br><br>"
|
||||
text += "<font color='red'><b>Talisman of Tome summoning</b></font><br>This talisman functions identically to the rune. It can be used once, then disappears.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Talismans of Obscurity, True Sight, and False Truths</b></font><br>These talismans all function identically to their rune counterparts, but with less range. In addition, \
|
||||
text += "<font color='red'><b>Talismans of Veiling, Revealing, and Disguising</b></font><br>These talismans all function identically to their rune counterparts, but with less range. In addition, \
|
||||
the Talisman of True Sight will not reveal spirits. They will disappear after one use.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Talisman of Disruption</b></font><br>This talisman functions like the Rite of Disruption, but with halved range. It disappears after one use.<br><br>"
|
||||
text += "<font color='red'><b>Talisman of Electromagnets</b></font><br>This talisman functions like the Rite of Disruption. It disappears after one use.<br><br>"
|
||||
|
||||
text += "<font color='red'><b>Talisman of Disorientation</b></font><br>Without this talisman, the cult would have no way of easily acquiring targets to convert. Commonly called \"stunpapers\", this \
|
||||
text += "<font color='red'><b>Talisman of Stunning</b></font><br>Without this talisman, the cult would have no way of easily acquiring targets to convert. Commonly called \"stunpapers\", this \
|
||||
talisman functions differently from others. Rather than simply reading the words, the target must be attacked directly with the talisman. The talisman will then knock down the target for a long \
|
||||
duration in addition to rendering them incapable of speech. Robotic lifeforms will suffer the effects of a heavy electromagnetic pulse instead."
|
||||
|
||||
@@ -269,7 +268,7 @@ It also contains rune words, which are soon to be removed.
|
||||
"<span class='danger'>You slice open your arm and begin drawing a sigil of the Geometer.</span>")
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.apply_damage(1, BRUTE, pick("l_arm", "r_arm"))
|
||||
C.apply_damage(0.1, BRUTE, pick("l_arm", "r_arm"))
|
||||
if(!do_after(user, 50, target = get_turf(user)))
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] creates a strange circle in their own blood.</span>", \
|
||||
|
||||
@@ -171,7 +171,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
var/list/teleport_runes = list()
|
||||
//Rite of Translocation: Warps the user to a random teleport rune with the same keyword.
|
||||
/obj/effect/rune/teleport
|
||||
cultist_name = "Rite of Translocation"
|
||||
cultist_name = "Teleport"
|
||||
cultist_desc = "Warps the user to a random rune of the same keyword."
|
||||
invocation = "Sas'so c'arta forbici!"
|
||||
icon_state = "2"
|
||||
@@ -210,7 +210,7 @@ var/list/teleport_runes = list()
|
||||
var/list/teleport_other_runes = list()
|
||||
//Rite of Forced Translocation: Warps the target to a random teleport rune with the same keyword.
|
||||
/obj/effect/rune/teleport_other
|
||||
cultist_name = "Rite of Forced Translocation"
|
||||
cultist_name = "Teleport Other"
|
||||
cultist_desc = "Warps the target to a random rune of the same keyword."
|
||||
invocation = "Sas'so c'arta forbica!"
|
||||
icon_state = "1"
|
||||
@@ -266,8 +266,8 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of Knowledge: Creates an arcane tome at the rune's location and destroys the rune.
|
||||
/obj/effect/rune/summon_tome
|
||||
cultist_name = "Rite of Knowledge"
|
||||
cultist_desc = "Pulls an unstranslated arcane tome from the archives of the Geometer."
|
||||
cultist_name = "Summon Tome"
|
||||
cultist_desc = "Pulls an arcane tome from the archives of the Geometer."
|
||||
invocation = "N'ath reth sh'yro eth d'raggathnor!"
|
||||
icon_state = "5"
|
||||
color = rgb(0, 0, 255)
|
||||
@@ -281,12 +281,13 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of Enlightenment: Converts a normal crewmember to the cult. Faster for every cultist nearby.
|
||||
/obj/effect/rune/convert
|
||||
cultist_name = "Rite of Enlightenment"
|
||||
cultist_name = "Convert"
|
||||
cultist_desc = "Converts a normal crewmember on top of it to the cult. Does not work on loyalty-implanted crew."
|
||||
invocation = "Mah'weyh pleggh at e'ntrath!"
|
||||
icon_state = "3"
|
||||
color = rgb(255, 0, 0)
|
||||
grammar = "certum nahlizet ego"
|
||||
req_cultists = 2
|
||||
|
||||
/obj/effect/rune/convert/invoke(mob/living/user)
|
||||
var/list/convertees = list()
|
||||
@@ -308,31 +309,6 @@ var/list/teleport_other_runes = list()
|
||||
if(iscultist(M))
|
||||
M << "<span class='cult'>\"I desire this one for myself. <i>SACRIFICE THEM!</i>\"</span>"
|
||||
return
|
||||
var/time = 300
|
||||
for(var/mob/living/M in orange(1,src))
|
||||
if(iscultist(M))
|
||||
time -= 100
|
||||
time = Clamp(time, 0, 300)
|
||||
if(time)
|
||||
visible_message("<span class='warning'>[src] begins to glow with a sinister light...</span>")
|
||||
for(var/mob/living/M in orange(1,src))
|
||||
if(iscultist(M))
|
||||
if(M != user)
|
||||
M << "<span class='warning'>You have aided [user] in invoking the [cultist_name]. You may now safely depart.</span>"
|
||||
else
|
||||
M << "<span class='warning'>You begin the enlightenment of [new_cultist]. This will take [time / 10] seconds and you must stand still.</span>"
|
||||
new_cultist << "<span class='userdanger'>Your head begins to ache...</span>"
|
||||
if(!do_mob(user, new_cultist, time))
|
||||
visible_message("<span class='warning'>[src] reluctantly falls dark.</span>")
|
||||
new_cultist << "<span class='danger'>Your headache fades.</span>"
|
||||
return
|
||||
if(is_sacrifice_target(new_cultist.mind))
|
||||
for(var/mob/living/M in orange(1,src))
|
||||
if(iscultist(M))
|
||||
M << "<span class='cult'>\"I desire this one for myself. <i>SACRIFICE THEM!</i>\"</span>"
|
||||
fail_invoke()
|
||||
log_game("Convert rune failed - convertee is sacrifice target")
|
||||
return
|
||||
new_cultist.visible_message("<span class='warning'>[new_cultist] writhes in pain as the markings below them glow a bloody red!</span>", \
|
||||
"<span class='userdanger'><i>AAAAAAAAAAAAAA-</i></span>")
|
||||
ticker.mode.add_cultist(new_cultist.mind)
|
||||
@@ -345,14 +321,18 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of Tribute: Sacrifices a crew member to Nar-Sie. Places them into a soul shard if they're in their body.
|
||||
/obj/effect/rune/sacrifice
|
||||
cultist_name = "Rite of Tribute"
|
||||
cultist_name = "Sacrifice"
|
||||
cultist_desc = "Sacrifices a crew member to the Geometer. May place them into a soul shard if their spirit remains in their body."
|
||||
icon_state = "3"
|
||||
invocation = "Barhah hra zar'garis!"
|
||||
invocation = "Ih wah'kd in teh'tin!"
|
||||
color = rgb(255, 255, 255)
|
||||
grammar = "veri nahlizet certum"
|
||||
var/rune_in_use = 0
|
||||
|
||||
/obj/effect/rune/sacrifice/New()
|
||||
..()
|
||||
icon_state = "[rand(1,6)]"
|
||||
|
||||
/obj/effect/rune/sacrifice/invoke(mob/living/user)
|
||||
if(rune_in_use)
|
||||
return
|
||||
@@ -397,28 +377,16 @@ var/list/teleport_other_runes = list()
|
||||
/obj/effect/rune/sacrifice/proc/sac(mob/living/T)
|
||||
var/sacrifice_fulfilled
|
||||
if(T)
|
||||
if(T.mind)
|
||||
var/obj/item/device/soulstone/stone = new /obj/item/device/soulstone(get_turf(src))
|
||||
if(!stone.transfer_soul("FORCE", T, usr)) //If it cannot be added
|
||||
qdel(stone)
|
||||
if(!T)
|
||||
rune_in_use = 0
|
||||
return
|
||||
if(istype(T, /mob/living/simple_animal/pet/dog/corgi))
|
||||
for(var/mob/living/carbon/C in orange(1,src))
|
||||
if(iscultist(C))
|
||||
C << "<span class='warning'>Even dark gods from another plane have standards, sicko.</span>"
|
||||
if(C.reagents)
|
||||
C.reagents.add_reagent("hell_water", 2)
|
||||
sacrificed.Add(T.mind)
|
||||
if(is_sacrifice_target(T.mind))
|
||||
sacrifice_fulfilled = 1
|
||||
if(isrobot(T))
|
||||
playsound(T, 'sound/magic/Disable_Tech.ogg', 100, 1)
|
||||
T.dust() //To prevent the MMI from remaining
|
||||
else
|
||||
playsound(T, 'sound/magic/Disintegrate.ogg', 100, 1)
|
||||
T.gib()
|
||||
if(T.mind)
|
||||
sacrificed.Add(T.mind)
|
||||
if(is_sacrifice_target(T.mind))
|
||||
sacrifice_fulfilled = 1
|
||||
for(var/mob/living/M in orange(1,src))
|
||||
if(iscultist(M))
|
||||
if(sacrifice_fulfilled)
|
||||
@@ -428,12 +396,25 @@ var/list/teleport_other_runes = list()
|
||||
M << "<span class='cult'>\"I accept this sacrifice.\"</span>"
|
||||
else
|
||||
M << "<span class='cult'>\"I accept this meager sacrifice.\"</span>"
|
||||
if(T.mind)
|
||||
var/obj/item/device/soulstone/stone = new /obj/item/device/soulstone(get_turf(src))
|
||||
if(!stone.transfer_soul("FORCE", T, usr)) //If it cannot be added
|
||||
qdel(stone)
|
||||
if(!T)
|
||||
rune_in_use = 0
|
||||
return
|
||||
if(isrobot(T))
|
||||
playsound(T, 'sound/magic/Disable_Tech.ogg', 100, 1)
|
||||
T.dust() //To prevent the MMI from remaining
|
||||
else
|
||||
playsound(T, 'sound/magic/Disintegrate.ogg', 100, 1)
|
||||
T.gib()
|
||||
rune_in_use = 0
|
||||
|
||||
|
||||
//Ritual of Dimensional Rending: Calls forth the avatar of Nar-Sie upon the station.
|
||||
/obj/effect/rune/narsie
|
||||
cultist_name = "Ritual of Dimensional Rending"
|
||||
cultist_name = "Call Forth The Geometer"
|
||||
cultist_desc = "Tears apart dimensional barriers, calling forth the avatar of the Geometer."
|
||||
invocation = "Tok-lyr rqa'nap g'olt-ulotf!"
|
||||
req_cultists = 9
|
||||
@@ -489,10 +470,11 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of Resurrection: Requires two corpses. Revives one and gibs the other.
|
||||
/obj/effect/rune/raise_dead
|
||||
cultist_name = "Rite of Resurrection"
|
||||
cultist_name = "Raise Dead"
|
||||
cultist_desc = "Requires two corpses. The one placed upon the rune is brought to life, the other is turned to ash."
|
||||
invocation = null //Depends on the name of the user - see below
|
||||
color = rgb(150, 0, 0)
|
||||
icon_state = "1"
|
||||
color = rgb(255, 0, 0)
|
||||
grammar = "nahlizet certum veri"
|
||||
|
||||
/obj/effect/rune/raise_dead/invoke(mob/living/user)
|
||||
@@ -557,11 +539,11 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of Obscurity: Turns all runes within a 3-tile radius invisible.
|
||||
/obj/effect/rune/hide_runes
|
||||
cultist_name = "Rite of Obscurity"
|
||||
cultist_desc = "Turns nearby runes invisible. They can be revealed by using the Rite of True Sight."
|
||||
cultist_name = "Veil Runes"
|
||||
cultist_desc = "Turns nearby runes invisible. They can be revealed by using the Reveal Runes rune."
|
||||
invocation = "Kla'atu barada nikt'o!"
|
||||
icon_state = "3"
|
||||
color = rgb(255,255,255)
|
||||
icon_state = "1"
|
||||
color = rgb(0,0,255)
|
||||
grammar = "geeri karazet nahlizet"
|
||||
|
||||
/obj/effect/rune/hide_runes/invoke(mob/living/user)
|
||||
@@ -579,11 +561,11 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of True Sight: Turns ghosts and obscured runes visible
|
||||
/obj/effect/rune/true_sight
|
||||
cultist_name = "Rite of True Sight"
|
||||
cultist_name = "Reveal Runes"
|
||||
cultist_desc = "Reveals all invisible objects nearby, from spirits to runes."
|
||||
invocation = "Nikt'o barada kla'atu!"
|
||||
icon_state = "6"
|
||||
color = rgb(255, 162, 33)
|
||||
icon_state = "4"
|
||||
color = rgb(255, 255, 255)
|
||||
grammar = "karazet geeri nahlizet"
|
||||
|
||||
/obj/effect/rune/true_sight/invoke()
|
||||
@@ -599,7 +581,7 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of False Truths: Makes runes appear like crayon ones
|
||||
/obj/effect/rune/make_runes_fake
|
||||
cultist_name = "Rite of False Truths"
|
||||
cultist_name = "Disguise Runes"
|
||||
cultist_desc = "Causes all nearby runes (including itself) to resemble those drawn in crayon."
|
||||
invocation = "By'o isit!"
|
||||
icon_state = "4"
|
||||
@@ -614,11 +596,11 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of Disruption: Emits an EMP blast.
|
||||
/obj/effect/rune/emp
|
||||
cultist_name = "Rite of Disruption"
|
||||
cultist_name = "Electromagnetic Disruption"
|
||||
cultist_desc = "Emits a large electromagnetic pulse, hindering electronics and disabling silicons."
|
||||
invocation = "Ta'gh fara'qha fel d'amar det!"
|
||||
icon_state = "1"
|
||||
color = rgb(0, 0, 255)
|
||||
icon_state = "5"
|
||||
color = rgb(255, 0, 0)
|
||||
grammar = "mgar karazet balaq"
|
||||
|
||||
/obj/effect/rune/emp/invoke(mob/living/user)
|
||||
@@ -632,11 +614,11 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of Astral Communion: Separates one's spirit from their body. They will take damage while it is active.
|
||||
/obj/effect/rune/astral
|
||||
cultist_name = "Rite of Astral Communion"
|
||||
cultist_name = "Astral Communion"
|
||||
cultist_desc = "Severs the link between one's spirit and body. This effect is taxing and one's physical body will take damage while this is active."
|
||||
invocation = "Fwe'sh mah erl nyag r'ya!"
|
||||
icon_state = "1"
|
||||
color = rgb(68, 47, 255)
|
||||
icon_state = "6"
|
||||
color = rgb(0, 0, 255)
|
||||
var/rune_in_use = 0 //One at a time, please!
|
||||
var/mob/living/affecting = null
|
||||
grammar = "veri ire ego"
|
||||
@@ -702,10 +684,11 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of the Corporeal Shield: When invoked, becomes solid and cannot be passed. Invoke again to undo.
|
||||
/obj/effect/rune/wall
|
||||
cultist_name = "Rite of the Corporeal Shield"
|
||||
cultist_name = "Form Shield"
|
||||
cultist_desc = "When invoked, makes the rune block passage. Can be invoked again to reverse this."
|
||||
invocation = "Khari'd! Eske'te tannin!"
|
||||
icon_state = "1"
|
||||
color = rgb(255, 0, 0)
|
||||
grammar = "mgar ire ego"
|
||||
|
||||
/obj/effect/rune/wall/examine(mob/user)
|
||||
@@ -724,10 +707,12 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of the Unheard Whisper: Deafens all non-cultists nearby.
|
||||
/obj/effect/rune/deafen
|
||||
cultist_name = "Rite of the Unheard Whisper"
|
||||
cultist_name = "Deafen"
|
||||
cultist_desc = "Causes all non-followers nearby to lose their hearing."
|
||||
invocation = "Sti kaliedir!"
|
||||
grammar = "geeri jatkaa karazet"
|
||||
color = rgb(0, 255, 0)
|
||||
icon_state = "4"
|
||||
|
||||
/obj/effect/rune/deafen/invoke(mob/living/user)
|
||||
visible_message("<span class='warning'>[src] blurs for a moment before fading away.</span>")
|
||||
@@ -740,11 +725,11 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of the Unseen Glance: Blinds all non-cultists nearby.
|
||||
/obj/effect/rune/blind
|
||||
cultist_name = "Rite of the Unseen Glance"
|
||||
cultist_name = "Blind"
|
||||
cultist_desc = "Causes all non-followers nearby to lose their sight."
|
||||
invocation = "Sti kaliesin!"
|
||||
icon_state = "1"
|
||||
color = rgb(0, 255, 0)
|
||||
icon_state = "4"
|
||||
color = rgb(0, 0, 255)
|
||||
grammar = "mgar jatkaa karazet"
|
||||
|
||||
/obj/effect/rune/blind/invoke(mob/living/user)
|
||||
@@ -760,11 +745,11 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of Disorientation: Stuns all non-cultists nearby for a brief time
|
||||
/obj/effect/rune/stun
|
||||
cultist_name = "Rite of Disorientation"
|
||||
cultist_name = "Stun"
|
||||
cultist_desc = "Stuns all nearby non-followers for a brief time."
|
||||
invocation = "Fuu ma'jin!"
|
||||
icon_state = "2"
|
||||
color = rgb(150, 0, 255)
|
||||
color = rgb(100, 0, 100)
|
||||
grammar = "certum geeri balaq"
|
||||
|
||||
/obj/effect/rune/stun/invoke(mob/living/user)
|
||||
@@ -780,7 +765,7 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of Joined Souls: Summons a single cultist. Requires 2 cultists.
|
||||
/obj/effect/rune/summon
|
||||
cultist_name = "Rite of Joined Souls"
|
||||
cultist_name = "Summon Cultist"
|
||||
cultist_desc = "Summons a single cultist to the rune."
|
||||
invocation = "N'ath reth sh'yro eth d'rekkathnor!"
|
||||
req_cultists = 2
|
||||
@@ -817,11 +802,11 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of Binding: Turns a nearby rune and a paper on top of the rune to a talisman, if both are valid.
|
||||
/obj/effect/rune/imbue
|
||||
cultist_name = "Rite of Binding"
|
||||
cultist_name = "Bind Talisman"
|
||||
cultist_desc = "Transforms papers and valid runes into talismans."
|
||||
invocation = "H'drak v'loso, mir'kanas verbot!"
|
||||
icon_state = "3"
|
||||
color = rgb(150, 0, 255)
|
||||
color = rgb(0, 0, 255)
|
||||
grammar = "veri balaq certum"
|
||||
|
||||
/obj/effect/rune/imbue/invoke(mob/living/user)
|
||||
@@ -860,18 +845,13 @@ var/list/teleport_other_runes = list()
|
||||
log_game("Talisman Imbue rune failed - chosen rune invalid")
|
||||
return
|
||||
visible_message("<span class='warning'>[picked_rune] crumbles to dust, and bloody images form themselves on [paper_to_imbue].</span>")
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.apply_damage(5, BRUTE, pick("l_arm", "r_arm"))
|
||||
else
|
||||
user.adjustBruteLoss(5)
|
||||
qdel(paper_to_imbue)
|
||||
qdel(picked_rune)
|
||||
|
||||
|
||||
//Rite of Fabrication: Creates a construct shell out of 5 metal sheets.
|
||||
/obj/effect/rune/construct_shell
|
||||
cultist_name = "Rite of Fabrication"
|
||||
cultist_name = "Fabricate Shell"
|
||||
cultist_desc = "Turns five plasteel sheets into an empty construct shell, suitable for containing a soul shard."
|
||||
invocation = "Ethra p'ni dedol!"
|
||||
icon_state = "5"
|
||||
@@ -900,7 +880,7 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of Arming: Creates cult robes, a trophy rack, and a cult sword on the rune.
|
||||
/obj/effect/rune/armor
|
||||
cultist_name = "Rite of Arming"
|
||||
cultist_name = "Summon Arnaments"
|
||||
cultist_desc = "Equips the user with robes, shoes, a backpack, and a longsword. Items that cannot be equipped will not be summoned."
|
||||
invocation = "N'ath reth sh'yro eth draggathnor!"
|
||||
icon_state = "4"
|
||||
@@ -919,7 +899,7 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of Leeching: Deals brute damage to the target and heals the same amount to the invoker.
|
||||
/obj/effect/rune/leeching
|
||||
cultist_name = "Rite of Leeching"
|
||||
cultist_name = "Drain Life"
|
||||
cultist_desc = "Drains the life of the target on the rune, restoring it to the user."
|
||||
invocation = "Yu'gular faras desdae. Havas mithum javara. Umathar uf'kal thenar!" //that's a mouthful
|
||||
icon_state = "2"
|
||||
@@ -948,7 +928,7 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of Boiling Blood: Deals extremely high amounts of damage to non-cultists nearby
|
||||
/obj/effect/rune/blood_boil
|
||||
cultist_name = "Rite of Boiling Blood"
|
||||
cultist_name = "Boil Blood"
|
||||
cultist_desc = "Boils the blood of non-believers who can see the rune, dealing extreme amounts of damage."
|
||||
invocation = "Dedo ol'btoh!"
|
||||
icon_state = "4"
|
||||
@@ -975,7 +955,7 @@ var/list/teleport_other_runes = list()
|
||||
|
||||
//Rite of Spectral Manifestation: Summons a ghost on top of the rune as a cultist human with no items. User must stand on the rune at all times, and takes damage for each summoned ghost.
|
||||
/obj/effect/rune/manifest
|
||||
cultist_name = "Rite of Spectral Manifestation"
|
||||
cultist_name = "Manifest Spirit"
|
||||
cultist_desc = "Manifests a spirit as a servant of the Geometer. The invoker must not move from atop the rune, and will take damage for each summoned spirit."
|
||||
invocation = "Gal'h'rfikk harfrandid mud'gib!" //how the fuck do you pronounce this
|
||||
icon_state = "6"
|
||||
|
||||
@@ -19,6 +19,7 @@ Rite of Disorientation
|
||||
var/cultist_desc = "A basic talisman. It serves no purpose."
|
||||
var/invocation = "Naise meam!"
|
||||
var/uses = 1
|
||||
var/health_cost = 0 //The amount of health taken from the user when invoking the talisman
|
||||
|
||||
/obj/item/weapon/paper/talisman/examine(mob/user)
|
||||
..()
|
||||
@@ -40,7 +41,9 @@ Rite of Disorientation
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/paper/talisman/proc/invoke(mob/living/user)
|
||||
|
||||
if(health_cost && iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.apply_damage(health_cost, BRUTE, pick("l_arm", "r_arm"))
|
||||
|
||||
//Malformed Talisman: If something goes wrong.
|
||||
/obj/item/weapon/paper/talisman/malformed
|
||||
@@ -124,9 +127,10 @@ Rite of Disorientation
|
||||
|
||||
//Rite of Translocation: Same as rune
|
||||
/obj/item/weapon/paper/talisman/teleport
|
||||
cultist_name = "Rite of Translocation"
|
||||
cultist_name = "Talisman of Teleportation"
|
||||
cultist_desc = "A single-use talisman that will teleport a user to a random rune of the same keyword."
|
||||
invocation = "Sas'so c'arta forbici!"
|
||||
health_cost = 5
|
||||
var/keyword = "ire"
|
||||
|
||||
/obj/item/weapon/paper/talisman/teleport/invoke(mob/living/user)
|
||||
@@ -135,7 +139,7 @@ Rite of Disorientation
|
||||
if(R.keyword == src.keyword)
|
||||
possible_runes.Add(R)
|
||||
if(!possible_runes.len)
|
||||
user << "<span class='warning'>There are no Rites of Translocation with the same keyword!</span>"
|
||||
user << "<span class='warning'>There are no Teleport runes with the same keyword!</span>"
|
||||
log_game("Teleportation talisman failed - no teleport runes of the same keyword")
|
||||
uses++ //To prevent deletion
|
||||
return
|
||||
@@ -151,12 +155,18 @@ Rite of Disorientation
|
||||
spawn(1) //To give the keyword time to change from the imbue rune
|
||||
info += keyword
|
||||
|
||||
/obj/item/weapon/paper/talisman/teleport/examine(mob/user)
|
||||
..()
|
||||
if(iscultist(user) && keyword)
|
||||
user << "<b>Keyword:</b> [keyword]"
|
||||
|
||||
|
||||
//Rite of Knowledge: Same as rune, but has two uses
|
||||
/obj/item/weapon/paper/talisman/summon_tome
|
||||
cultist_name = "Rite of Knowledge"
|
||||
cultist_name = "Talisman of Tome Summoning"
|
||||
cultist_desc = "A two-use talisman that will call untranslated tomes from the archives of the Geometer."
|
||||
invocation = "N'ath reth sh'yro eth d'raggathnor!"
|
||||
health_cost = 1
|
||||
|
||||
/obj/item/weapon/paper/talisman/summon_tome/invoke(mob/living/user)
|
||||
user.visible_message("<span class='warning'>Dust flows from [user]'s hand for a moment.</span>", \
|
||||
@@ -171,9 +181,10 @@ Rite of Disorientation
|
||||
|
||||
//Rite of Obscurity: Same as rune, but less range
|
||||
/obj/item/weapon/paper/talisman/hide_runes
|
||||
cultist_name = "Rite of Obscurity"
|
||||
cultist_name = "Talisman of Veiling"
|
||||
cultist_desc = "A talisman that will make all runes within a small radius invisible."
|
||||
invocation = "Kla'atu barada nikt'o!"
|
||||
health_cost = 1
|
||||
|
||||
/obj/item/weapon/paper/talisman/hide_runes/invoke(mob/living/user)
|
||||
user.visible_message("<span class='warning'>Dust flows from [user]'s hand.</span>", \
|
||||
@@ -185,9 +196,10 @@ Rite of Disorientation
|
||||
|
||||
//Rite of True Sight: Same as rune, but doesn't work on ghosts
|
||||
/obj/item/weapon/paper/talisman/true_sight
|
||||
cultist_name = "Rite of True Sight"
|
||||
cultist_name = "Talisman of Revealing"
|
||||
cultist_desc = "A talisman that reveals nearby invisible runes."
|
||||
invocation = "Nikt'o barada kla'atu!"
|
||||
health_cost = 1
|
||||
|
||||
/obj/item/weapon/paper/talisman/true_sight/invoke(mob/living/user)
|
||||
user.visible_message("<span class='warning'>A flash of light shines from [user]'s hand!</span>", \
|
||||
@@ -198,9 +210,10 @@ Rite of Disorientation
|
||||
|
||||
//Rite of False Truths: Same as rune
|
||||
/obj/item/weapon/paper/talisman/make_runes_fake
|
||||
cultist_name = "Rite of False Truths"
|
||||
cultist_name = "Talisman of Disguising"
|
||||
cultist_desc = "A talisman that will make nearby runes appear fake."
|
||||
invocation = "By'o isit!"
|
||||
health_cost = 3
|
||||
|
||||
/obj/item/weapon/paper/talisman/make_runes_fake/invoke(mob/living/user)
|
||||
user.visible_message("<span class='warning'>Dust flows from [user]s hand.</span>", \
|
||||
@@ -211,21 +224,23 @@ Rite of Disorientation
|
||||
|
||||
//Rite of Disruption: Same as rune, halved radius
|
||||
/obj/item/weapon/paper/talisman/emp
|
||||
cultist_name = "Rite of Disruption"
|
||||
cultist_name = "Talisman of Electromagnets"
|
||||
cultist_desc = "A talisman that will cause a moderately-sized electromagnetic pulse."
|
||||
invocation = "Ta'gh fara'qha fel d'amar det!"
|
||||
health_cost = 5
|
||||
|
||||
/obj/item/weapon/paper/talisman/emp/invoke(mob/living/user)
|
||||
user.visible_message("<span class='warning'>[user]'s hand glows a bright blue!</span>", \
|
||||
user.visible_message("<span class='warning'>[user]'s hand flashes a bright blue!</span>", \
|
||||
"<span class='warning'>You speak the words of the talisman, emitting an EMP blast.</span>")
|
||||
empulse(src, 2, 4)
|
||||
empulse(src, 4, 8)
|
||||
|
||||
|
||||
//Rite of Disorientation: Stuns and mutes a single target for quite some time
|
||||
/obj/item/weapon/paper/talisman/stun
|
||||
cultist_name = "Rite of Disorientation"
|
||||
cultist_name = "Talisman of Stunning"
|
||||
cultist_desc = "A talisman that will stun and mute a single target. To use, attack target directly."
|
||||
invocation = "Fuu ma'jin!"
|
||||
health_cost = 10 //A lot of health because of how powerful this is
|
||||
|
||||
/obj/item/weapon/paper/talisman/stun/attack_self(mob/living/user)
|
||||
user << "<span class='warning'>To use this talisman, attack the target directly.</span>"
|
||||
@@ -254,3 +269,20 @@ Rite of Disorientation
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
//Rite of Arming: Equips cultist armor on the user, where available
|
||||
/obj/item/weapon/paper/talisman/armor
|
||||
cultist_name = "Talisman of Arming"
|
||||
cultist_desc = "A talisman that will equip the invoker with cultist equipment where available."
|
||||
invocation = "N'ath reth sh'yro eth draggathnor!"
|
||||
health_cost = 3
|
||||
|
||||
/obj/item/weapon/paper/talisman/armor/invoke(mob/living/user)
|
||||
user.visible_message("<span class='warning'>Otherworldy objects suddenly appear on [user]!</span>", \
|
||||
"<span class='warning'>You speak the words of the talisman, arming yourself!</span>")
|
||||
user.equip_to_slot_or_del(new /obj/item/clothing/head/culthood/alt(user), slot_head)
|
||||
user.equip_to_slot_or_del(new /obj/item/clothing/suit/cultrobes/alt(user), slot_wear_suit)
|
||||
user.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult/alt(user), slot_shoes)
|
||||
user.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/cultpack(user), slot_back)
|
||||
user.put_in_hands(new /obj/item/weapon/melee/cultblade(user))
|
||||
|
||||
@@ -147,11 +147,11 @@
|
||||
var/DNAstring = input("Input DNA string to search for." , "Please Enter String." , "")
|
||||
if(!DNAstring)
|
||||
return
|
||||
for(var/mob/living/carbon/M in mob_list)
|
||||
if(!M.dna)
|
||||
for(var/mob/living/carbon/C in mob_list)
|
||||
if(!C.dna)
|
||||
continue
|
||||
if(M.dna.unique_enzymes == DNAstring)
|
||||
target = M
|
||||
if(C.dna.unique_enzymes == DNAstring)
|
||||
target = C
|
||||
break
|
||||
|
||||
return attack_self()
|
||||
|
||||
@@ -807,7 +807,7 @@ var/global/list/possible_items_special = list()
|
||||
var/turf/cloc = get_turf(changeling.current)
|
||||
if(cloc && cloc.onCentcom() && (changeling.current.stat != DEAD)) //Living changeling on centcomm....
|
||||
for(var/name in check_names) //Is he (disguised as) one of the staff?
|
||||
if(H.dna && H.dna.real_name == name)
|
||||
if(H.dna.real_name == name)
|
||||
check_names -= name //This staff member is accounted for, remove them, so the team don't succeed by escape as 7 of the same engineer
|
||||
success++ //A living changeling staff member made it to centcomm
|
||||
continue changelings
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/datum/subsystem/ticker/proc/setupGenetics()
|
||||
/datum/subsystem/objects/proc/setupGenetics()
|
||||
var/list/avnums = new /list(DNA_STRUC_ENZYMES_BLOCKS)
|
||||
for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++)
|
||||
avnums[i] = i
|
||||
|
||||
@@ -166,10 +166,8 @@ Made by Xhuis
|
||||
thralls.Remove(thrall_mind)
|
||||
thrall_mind.current.attack_log += "\[[time_stamp()]\] <span class='danger'>Dethralled</span>"
|
||||
thrall_mind.special_role = null
|
||||
thrall_mind.remove_spell(/obj/effect/proc_holder/spell/targeted/lesser_shadowling_hivemind)
|
||||
thrall_mind.remove_spell(/obj/effect/proc_holder/spell/targeted/lesser_glare)
|
||||
thrall_mind.remove_spell(/obj/effect/proc_holder/spell/targeted/lesser_shadow_walk)
|
||||
thrall_mind.remove_spell(/obj/effect/proc_holder/spell/targeted/thrall_vision)
|
||||
for(var/obj/effect/proc_holder/spell/S in thrall_mind.spell_list)
|
||||
thrall_mind.remove_spell(S)
|
||||
if(kill && ishuman(thrall_mind.current)) //If dethrallization surgery fails, kill the mob as well as dethralling them
|
||||
var/mob/living/carbon/human/H = thrall_mind.current
|
||||
H.visible_message("<span class='warning'>[H] jerks violently and falls still.</span>", \
|
||||
@@ -186,6 +184,30 @@ Made by Xhuis
|
||||
under their command...</span>")
|
||||
return 1
|
||||
|
||||
/datum/game_mode/proc/remove_shadowling(datum/mind/ling_mind)
|
||||
if(!istype(ling_mind) || !(ling_mind in shadows)) return 0
|
||||
update_shadow_icons_removed(ling_mind)
|
||||
shadows.Remove(ling_mind)
|
||||
ling_mind.current.attack_log += "\[[time_stamp()]\] <span class='danger'>Deshadowlinged</span>"
|
||||
ling_mind.special_role = null
|
||||
for(var/obj/effect/proc_holder/spell/S in ling_mind.spell_list)
|
||||
ling_mind.remove_spell(S)
|
||||
var/mob/living/M = ling_mind.current
|
||||
if(issilicon(M))
|
||||
M.audible_message("<span class='notice'>[M] lets out a short blip.</span>", \
|
||||
"<span class='userdanger'>You have been turned into a robot! You are no longer a shadowling! Though you try, you cannot remember anything about your time as one...</span>")
|
||||
else
|
||||
M.visible_message("<span class='big'>[M] screams and contorts!</span>", \
|
||||
"<span class='userdanger'>THE LIGHT-- YOUR MIND-- <i>BURNS--</i></span>")
|
||||
spawn(30)
|
||||
if(!M || qdeleted(M))
|
||||
return
|
||||
M.visible_message("<span class='warning'>[M] suddenly bloats and explodes!</span>", \
|
||||
"<span class='warning'><b>AAAAAAAAA<font size=3>AAAAAAAAAAAAA</font><font size=4>AAAAAAAAAAAA----</font></span>")
|
||||
playsound(M, 'sound/magic/Disintegrate.ogg', 100, 1)
|
||||
M.gib()
|
||||
|
||||
|
||||
/datum/game_mode/shadowling/proc/check_shadow_victory()
|
||||
var/success = 0 //Did they win?
|
||||
if(shadow_objectives.Find("enthrall"))
|
||||
@@ -244,7 +266,7 @@ Made by Xhuis
|
||||
light_amount = T.get_lumcount()
|
||||
if(light_amount > LIGHT_DAM_THRESHOLD && !H.incorporeal_move) //Can survive in very small light levels. Also doesn't take damage while incorporeal, for shadow walk purposes
|
||||
H.take_overall_damage(0, LIGHT_DAMAGE_TAKEN)
|
||||
H << "<span class='userdanger'>The light burns you!</span>"
|
||||
H << "<span class='userdanger'>The light burns you!</span>" //Message spam to say "GET THE FUCK OUT"
|
||||
H << 'sound/weapons/sear.ogg'
|
||||
else if (light_amount < LIGHT_HEAL_THRESHOLD)
|
||||
H.heal_overall_damage(5,5)
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
for(var/obj/machinery/computer/C in T.contents)
|
||||
C.SetLuminosity(0)
|
||||
C.visible_message("<span class='warning'>[C] grows dim, its screen barely readable.</span>")
|
||||
for(var/obj/effect/glowshroom/G in orange(2, usr)) //Very small radius
|
||||
for(var/obj/effect/glowshroom/G in orange(7, usr)) //High radius because glowshroom spam wrecks shadowlings
|
||||
G.visible_message("<span class='warning'>[G] withers away!</span>")
|
||||
qdel(G)
|
||||
for(var/mob/living/H in T.contents)
|
||||
@@ -297,7 +297,7 @@
|
||||
user.equip_to_slot_or_del(new /obj/item/clothing/gloves/shadowling(usr), slot_gloves)
|
||||
user.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/shadowling(usr), slot_wear_mask)
|
||||
user.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/shadowling(usr), slot_glasses)
|
||||
hardset_dna(user, null, null, null, null, /datum/species/shadow/ling)
|
||||
user.set_species(/datum/species/shadow/ling)
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/collective_mind //Lets a shadowling bring together their thralls' strength, granting new abilities and a headcount
|
||||
@@ -334,27 +334,28 @@
|
||||
user << "<span class='warning'>Your concentration has been broken. The mental hooks you have sent out now retract into your mind.</span>"
|
||||
return
|
||||
|
||||
if(thralls >= 3 && !blind_smoke_acquired)
|
||||
if(thralls >= 3 && !screech_acquired)
|
||||
screech_acquired = 1
|
||||
user << "<span class='shadowling'><i>The power of your thralls has granted you the <b>Sonic Screech</b> ability. This ability will shatter nearby windows and deafen enemies, plus stunning silicon lifeforms.</span>"
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/unearthly_screech(null))
|
||||
|
||||
if(thralls >= 5 && !blind_smoke_acquired)
|
||||
blind_smoke_acquired = 1
|
||||
user << "<span class='shadowling'><i>The power of your thralls has granted you the <b>Blinding Smoke</b> ability. It will create a choking cloud that will blind any non-thralls who enter. \
|
||||
</i></span>"
|
||||
user.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/blindness_smoke
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/blindness_smoke(null))
|
||||
|
||||
if(thralls >= 5 && !drainLifeAcquired)
|
||||
if(thralls >= 7 && !drainLifeAcquired)
|
||||
drainLifeAcquired = 1
|
||||
user << "<span class='shadowling'><i>The power of your thralls has granted you the <b>Drain Life</b> ability. You can now drain the health of nearby humans to heal yourself.</i></span>"
|
||||
user.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/drain_life
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/drain_life(null))
|
||||
|
||||
if(thralls >= 7 && !screech_acquired)
|
||||
screech_acquired = 1
|
||||
user << "<span class='shadowling'><i>The power of your thralls has granted you the <b>Sonic Screech</b> ability. This ability will shatter nearby windows and deafen enemies, plus stunning silicon lifeforms.</span>"
|
||||
user.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/unearthly_screech
|
||||
|
||||
if(thralls >= 9 && !reviveThrallAcquired)
|
||||
reviveThrallAcquired = 1
|
||||
user << "<span class='shadowling'><i>The power of your thralls has granted you the <b>Black Recuperation</b> ability. This will, after a short time, bring a dead thrall completely back to life \
|
||||
with no bodily defects.</i></span>"
|
||||
user.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/revive_thrall
|
||||
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/revive_thrall(null))
|
||||
|
||||
if(thralls < victory_threshold)
|
||||
user << "<span class='shadowling'>You do not have the power to ascend. You require [victory_threshold] thralls, but only [thralls] living thralls are present.</span>"
|
||||
@@ -492,7 +493,7 @@ datum/reagent/shadowling_blindness_smoke //Reagent used for above spell
|
||||
nearbyTargets = list()
|
||||
for(var/turf/T in targets)
|
||||
for(var/mob/living/carbon/M in T.contents)
|
||||
if(M == src) continue
|
||||
if(M == usr) continue
|
||||
targetsDrained++
|
||||
nearbyTargets.Add(M)
|
||||
if(!targetsDrained)
|
||||
@@ -568,7 +569,7 @@ datum/reagent/shadowling_blindness_smoke //Reagent used for above spell
|
||||
thrallToRevive.visible_message("<span class='warning'>[thrallToRevive] slowly rises, no longer recognizable as human.</span>", \
|
||||
"<span class='shadowling'><b>You feel new power flow into you. You have been gifted by your masters. You now closely resemble them. You are empowered in \
|
||||
darkness but wither slowly in light. In addition, Lesser Glare and Guise have been upgraded into their true forms.</b></span>")
|
||||
hardset_dna(thrallToRevive, null, null, null, null, /datum/species/shadow/ling/lesser)
|
||||
thrallToRevive.set_species(/datum/species/shadow/ling/lesser)
|
||||
thrallToRevive.mind.remove_spell(/obj/effect/proc_holder/spell/targeted/lesser_glare)
|
||||
thrallToRevive.mind.remove_spell(/obj/effect/proc_holder/spell/targeted/lesser_shadow_walk)
|
||||
thrallToRevive.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/glare(null))
|
||||
@@ -606,10 +607,56 @@ datum/reagent/shadowling_blindness_smoke //Reagent used for above spell
|
||||
return
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/shadowling_extend_shuttle
|
||||
name = "Destroy Engines"
|
||||
desc = "Extends the time of the emergency shuttle's arrival by ten to fifteen minutes."
|
||||
panel = "Shadowling Abilities"
|
||||
range = 1
|
||||
clothes_req = 0
|
||||
charge_max = 600
|
||||
action_icon_state = "extend_shuttle"
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/shadowling_extend_shuttle/cast(list/targets, mob/living/carbon/human/U = usr)
|
||||
if(!shadowling_check(usr))
|
||||
charge_counter = charge_max
|
||||
return
|
||||
for(var/mob/living/carbon/human/target in targets)
|
||||
if(target.stat)
|
||||
charge_counter = charge_max
|
||||
return
|
||||
if(!is_thrall(target))
|
||||
usr << "<span class='warning'>[target] must be a thrall.</span>"
|
||||
charge_counter = charge_max
|
||||
return
|
||||
if(SSshuttle.emergency.mode != SHUTTLE_CALL)
|
||||
usr << "<span class='warning'>The shuttle must be inbound only to the station.</span>"
|
||||
charge_counter = charge_max
|
||||
return
|
||||
var/mob/living/carbon/human/M = target
|
||||
U.visible_message("<span class='warning'>[U]'s eyes flash a bright red!</span>", \
|
||||
"<span class='notice'>You begin to draw [M]'s life force.</span>")
|
||||
M.visible_message("<span class='warning'>[M]'s face falls slack, their jaw slightly distending.</span>", \
|
||||
"<span class='boldannounce'>You are suddenly transported... far, far away...</span>")
|
||||
if(!do_after(U, 50, target = M))
|
||||
M << "<span class='warning'>You are snapped back to reality, your haze dissipating!</span>"
|
||||
U << "<span class='warning'>You have been interrupted. The draw has failed.</span>"
|
||||
return
|
||||
U << "<span class='notice'>You project [M]'s life force toward the approaching shuttle, extending its arrival duration!</span>"
|
||||
M.visible_message("<span class='warning'>[M]'s eyes suddenly flare red. They proceed to collapse on the floor, not breathing.</span>", \
|
||||
"<span class='warning'><b>...speeding by... ...pretty blue glow... ...touch it... ...no glow now... ...no light... ...nothing at all...</span>")
|
||||
M.death()
|
||||
if(SSshuttle.emergency.mode == SHUTTLE_CALL)
|
||||
var/more_minutes = 9000
|
||||
var/timer = SSshuttle.emergency.timeLeft()
|
||||
timer += more_minutes
|
||||
priority_announce("Major system failure aboard the emergency shuttle. This will extend its arrival time by approximately 15 minutes..", "System Failure", 'sound/misc/notice1.ogg')
|
||||
SSshuttle.emergency.setTimer(timer)
|
||||
|
||||
|
||||
// THRALL ABILITIES BEYOND THIS POINT //
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/lesser_glare //Thrall version of Glare - same effects but for 3 seconds
|
||||
/obj/effect/proc_holder/spell/targeted/lesser_glare //Thrall version of Glare - same effects but for 5 seconds
|
||||
name = "Lesser Glare"
|
||||
desc = "Stuns and mutes a target for a short duration."
|
||||
panel = "Thrall Abilities"
|
||||
@@ -636,8 +683,8 @@ datum/reagent/shadowling_blindness_smoke //Reagent used for above spell
|
||||
target << "<span class='userdanger'>Your gaze is forcibly drawn into [usr]'s eyes, and you are starstruck by the heavenly lights...</span>"
|
||||
else //Only alludes to the shadowling if the target is close by
|
||||
target << "<span class='userdanger'>Red lights suddenly dance in your vision, and you are starstruck by their heavenly beauty...</span>"
|
||||
target.Stun(3) //Roughly 30% as long as the normal one
|
||||
M.silent += 3
|
||||
target.Stun(5) //Roughly 50% as long as the normal one
|
||||
M.silent += 5
|
||||
|
||||
|
||||
/obj/effect/proc_holder/spell/targeted/lesser_shadow_walk //Thrall version of Shadow Walk, only works in darkness, doesn't grant phasing, but gives near-invisibility
|
||||
@@ -730,11 +777,11 @@ datum/reagent/shadowling_blindness_smoke //Reagent used for above spell
|
||||
return
|
||||
|
||||
for(var/mob/living/boom in targets)
|
||||
if(is_shadow_or_thrall(boom))
|
||||
if(is_shadow(boom)) //Used to not work on thralls. Now it does so you can PUNISH THEM LIKE THE WRATHFUL GOD YOU ARE.
|
||||
usr << "<span class='warning'>Making an ally explode seems unwise.<span>"
|
||||
charge_counter = charge_max
|
||||
return
|
||||
usr.visible_message("<span class='danger'>[usr]'s markings flare as they gesture at [boom]!</span>", \
|
||||
usr.visible_message("<span class='warning'>[usr]'s markings flare as they gesture at [boom]!</span>", \
|
||||
"<span class='shadowling'>You direct a lance of telekinetic energy into [boom].</span>")
|
||||
playMagSound()
|
||||
sleep(4)
|
||||
@@ -835,8 +882,7 @@ datum/reagent/shadowling_blindness_smoke //Reagent used for above spell
|
||||
for(var/turf/T in targets)
|
||||
for(var/mob/living/carbon/human/target in T.contents)
|
||||
if(is_shadow_or_thrall(target))
|
||||
if(target == usr) //No message for the user, of course
|
||||
continue
|
||||
continue
|
||||
target << "<span class='userdanger'>You are struck by a bolt of lightning!</span>"
|
||||
playsound(target, 'sound/magic/LightningShock.ogg', 50, 1)
|
||||
target.Weaken(8)
|
||||
|
||||
@@ -84,7 +84,7 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/shadowling(H), slot_gloves)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/shadowling(H), slot_wear_mask)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/shadowling(H), slot_glasses)
|
||||
hardset_dna(H, null, null, null, null, /datum/species/shadow/ling) //can't be a shadowling without being a shadowling
|
||||
H.set_species(/datum/species/shadow/ling) //can't be a shadowling without being a shadowling
|
||||
|
||||
sleep(10)
|
||||
H << "<span class='shadowling'><b><i>Your powers are awoken. You may now live to your fullest extent. Remember your goal. Cooperate with your thralls and allies.</b></i></span>"
|
||||
@@ -95,6 +95,7 @@ var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "N
|
||||
H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/flashfreeze(null))
|
||||
H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/collective_mind(null))
|
||||
H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadowling_regenarmor(null))
|
||||
H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadowling_extend_shuttle(null))
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
|
||||
/obj/item/weapon/veilrender/attack_self(mob/user)
|
||||
if(charges > 0)
|
||||
new /obj/effect/rend(get_turf(usr), spawn_type, spawn_amt, rend_desc, spawn_fast)
|
||||
new /obj/effect/rend(get_turf(user), spawn_type, spawn_amt, rend_desc, spawn_fast)
|
||||
charges--
|
||||
user.visible_message("<span class='boldannounce'>[src] hums with power as [usr] deals a blow to [activate_descriptor] itself!</span>")
|
||||
user.visible_message("<span class='boldannounce'>[src] hums with power as [user] deals a blow to [activate_descriptor] itself!</span>")
|
||||
else
|
||||
user << "<span class='danger'>The unearthly energies that powered the blade are now dormant.</span>"
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
|
||||
/obj/effect/rend/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/nullrod))
|
||||
user.visible_message("<span class='danger'>[usr] seals \the [src] with \the [I].</span>")
|
||||
user.visible_message("<span class='danger'>[user] seals \the [src] with \the [I].</span>")
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
@@ -97,7 +97,7 @@
|
||||
|
||||
/obj/item/weapon/scrying/attack_self(mob/user)
|
||||
user << "<span class='notice'>You can see...everything!</span>"
|
||||
visible_message("<span class='danger'>[usr] stares into [src], their eyes glazing over.</span>")
|
||||
visible_message("<span class='danger'>[user] stares into [src], their eyes glazing over.</span>")
|
||||
user.ghostize(1)
|
||||
return
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
unlimited = 1
|
||||
|
||||
/obj/item/device/necromantic_stone/attack(mob/living/carbon/human/M, mob/living/carbon/human/user)
|
||||
if(!istype(M, /mob/living/carbon/human))
|
||||
if(!istype(M))
|
||||
return ..()
|
||||
|
||||
if(!istype(user) || !user.canUseTopic(M,1))
|
||||
@@ -137,7 +137,7 @@
|
||||
user << "<span class='warning'>This artifact can only affect three undead at a time!</span>"
|
||||
return
|
||||
|
||||
hardset_dna(M, null, null, null, null, /datum/species/skeleton)
|
||||
M.set_species(/datum/species/skeleton, icon_update=0)
|
||||
M.revive()
|
||||
spooky_scaries |= M
|
||||
M << "<span class='userdanger'>You have been revived by </span><B>[user.real_name]!</B>"
|
||||
@@ -261,13 +261,24 @@ var/global/list/multiverse = list()
|
||||
|
||||
/obj/item/weapon/multisword/proc/spawn_copy(var/client/C, var/turf/T)
|
||||
var/mob/living/carbon/human/M = new/mob/living/carbon/human(T)
|
||||
C.prefs.copy_to(M)
|
||||
C.prefs.copy_to(M, icon_updates=0)
|
||||
M.key = C.key
|
||||
M.mind.name = usr.real_name
|
||||
M << "<B>You are an alternate version of [usr.real_name] from another universe! Help them accomplish their goals at all costs.</B>"
|
||||
M.real_name = usr.real_name
|
||||
M.name = usr.real_name
|
||||
M.faction = list("[usr.real_name]")
|
||||
if(prob(50))
|
||||
var/list/all_species = list()
|
||||
for(var/speciestype in typesof(/datum/species) - /datum/species)
|
||||
var/datum/species/S = new speciestype()
|
||||
if(!S.dangerous_existence)
|
||||
all_species += speciestype
|
||||
M.set_species(pick(all_species), icon_update=0)
|
||||
M.update_body()
|
||||
M.update_hair()
|
||||
M.update_mutcolor()
|
||||
M.dna.update_dna_identity()
|
||||
equip_copy(M)
|
||||
|
||||
if(evil)
|
||||
@@ -440,14 +451,6 @@ var/global/list/multiverse = list()
|
||||
else
|
||||
return
|
||||
|
||||
ready_dna(M)
|
||||
if(M.dna && prob(50))
|
||||
var/list/all_species = list()
|
||||
for(var/speciestype in typesof(/datum/species) - /datum/species)
|
||||
var/datum/species/S = new speciestype()
|
||||
if(!S.dangerous_existence)
|
||||
all_species += speciestype
|
||||
hardset_dna(M, null, null, null, null, pick(all_species))
|
||||
M.update_icons()
|
||||
M.update_augments()
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
var/mob/living/carbon/human/new_character = new(pick(latejoin))//The mob being spawned.
|
||||
|
||||
G_found.client.prefs.copy_to(new_character)
|
||||
ready_dna(new_character)
|
||||
new_character.dna.update_dna_identity()
|
||||
new_character.key = G_found.key
|
||||
|
||||
return new_character
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
return 0
|
||||
return 1
|
||||
/datum/spellbook_entry/proc/Buy(mob/living/carbon/human/user,obj/item/weapon/spellbook/book) //return 1 on success
|
||||
if(!S)
|
||||
if(!S || qdeleted(S))
|
||||
S = new spell_type()
|
||||
|
||||
//Check if we got the spell already
|
||||
|
||||
@@ -50,14 +50,12 @@
|
||||
return 0
|
||||
|
||||
//Equip the rest of the gear
|
||||
if(H.dna)
|
||||
H.dna.species.before_equip_job(src, H)
|
||||
H.dna.species.before_equip_job(src, H)
|
||||
|
||||
if(outfit)
|
||||
H.equipOutfit(outfit)
|
||||
|
||||
if(H.dna)
|
||||
H.dna.species.after_equip_job(src, H)
|
||||
H.dna.species.after_equip_job(src, H)
|
||||
|
||||
/datum/job/proc/apply_fingerprints(mob/living/carbon/human/H)
|
||||
if(!istype(H))
|
||||
|
||||
@@ -30,16 +30,17 @@
|
||||
var/emped = 0 //Number of consecutive EMP's on this camera
|
||||
|
||||
/obj/machinery/camera/New()
|
||||
..()
|
||||
assembly = new(src)
|
||||
assembly.state = 4
|
||||
|
||||
cameranet.cameras += src
|
||||
cameranet.addCamera(src)
|
||||
/* // Use this to look for cameras that have the same c_tag.
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
var/list/tempnetwork = C.network&src.network
|
||||
if(C != src && C.c_tag == src.c_tag && tempnetwork.len)
|
||||
world.log << "[src.c_tag] [src.x] [src.y] [src.z] conflicts with [C.c_tag] [C.x] [C.y] [C.z]"
|
||||
*/
|
||||
..()
|
||||
|
||||
/obj/machinery/camera/initialize()
|
||||
if(z == 1 && prob(3) && !start_active)
|
||||
@@ -56,6 +57,8 @@
|
||||
bug.current = null
|
||||
bug = null
|
||||
cameranet.removeCamera(src) //Will handle removal from the camera network and the chunks, so we don't need to worry about that
|
||||
cameranet.cameras -= src
|
||||
cameranet.removeCamera(src)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/camera/emp_act(severity)
|
||||
@@ -235,6 +238,11 @@
|
||||
return
|
||||
|
||||
/obj/machinery/camera/proc/deactivate(mob/user, displaymessage = 1) //this should be called toggle() but doing a find and replace for this would be ass
|
||||
if(can_use())
|
||||
cameranet.addCamera(src)
|
||||
else
|
||||
SetLuminosity(0)
|
||||
cameranet.removeCamera(src)
|
||||
status = !status
|
||||
cameranet.updateChunk(x, y, z)
|
||||
var/change_msg = "deactivates"
|
||||
|
||||
@@ -185,7 +185,7 @@
|
||||
H.ckey = ckey
|
||||
H << "<span class='notice'><b>Consciousness slowly creeps over you as your body regenerates.</b><br><i>So this is what cloning feels like?</i></span>"
|
||||
|
||||
hardset_dna(H, ui, se, null, null, mrace, features)
|
||||
H.hardset_dna(ui, se, H.real_name, null, mrace, features)
|
||||
H.faction |= factions
|
||||
|
||||
H.set_cloned_appearance()
|
||||
@@ -301,13 +301,13 @@
|
||||
return
|
||||
|
||||
/obj/machinery/clonepod/proc/go_out()
|
||||
if (src.locked)
|
||||
if (locked)
|
||||
return
|
||||
|
||||
if (src.mess) //Clean that mess and dump those gibs!
|
||||
src.mess = 0
|
||||
gibs(src.loc)
|
||||
src.icon_state = "pod_0"
|
||||
if (mess) //Clean that mess and dump those gibs!
|
||||
mess = 0
|
||||
gibs(loc)
|
||||
icon_state = "pod_0"
|
||||
|
||||
/*
|
||||
for(var/obj/O in src)
|
||||
@@ -315,22 +315,22 @@
|
||||
*/
|
||||
return
|
||||
|
||||
if (!(src.occupant))
|
||||
if (!occupant)
|
||||
return
|
||||
/*
|
||||
for(var/obj/O in src)
|
||||
O.loc = src.loc
|
||||
*/
|
||||
|
||||
if (src.occupant.client)
|
||||
src.occupant.client.eye = src.occupant.client.mob
|
||||
src.occupant.client.perspective = MOB_PERSPECTIVE
|
||||
if (occupant.client)
|
||||
occupant.client.eye = occupant.client.mob
|
||||
occupant.client.perspective = MOB_PERSPECTIVE
|
||||
if(occupant.loc == src)
|
||||
src.occupant.loc = src.loc
|
||||
src.icon_state = "pod_0"
|
||||
src.eject_wait = 0 //If it's still set somehow.
|
||||
domutcheck(src.occupant) //Waiting until they're out before possible monkeyizing.
|
||||
src.occupant = null
|
||||
occupant.loc = loc
|
||||
icon_state = "pod_0"
|
||||
eject_wait = 0 //If it's still set somehow.
|
||||
occupant.domutcheck() //Waiting until they're out before possible monkeyizing.
|
||||
occupant = null
|
||||
return
|
||||
|
||||
/obj/machinery/clonepod/proc/malfunction()
|
||||
|
||||
@@ -297,6 +297,7 @@
|
||||
src.updateUsrDialog()
|
||||
|
||||
|
||||
|
||||
// *** THE ORION TRAIL ** //
|
||||
|
||||
#define ORION_TRAIL_WINTURN 9
|
||||
@@ -313,6 +314,10 @@
|
||||
#define ORION_TRAIL_SPACEPORT "Spaceport"
|
||||
#define ORION_TRAIL_BLACKHOLE "BlackHole"
|
||||
|
||||
#define ORION_STATUS_START 1
|
||||
#define ORION_STATUS_NORMAL 2
|
||||
#define ORION_STATUS_GAMEOVER 3
|
||||
#define ORION_STATUS_MARKET 4
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail
|
||||
name = "The Orion Trail"
|
||||
@@ -326,8 +331,6 @@
|
||||
var/food = 80
|
||||
var/fuel = 60
|
||||
var/turns = 4
|
||||
var/playing = 0
|
||||
var/gameover = 0
|
||||
var/alive = 4
|
||||
var/eventdat = null
|
||||
var/event = null
|
||||
@@ -347,6 +350,8 @@
|
||||
var/spaceport_raided = 0
|
||||
var/spaceport_freebie = 0
|
||||
var/last_spaceport_action = ""
|
||||
var/gameStatus = ORION_STATUS_START
|
||||
var/canContinueEvent = 0
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/New()
|
||||
..()
|
||||
@@ -379,8 +384,7 @@
|
||||
alive = 4
|
||||
turns = 1
|
||||
event = null
|
||||
playing = 1
|
||||
gameover = 0
|
||||
gameStatus = ORION_STATUS_NORMAL
|
||||
lings_aboard = 0
|
||||
|
||||
//spaceport junk
|
||||
@@ -392,11 +396,11 @@
|
||||
if(..())
|
||||
return
|
||||
if(fuel <= 0 || food <=0 || settlers.len == 0)
|
||||
gameover = 1
|
||||
gameStatus = ORION_STATUS_GAMEOVER
|
||||
event = null
|
||||
user.set_machine(src)
|
||||
var/dat = ""
|
||||
if(gameover)
|
||||
if(gameStatus == ORION_STATUS_GAMEOVER)
|
||||
dat = "<center><h1>Game Over</h1></center>"
|
||||
dat += "Like many before you, your crew never made it to Orion, lost to space... <br><b>Forever</b>."
|
||||
if(settlers.len == 0)
|
||||
@@ -420,13 +424,13 @@
|
||||
user << "<span class='userdanger'><font size=3>You're never going to make it to Orion...</span></font>"
|
||||
user.death()
|
||||
emagged = 0 //removes the emagged status after you lose
|
||||
playing = 0 //also a new game
|
||||
gameStatus = ORION_STATUS_START
|
||||
name = "The Orion Trail"
|
||||
desc = "Learn how our ancestors got to Orion, and have fun in the process!"
|
||||
|
||||
else if(event)
|
||||
dat = eventdat
|
||||
else if(playing)
|
||||
else if(gameStatus == ORION_STATUS_NORMAL)
|
||||
var/title = stops[turns]
|
||||
var/subtext = stopblurbs[turns]
|
||||
dat = "<center><h1>[title]</h1></center>"
|
||||
@@ -453,8 +457,7 @@
|
||||
return
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/Topic(href, href_list)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(..())
|
||||
return
|
||||
if(href_list["close"])
|
||||
usr.unset_machine()
|
||||
@@ -465,247 +468,275 @@
|
||||
busy = 1
|
||||
|
||||
if (href_list["continue"]) //Continue your travels
|
||||
if(turns >= ORION_TRAIL_WINTURN)
|
||||
win()
|
||||
else
|
||||
food -= (alive+lings_aboard)*2
|
||||
fuel -= 5
|
||||
if(turns == 2 && prob(30))
|
||||
event = ORION_TRAIL_COLLISION
|
||||
event()
|
||||
else if(prob(75))
|
||||
event = pickweight(events)
|
||||
if(lings_aboard)
|
||||
if(event == ORION_TRAIL_LING || prob(55))
|
||||
event = ORION_TRAIL_LING_ATTACK
|
||||
event()
|
||||
turns += 1
|
||||
if(emagged)
|
||||
var/mob/living/carbon/M = usr //for some vars
|
||||
switch(event)
|
||||
if(ORION_TRAIL_RAIDERS)
|
||||
if(prob(50))
|
||||
usr << "<span class='userdanger'>You hear battle shouts. The tramping of boots on cold metal. Screams of agony. The rush of venting air. Are you going insane?</span>"
|
||||
M.hallucination += 30
|
||||
else
|
||||
usr << "<span class='userdanger'>Something strikes you from behind! It hurts like hell and feel like a blunt weapon, but nothing is there...</span>"
|
||||
M.take_organ_damage(30)
|
||||
playsound(loc, 'sound/weapons/genhit2.ogg', 100, 1)
|
||||
if(ORION_TRAIL_ILLNESS)
|
||||
var/severity = rand(1,3) //pray to RNGesus. PRAY, PIGS
|
||||
if(severity == 1)
|
||||
M << "<span class='userdanger'>You suddenly feel slightly nauseous.</span>" //got off lucky
|
||||
if(severity == 2)
|
||||
usr << "<span class='userdanger'>You suddenly feel extremely nauseous and hunch over until it passes.</span>"
|
||||
M.Stun(3)
|
||||
if(severity >= 3) //you didn't pray hard enough
|
||||
M << "<span class='warning'>An overpowering wave of nausea consumes over you. You hunch over, your stomach's contents preparing for a spectacular exit.</span>"
|
||||
M.Stun(5)
|
||||
sleep(30)
|
||||
say("[M] violently throws up!")
|
||||
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
M.nutrition -= 50 //lose a lot of food
|
||||
var/turf/location = usr.loc
|
||||
if(istype(location, /turf/simulated))
|
||||
location.add_vomit_floor(src, 1)
|
||||
if(ORION_TRAIL_FLUX)
|
||||
if(prob(75))
|
||||
M.Weaken(3)
|
||||
say("A sudden gust of powerful wind slams [M] into the floor!")
|
||||
M.take_organ_damage(25)
|
||||
playsound(src.loc, 'sound/weapons/Genhit.ogg', 100, 1)
|
||||
else
|
||||
M << "<span class='userdanger'>A violent gale blows past you, and you barely manage to stay standing!</span>"
|
||||
if(ORION_TRAIL_COLLISION) //by far the most damaging event
|
||||
if(prob(90))
|
||||
playsound(src.loc, 'sound/effects/bang.ogg', 100, 1)
|
||||
var/turf/simulated/floor/F
|
||||
for(F in orange(1, src))
|
||||
F.ChangeTurf(F.baseturf)
|
||||
say("Something slams into the floor around [src], exposing it to space!")
|
||||
if(hull)
|
||||
sleep(10)
|
||||
say("A new floor suddenly appears around [src]. What the hell?")
|
||||
if(gameStatus == ORION_STATUS_NORMAL && !event && turns != 7)
|
||||
if(turns >= ORION_TRAIL_WINTURN)
|
||||
win()
|
||||
else
|
||||
food -= (alive+lings_aboard)*2
|
||||
fuel -= 5
|
||||
if(turns == 2 && prob(30))
|
||||
event = ORION_TRAIL_COLLISION
|
||||
event()
|
||||
else if(prob(75))
|
||||
event = pickweight(events)
|
||||
if(lings_aboard)
|
||||
if(event == ORION_TRAIL_LING || prob(55))
|
||||
event = ORION_TRAIL_LING_ATTACK
|
||||
event()
|
||||
turns += 1
|
||||
if(emagged)
|
||||
var/mob/living/carbon/M = usr //for some vars
|
||||
switch(event)
|
||||
if(ORION_TRAIL_RAIDERS)
|
||||
if(prob(50))
|
||||
usr << "<span class='userdanger'>You hear battle shouts. The tramping of boots on cold metal. Screams of agony. The rush of venting air. Are you going insane?</span>"
|
||||
M.hallucination += 30
|
||||
else
|
||||
usr << "<span class='userdanger'>Something strikes you from behind! It hurts like hell and feel like a blunt weapon, but nothing is there...</span>"
|
||||
M.take_organ_damage(30)
|
||||
playsound(loc, 'sound/weapons/genhit2.ogg', 100, 1)
|
||||
if(ORION_TRAIL_ILLNESS)
|
||||
var/severity = rand(1,3) //pray to RNGesus. PRAY, PIGS
|
||||
if(severity == 1)
|
||||
M << "<span class='userdanger'>You suddenly feel slightly nauseous.</span>" //got off lucky
|
||||
if(severity == 2)
|
||||
usr << "<span class='userdanger'>You suddenly feel extremely nauseous and hunch over until it passes.</span>"
|
||||
M.Stun(3)
|
||||
if(severity >= 3) //you didn't pray hard enough
|
||||
M << "<span class='warning'>An overpowering wave of nausea consumes over you. You hunch over, your stomach's contents preparing for a spectacular exit.</span>"
|
||||
M.Stun(5)
|
||||
sleep(30)
|
||||
say("[M] violently throws up!")
|
||||
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
|
||||
M.nutrition -= 50 //lose a lot of food
|
||||
var/turf/location = usr.loc
|
||||
if(istype(location, /turf/simulated))
|
||||
location.add_vomit_floor(src, 1)
|
||||
if(ORION_TRAIL_FLUX)
|
||||
if(prob(75))
|
||||
M.Weaken(3)
|
||||
say("A sudden gust of powerful wind slams [M] into the floor!")
|
||||
M.take_organ_damage(25)
|
||||
playsound(src.loc, 'sound/weapons/Genhit.ogg', 100, 1)
|
||||
var/turf/space/T
|
||||
for(T in orange(1, src))
|
||||
T.ChangeTurf(/turf/simulated/floor/plating/)
|
||||
else
|
||||
say("Something slams into the floor around [src] - luckily, it didn't get through!")
|
||||
playsound(src.loc, 'sound/effects/bang.ogg', 50, 1)
|
||||
if(ORION_TRAIL_MALFUNCTION)
|
||||
playsound(src.loc, 'sound/effects/EMPulse.ogg', 50, 1)
|
||||
src.visible_message("<span class='danger'>[src] malfunctions, randomizing in-game stats!</span>")
|
||||
var/oldfood = food
|
||||
var/oldfuel = fuel
|
||||
food = rand(10,80) / rand(1,2)
|
||||
fuel = rand(10,60) / rand(1,2)
|
||||
if(electronics)
|
||||
sleep(10)
|
||||
if(oldfuel > fuel && oldfood > food)
|
||||
src.audible_message("<span class='danger'>[src] lets out a somehow reassuring chime.</span>")
|
||||
else if(oldfuel < fuel || oldfood < food)
|
||||
src.audible_message("<span class='danger'>[src] lets out a somehow ominous chime.</span>")
|
||||
food = oldfood
|
||||
fuel = oldfuel
|
||||
playsound(src.loc, 'sound/machines/chime.ogg', 50, 1)
|
||||
else
|
||||
M << "<span class='userdanger'>A violent gale blows past you, and you barely manage to stay standing!</span>"
|
||||
if(ORION_TRAIL_COLLISION) //by far the most damaging event
|
||||
if(prob(90))
|
||||
playsound(src.loc, 'sound/effects/bang.ogg', 100, 1)
|
||||
var/turf/simulated/floor/F
|
||||
for(F in orange(1, src))
|
||||
F.ChangeTurf(F.baseturf)
|
||||
say("Something slams into the floor around [src], exposing it to space!")
|
||||
if(hull)
|
||||
sleep(10)
|
||||
say("A new floor suddenly appears around [src]. What the hell?")
|
||||
playsound(src.loc, 'sound/weapons/Genhit.ogg', 100, 1)
|
||||
var/turf/space/T
|
||||
for(T in orange(1, src))
|
||||
T.ChangeTurf(/turf/simulated/floor/plating/)
|
||||
else
|
||||
say("Something slams into the floor around [src] - luckily, it didn't get through!")
|
||||
playsound(src.loc, 'sound/effects/bang.ogg', 50, 1)
|
||||
if(ORION_TRAIL_MALFUNCTION)
|
||||
playsound(src.loc, 'sound/effects/EMPulse.ogg', 50, 1)
|
||||
src.visible_message("<span class='danger'>[src] malfunctions, randomizing in-game stats!</span>")
|
||||
var/oldfood = food
|
||||
var/oldfuel = fuel
|
||||
food = rand(10,80) / rand(1,2)
|
||||
fuel = rand(10,60) / rand(1,2)
|
||||
if(electronics)
|
||||
sleep(10)
|
||||
if(oldfuel > fuel && oldfood > food)
|
||||
src.audible_message("<span class='danger'>[src] lets out a somehow reassuring chime.</span>")
|
||||
else if(oldfuel < fuel || oldfood < food)
|
||||
src.audible_message("<span class='danger'>[src] lets out a somehow ominous chime.</span>")
|
||||
food = oldfood
|
||||
fuel = oldfuel
|
||||
playsound(src.loc, 'sound/machines/chime.ogg', 50, 1)
|
||||
|
||||
else if(href_list["newgame"]) //Reset everything
|
||||
newgame()
|
||||
if(gameStatus == ORION_STATUS_START)
|
||||
newgame()
|
||||
else if(href_list["menu"]) //back to the main menu
|
||||
playing = 0
|
||||
event = null
|
||||
gameover = 0
|
||||
food = 80
|
||||
fuel = 60
|
||||
settlers = list("Harry","Larry","Bob")
|
||||
if(gameStatus == ORION_STATUS_GAMEOVER)
|
||||
gameStatus = ORION_STATUS_START
|
||||
event = null
|
||||
food = 80
|
||||
fuel = 60
|
||||
settlers = list("Harry","Larry","Bob")
|
||||
else if(href_list["slow"]) //slow down
|
||||
food -= (alive+lings_aboard)*2
|
||||
fuel -= 5
|
||||
if(event == ORION_TRAIL_FLUX)
|
||||
food -= (alive+lings_aboard)*2
|
||||
fuel -= 5
|
||||
event = null
|
||||
else if(href_list["pastblack"]) //slow down
|
||||
food -= ((alive+lings_aboard)*2)*3
|
||||
fuel -= 15
|
||||
turns += 1
|
||||
event = null
|
||||
else if(href_list["useengine"]) //use parts
|
||||
engine = max(0, --engine)
|
||||
event = null
|
||||
else if(href_list["useelec"]) //use parts
|
||||
electronics = max(0, --electronics)
|
||||
event = null
|
||||
else if(href_list["usehull"]) //use parts
|
||||
hull = max(0, --hull)
|
||||
event = null
|
||||
else if(href_list["wait"]) //wait 3 days
|
||||
food -= ((alive+lings_aboard)*2)*3
|
||||
event = null
|
||||
else if(href_list["keepspeed"]) //keep speed
|
||||
if(prob(75))
|
||||
event = "Breakdown"
|
||||
event()
|
||||
else
|
||||
event = null
|
||||
else if(href_list["blackhole"]) //keep speed past a black hole
|
||||
if(prob(75))
|
||||
event = ORION_TRAIL_BLACKHOLE
|
||||
event()
|
||||
if(emagged) //has to be here because otherwise it doesn't work
|
||||
playsound(src.loc, 'sound/effects/supermatter.ogg', 100, 1)
|
||||
say("A miniature black hole suddenly appears in front of [src], devouring [usr] alive!")
|
||||
usr.Stun(10) //you can't run :^)
|
||||
var/S = new /obj/singularity/academy(usr.loc)
|
||||
emagged = 0 //immediately removes emagged status so people can't kill themselves by sprinting up and interacting
|
||||
sleep(50)
|
||||
say("[S] winks out, just as suddenly as it appeared.")
|
||||
qdel(S)
|
||||
else
|
||||
event = null
|
||||
if(turns == 7)
|
||||
food -= ((alive+lings_aboard)*2)*3
|
||||
fuel -= 15
|
||||
turns += 1
|
||||
event = null
|
||||
else if(href_list["useengine"]) //use parts
|
||||
if(event == ORION_TRAIL_BREAKDOWN)
|
||||
engine = max(0, --engine)
|
||||
event = null
|
||||
else if(href_list["useelec"]) //use parts
|
||||
if(event == ORION_TRAIL_MALFUNCTION)
|
||||
electronics = max(0, --electronics)
|
||||
event = null
|
||||
else if(href_list["usehull"]) //use parts
|
||||
if(event == ORION_TRAIL_COLLISION)
|
||||
hull = max(0, --hull)
|
||||
event = null
|
||||
else if(href_list["wait"]) //wait 3 days
|
||||
if(event == ORION_TRAIL_BREAKDOWN || event == ORION_TRAIL_MALFUNCTION || event == ORION_TRAIL_COLLISION)
|
||||
food -= ((alive+lings_aboard)*2)*3
|
||||
event = null
|
||||
else if(href_list["keepspeed"]) //keep speed
|
||||
if(event == ORION_TRAIL_FLUX)
|
||||
if(prob(75))
|
||||
event = "Breakdown"
|
||||
event()
|
||||
else
|
||||
event = null
|
||||
else if(href_list["blackhole"]) //keep speed past a black hole
|
||||
if(turns == 7)
|
||||
if(prob(75))
|
||||
event = ORION_TRAIL_BLACKHOLE
|
||||
event()
|
||||
if(emagged) //has to be here because otherwise it doesn't work
|
||||
playsound(src.loc, 'sound/effects/supermatter.ogg', 100, 1)
|
||||
say("A miniature black hole suddenly appears in front of [src], devouring [usr] alive!")
|
||||
usr.Stun(10) //you can't run :^)
|
||||
var/S = new /obj/singularity/academy(usr.loc)
|
||||
emagged = 0 //immediately removes emagged status so people can't kill themselves by sprinting up and interacting
|
||||
sleep(50)
|
||||
say("[S] winks out, just as suddenly as it appeared.")
|
||||
qdel(S)
|
||||
else
|
||||
event = null
|
||||
turns += 1
|
||||
else if(href_list["holedeath"])
|
||||
gameover = 1
|
||||
event = null
|
||||
if(event == ORION_TRAIL_BLACKHOLE)
|
||||
gameStatus = ORION_STATUS_GAMEOVER
|
||||
event = null
|
||||
else if(href_list["eventclose"]) //end an event
|
||||
event = null
|
||||
if(canContinueEvent)
|
||||
event = null
|
||||
|
||||
else if(href_list["killcrew"]) //shoot a crewmember
|
||||
var/sheriff = remove_crewmember() //I shot the sheriff
|
||||
playsound(loc,'sound/weapons/Gunshot.ogg', 100, 1)
|
||||
if(gameStatus == ORION_STATUS_NORMAL || event == ORION_TRAIL_LING)
|
||||
var/sheriff = remove_crewmember() //I shot the sheriff
|
||||
playsound(loc,'sound/weapons/Gunshot.ogg', 100, 1)
|
||||
|
||||
if(settlers.len == 0 || alive == 0)
|
||||
say("The last crewmember [sheriff], shot themselves, GAME OVER!")
|
||||
if(emagged)
|
||||
usr.death(0)
|
||||
emagged = 0
|
||||
gameover = 1
|
||||
event = null
|
||||
else if(emagged)
|
||||
if(usr.name == sheriff)
|
||||
say("The crew of the ship chose to kill [usr.name]!")
|
||||
usr.death(0)
|
||||
if(settlers.len == 0 || alive == 0)
|
||||
say("The last crewmember [sheriff], shot themselves, GAME OVER!")
|
||||
if(emagged)
|
||||
usr.death(0)
|
||||
emagged = 0
|
||||
gameStatus = ORION_STATUS_GAMEOVER
|
||||
event = null
|
||||
else if(emagged)
|
||||
if(usr.name == sheriff)
|
||||
say("The crew of the ship chose to kill [usr.name]!")
|
||||
usr.death(0)
|
||||
|
||||
if(event == ORION_TRAIL_LING) //only ends the ORION_TRAIL_LING event, since you can do this action in multiple places
|
||||
event = null
|
||||
if(event == ORION_TRAIL_LING) //only ends the ORION_TRAIL_LING event, since you can do this action in multiple places
|
||||
event = null
|
||||
|
||||
//Spaceport specific interactions
|
||||
//they get a header because most of them don't reset event (because it's a shop, you leave when you want to)
|
||||
//they also call event() again, to regen the eventdata, which is kind of odd but necessary
|
||||
else if(href_list["buycrew"]) //buy a crewmember
|
||||
var/bought = add_crewmember()
|
||||
last_spaceport_action = "You hired [bought] as a new crewmember."
|
||||
fuel -= 10
|
||||
food -= 10
|
||||
event()
|
||||
if(gameStatus == ORION_STATUS_MARKET)
|
||||
if(!spaceport_raided && food >= 10 && fuel >= 10)
|
||||
var/bought = add_crewmember()
|
||||
last_spaceport_action = "You hired [bought] as a new crewmember."
|
||||
fuel -= 10
|
||||
food -= 10
|
||||
event()
|
||||
|
||||
else if(href_list["sellcrew"]) //sell a crewmember
|
||||
var/sold = remove_crewmember()
|
||||
last_spaceport_action = "You sold your crewmember, [sold]!"
|
||||
fuel += 7
|
||||
food += 7
|
||||
event()
|
||||
if(gameStatus == ORION_STATUS_MARKET)
|
||||
if(!spaceport_raided && settlers.len > 1)
|
||||
var/sold = remove_crewmember()
|
||||
last_spaceport_action = "You sold your crewmember, [sold]!"
|
||||
fuel += 7
|
||||
food += 7
|
||||
event()
|
||||
|
||||
else if(href_list["leave_spaceport"])
|
||||
event = null
|
||||
spaceport_raided = 0
|
||||
spaceport_freebie = 0
|
||||
last_spaceport_action = ""
|
||||
if(gameStatus == ORION_STATUS_MARKET)
|
||||
event = null
|
||||
gameStatus = ORION_STATUS_NORMAL
|
||||
spaceport_raided = 0
|
||||
spaceport_freebie = 0
|
||||
last_spaceport_action = ""
|
||||
|
||||
else if(href_list["raid_spaceport"])
|
||||
var/success = min(15 * alive,100) //default crew (4) have a 60% chance
|
||||
spaceport_raided = 1
|
||||
if(gameStatus == ORION_STATUS_MARKET)
|
||||
if(!spaceport_raided)
|
||||
var/success = min(15 * alive,100) //default crew (4) have a 60% chance
|
||||
spaceport_raided = 1
|
||||
|
||||
var/FU = 0
|
||||
var/FO = 0
|
||||
if(prob(success))
|
||||
FU = rand(5,15)
|
||||
FO = rand(5,15)
|
||||
last_spaceport_action = "You successfully raided the spaceport! you gained [FU] Fuel and [FO] Food! (+[FU]FU,+[FO]FO)"
|
||||
else
|
||||
FU = rand(-5,-15)
|
||||
FO = rand(-5,-15)
|
||||
last_spaceport_action = "You failed to raid the spaceport! you lost [FU*-1] Fuel and [FO*-1] Food in your scramble to escape! ([FU]FU,[FO]FO)"
|
||||
var/FU = 0
|
||||
var/FO = 0
|
||||
if(prob(success))
|
||||
FU = rand(5,15)
|
||||
FO = rand(5,15)
|
||||
last_spaceport_action = "You successfully raided the spaceport! you gained [FU] Fuel and [FO] Food! (+[FU]FU,+[FO]FO)"
|
||||
else
|
||||
FU = rand(-5,-15)
|
||||
FO = rand(-5,-15)
|
||||
last_spaceport_action = "You failed to raid the spaceport! you lost [FU*-1] Fuel and [FO*-1] Food in your scramble to escape! ([FU]FU,[FO]FO)"
|
||||
|
||||
//your chance of lose a crewmember is 1/2 your chance of success
|
||||
//this makes higher % failures hurt more, don't get cocky space cowboy!
|
||||
if(prob(success*5))
|
||||
var/lost_crew = remove_crewmember()
|
||||
last_spaceport_action = "You failed to raid the spaceport! you lost [FU*-1] Fuel and [FO*-1] Food, AND [lost_crew] in your scramble to escape! ([FU]FI,[FO]FO,-Crew)"
|
||||
if(emagged)
|
||||
say("WEEWOO WEEWOO, Spaceport Security en route!")
|
||||
for(var/i, i<=3, i++)
|
||||
var/mob/living/simple_animal/hostile/syndicate/ranged/orion/O = new/mob/living/simple_animal/hostile/syndicate/ranged/orion(get_turf(src))
|
||||
O.target = usr
|
||||
//your chance of lose a crewmember is 1/2 your chance of success
|
||||
//this makes higher % failures hurt more, don't get cocky space cowboy!
|
||||
if(prob(success*5))
|
||||
var/lost_crew = remove_crewmember()
|
||||
last_spaceport_action = "You failed to raid the spaceport! you lost [FU*-1] Fuel and [FO*-1] Food, AND [lost_crew] in your scramble to escape! ([FU]FI,[FO]FO,-Crew)"
|
||||
if(emagged)
|
||||
say("WEEWOO WEEWOO, Spaceport Security en route!")
|
||||
for(var/i, i<=3, i++)
|
||||
var/mob/living/simple_animal/hostile/syndicate/ranged/orion/O = new/mob/living/simple_animal/hostile/syndicate/ranged/orion(get_turf(src))
|
||||
O.target = usr
|
||||
|
||||
|
||||
fuel += FU
|
||||
food += FO
|
||||
event()
|
||||
fuel += FU
|
||||
food += FO
|
||||
event()
|
||||
|
||||
else if(href_list["buyparts"])
|
||||
switch(text2num(href_list["buyparts"]))
|
||||
if(1) //Engine Parts
|
||||
engine++
|
||||
last_spaceport_action = "Bought Engine Parts"
|
||||
if(2) //Hull Plates
|
||||
hull++
|
||||
last_spaceport_action = "Bought Hull Plates"
|
||||
if(3) //Spare Electronics
|
||||
electronics++
|
||||
last_spaceport_action = "Bought Spare Electronics"
|
||||
fuel -= 5 //they all cost 5
|
||||
event()
|
||||
if(gameStatus == ORION_STATUS_MARKET)
|
||||
if(!spaceport_raided && fuel > 5)
|
||||
switch(text2num(href_list["buyparts"]))
|
||||
if(1) //Engine Parts
|
||||
engine++
|
||||
last_spaceport_action = "Bought Engine Parts"
|
||||
if(2) //Hull Plates
|
||||
hull++
|
||||
last_spaceport_action = "Bought Hull Plates"
|
||||
if(3) //Spare Electronics
|
||||
electronics++
|
||||
last_spaceport_action = "Bought Spare Electronics"
|
||||
fuel -= 5 //they all cost 5
|
||||
event()
|
||||
|
||||
else if(href_list["trade"])
|
||||
switch(text2num(href_list["trade"]))
|
||||
if(1) //Fuel
|
||||
fuel -= 5
|
||||
food += 5
|
||||
last_spaceport_action = "Traded Fuel for Food"
|
||||
if(2) //Food
|
||||
fuel += 5
|
||||
food -= 5
|
||||
last_spaceport_action = "Traded Food for Fuel"
|
||||
event()
|
||||
if(gameStatus == ORION_STATUS_MARKET)
|
||||
if(!spaceport_raided)
|
||||
switch(text2num(href_list["trade"]))
|
||||
if(1) //Fuel
|
||||
if(fuel > 5)
|
||||
fuel -= 5
|
||||
food += 5
|
||||
last_spaceport_action = "Traded Fuel for Food"
|
||||
event()
|
||||
if(2) //Food
|
||||
if(food > 5)
|
||||
fuel += 5
|
||||
food -= 5
|
||||
last_spaceport_action = "Traded Food for Fuel"
|
||||
event()
|
||||
|
||||
src.add_fingerprint(usr)
|
||||
src.updateUsrDialog()
|
||||
@@ -715,7 +746,7 @@
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/proc/event()
|
||||
eventdat = "<center><h1>[event]</h1></center>"
|
||||
|
||||
canContinueEvent = 0
|
||||
switch(event)
|
||||
if(ORION_TRAIL_RAIDERS)
|
||||
eventdat += "Raiders have come aboard your ship!"
|
||||
@@ -732,6 +763,7 @@
|
||||
eventdat += "<br>Fortunately you fended them off without any trouble."
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];eventclose=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
|
||||
canContinueEvent = 1
|
||||
|
||||
if(ORION_TRAIL_FLUX)
|
||||
eventdat += "This region of space is highly turbulent. <br>If we go slowly we may avoid more damage, but if we keep our speed we won't waste supplies."
|
||||
@@ -745,6 +777,7 @@
|
||||
eventdat += "<br>[deadname] was killed by the disease."
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];eventclose=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
|
||||
canContinueEvent = 1
|
||||
|
||||
if(ORION_TRAIL_BREAKDOWN)
|
||||
eventdat += "Oh no! The engine has broken down!"
|
||||
@@ -806,6 +839,7 @@
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];killcrew=1'>Kill a crewmember</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];eventclose=1'>Risk it</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
|
||||
canContinueEvent = 1
|
||||
|
||||
if(ORION_TRAIL_LING_ATTACK)
|
||||
if(lings_aboard <= 0) //shouldn't trigger, but hey.
|
||||
@@ -847,9 +881,11 @@
|
||||
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];eventclose=1'>Continue</a></P>"
|
||||
eventdat += "<P ALIGN=Right><a href='byond://?src=\ref[src];close=1'>Close</a></P>"
|
||||
canContinueEvent = 1
|
||||
|
||||
|
||||
if(ORION_TRAIL_SPACEPORT)
|
||||
gameStatus = ORION_STATUS_MARKET
|
||||
if(spaceport_raided)
|
||||
eventdat += "The Spaceport is on high alert! they wont let you dock since you tried to attack them!"
|
||||
if(last_spaceport_action)
|
||||
@@ -978,8 +1014,7 @@
|
||||
|
||||
|
||||
/obj/machinery/computer/arcade/orion_trail/proc/win()
|
||||
playing = 0
|
||||
turns = 1
|
||||
gameStatus = ORION_STATUS_START
|
||||
say("Congratulations, you made it to Orion!")
|
||||
if(emagged)
|
||||
new /obj/item/weapon/orion_ship(src.loc)
|
||||
@@ -1071,3 +1106,8 @@
|
||||
#undef ORION_TRAIL_COLLISION
|
||||
#undef ORION_TRAIL_SPACEPORT
|
||||
#undef ORION_TRAIL_BLACKHOLE
|
||||
|
||||
#undef ORION_STATUS_START
|
||||
#undef ORION_STATUS_NORMAL
|
||||
#undef ORION_STATUS_GAMEOVER
|
||||
#undef ORION_STATUS_MARKET
|
||||
@@ -38,7 +38,7 @@
|
||||
GrantActions(user)
|
||||
current_user = user
|
||||
eyeobj.user = user
|
||||
eyeobj.name = "Camere Eye ([user.name])"
|
||||
eyeobj.name = "Camera Eye ([user.name])"
|
||||
L.remote_view = 1
|
||||
L.remote_control = eyeobj
|
||||
L.client.perspective = EYE_PERSPECTIVE
|
||||
|
||||
@@ -350,7 +350,7 @@
|
||||
return
|
||||
|
||||
/obj/machinery/computer/cloning/proc/scan_mob(mob/living/carbon/human/subject)
|
||||
if (!check_dna_integrity(subject) || !istype(subject))
|
||||
if (!istype(subject))
|
||||
scantemp = "<font class='bad'>Unable to locate valid genetic data.</font>"
|
||||
return
|
||||
if (!subject.getorgan(/obj/item/organ/internal/brain))
|
||||
|
||||
@@ -0,0 +1,482 @@
|
||||
#define INJECTOR_TIMEOUT 300
|
||||
#define REJUVENATORS_INJECT 15
|
||||
#define REJUVENATORS_MAX 90
|
||||
#define NUMBER_OF_BUFFERS 3
|
||||
|
||||
#define RADIATION_STRENGTH_MAX 15
|
||||
#define RADIATION_STRENGTH_MULTIPLIER 1 //larger has a more range
|
||||
|
||||
#define RADIATION_DURATION_MAX 30
|
||||
#define RADIATION_ACCURACY_MULTIPLIER 3 //larger is less accurate
|
||||
|
||||
#define RADIATION_IRRADIATION_MULTIPLIER 0.2 //multiplier for how much radiation a test subject recieves
|
||||
|
||||
/obj/machinery/computer/scan_consolenew
|
||||
name = "\improper DNA scanner access console"
|
||||
desc = "Scan DNA."
|
||||
icon_screen = "dna"
|
||||
icon_keyboard = "med_key"
|
||||
density = 1
|
||||
circuit = /obj/item/weapon/circuitboard/scan_consolenew
|
||||
var/radduration = 2
|
||||
var/radstrength = 1
|
||||
|
||||
var/list/buffer[NUMBER_OF_BUFFERS]
|
||||
|
||||
var/injectorready = 0 //Quick fix for issue 286 (screwdriver the screen twice to restore injector) -Pete
|
||||
var/current_screen = "mainmenu"
|
||||
var/obj/machinery/dna_scannernew/connected = null
|
||||
var/obj/item/weapon/disk/data/diskette = null
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 400
|
||||
|
||||
/obj/machinery/computer/scan_consolenew/attackby(obj/item/I, mob/user, params)
|
||||
if (istype(I, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES
|
||||
if (!src.diskette)
|
||||
if(!user.drop_item())
|
||||
return
|
||||
I.loc = src
|
||||
src.diskette = I
|
||||
user << "<span class='notice'>You insert [I].</span>"
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
else
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/scan_consolenew/New()
|
||||
..()
|
||||
|
||||
spawn(5)
|
||||
for(dir in list(NORTH,EAST,SOUTH,WEST))
|
||||
connected = locate(/obj/machinery/dna_scannernew, get_step(src, dir))
|
||||
if(!isnull(connected))
|
||||
break
|
||||
spawn(250)
|
||||
injectorready = 1
|
||||
return
|
||||
return
|
||||
|
||||
/obj/machinery/computer/scan_consolenew/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
ShowInterface(user)
|
||||
|
||||
/obj/machinery/computer/scan_consolenew/proc/ShowInterface(mob/user, last_change)
|
||||
if(!user) return
|
||||
var/datum/browser/popup = new(user, "scannernew", "DNA Modifier Console", 800, 630) // Set up the popup browser window
|
||||
if(!( in_range(src, user) || istype(user, /mob/living/silicon) ))
|
||||
popup.close()
|
||||
return
|
||||
popup.add_stylesheet("scannernew", 'html/browser/scannernew.css')
|
||||
|
||||
var/mob/living/carbon/viable_occupant
|
||||
var/occupant_status = "<div class='line'><div class='statusLabel'>Subject Status:</div><div class='statusValue'>"
|
||||
var/scanner_status
|
||||
var/temp_html
|
||||
if(connected && connected.is_operational())
|
||||
if(connected.occupant) //set occupant_status message
|
||||
viable_occupant = connected.occupant
|
||||
if(viable_occupant.has_dna() && (!(viable_occupant.disabilities & NOCLONE) || (connected.scan_level == 3))) //occupent is viable for dna modification
|
||||
occupant_status += "[viable_occupant.name] => "
|
||||
switch(viable_occupant.stat)
|
||||
if(CONSCIOUS) occupant_status += "<span class='good'>Conscious</span>"
|
||||
if(UNCONSCIOUS) occupant_status += "<span class='average'>Unconscious</span>"
|
||||
else occupant_status += "<span class='bad'>DEAD - Cannot Operate</span>"
|
||||
occupant_status += "</div></div>"
|
||||
occupant_status += "<div class='line'><div class='statusLabel'>Health:</div><div class='progressBar'><div style='width: [viable_occupant.health]%;' class='progressFill good'></div></div><div class='statusValue'>[viable_occupant.health] %</div></div>"
|
||||
occupant_status += "<div class='line'><div class='statusLabel'>Radiation Level:</div><div class='progressBar'><div style='width: [viable_occupant.radiation]%;' class='progressFill bad'></div></div><div class='statusValue'>[viable_occupant.radiation] %</div></div>"
|
||||
var/rejuvenators = viable_occupant.reagents.get_reagent_amount("epinephrine")
|
||||
occupant_status += "<div class='line'><div class='statusLabel'>Rejuvenators:</div><div class='progressBar'><div style='width: [round((rejuvenators / REJUVENATORS_MAX) * 100)]%;' class='progressFill highlight'></div></div><div class='statusValue'>[rejuvenators] units</div></div>"
|
||||
occupant_status += "<div class='line'><div class='statusLabel'>Unique Enzymes :</div><div class='statusValue'><span class='highlight'>[viable_occupant.dna.unique_enzymes]</span></div></div>"
|
||||
occupant_status += "<div class='line'><div class='statusLabel'>Last Operation:</div><div class='statusValue'>[last_change ? last_change : "----"]</div></div>"
|
||||
else
|
||||
viable_occupant = null
|
||||
occupant_status += "<span class='bad'>Invalid DNA structure</span></div></div>"
|
||||
if (viable_occupant && viable_occupant.stat == DEAD)
|
||||
viable_occupant = null // No editing the dead.
|
||||
else
|
||||
occupant_status += "<span class='bad'>No subject detected</span></div></div>"
|
||||
|
||||
if(connected.state_open)
|
||||
scanner_status = "Open"
|
||||
else
|
||||
scanner_status = "Closed"
|
||||
if(connected.locked)
|
||||
scanner_status += " <span class='bad'>(Locked)</span>"
|
||||
else
|
||||
scanner_status += " <span class='good'>(Unlocked)</span>"
|
||||
|
||||
|
||||
else
|
||||
occupant_status += "<span class='bad'>----</span></div></div>"
|
||||
scanner_status += "<span class='bad'>Error: No scanner detected</span>"
|
||||
|
||||
var/status = "<div class='statusDisplay'>"
|
||||
status += "<div class='line'><div class='statusLabel'>Scanner:</div><div class='statusValue'>[scanner_status]</div></div>"
|
||||
status += "[occupant_status]"
|
||||
|
||||
|
||||
status += "<div class='line'><h3>Radiation Emitter Status</h3></div>"
|
||||
var/stddev = radstrength*RADIATION_STRENGTH_MULTIPLIER
|
||||
status += "<div class='line'><div class='statusLabel'>Output Level:</div><div class='statusValue'>[radstrength]</div></div>"
|
||||
status += "<div class='line'><div class='statusLabel'> \> Mutation:</div><div class='statusValue'>(-[stddev] to +[stddev] = 68 %) (-[2*stddev] to +[2*stddev] = 95 %)</div></div>"
|
||||
if(connected)
|
||||
stddev = RADIATION_ACCURACY_MULTIPLIER/(radduration + (connected.precision_coeff ** 2))
|
||||
else
|
||||
stddev = RADIATION_ACCURACY_MULTIPLIER/radduration
|
||||
var/chance_to_hit
|
||||
switch(stddev) //hardcoded values from a z-table for a normal distribution
|
||||
if(0 to 0.25) chance_to_hit = ">95 %"
|
||||
if(0.25 to 0.5) chance_to_hit = "68-95 %"
|
||||
if(0.5 to 0.75) chance_to_hit = "55-68 %"
|
||||
else chance_to_hit = "<38 %"
|
||||
status += "<div class='line'><div class='statusLabel'>Pulse Duration:</div><div class='statusValue'>[radduration]</div></div>"
|
||||
status += "<div class='line'><div class='statusLabel'> \> Accuracy:</div><div class='statusValue'>[chance_to_hit]</div></div>"
|
||||
status += "<br></div>" // Close statusDisplay div
|
||||
var/buttons = "<a href='?src=\ref[src];'>Scan</a> "
|
||||
if(connected)
|
||||
buttons += " <a href='?src=\ref[src];task=toggleopen;'>[connected.state_open ? "Close" : "Open"] Scanner</a> "
|
||||
if (connected.state_open)
|
||||
buttons += "<span class='linkOff'>[connected.locked ? "Unlock" : "Lock"] Scanner</span> "
|
||||
else
|
||||
buttons += "<a href='?src=\ref[src];task=togglelock;'>[connected.locked ? "Unlock" : "Lock"] Scanner</a> "
|
||||
else buttons += "<span class='linkOff'>Open Scanner</span> <span class='linkOff'>Lock Scanner</span> "
|
||||
if(viable_occupant) buttons += "<a href='?src=\ref[src];task=rejuv'>Inject Rejuvenators</a> "
|
||||
else buttons += "<span class='linkOff'>Inject Rejuvenators</span> "
|
||||
if(diskette) buttons += "<a href='?src=\ref[src];task=ejectdisk'>Eject Disk</a> "
|
||||
else buttons += "<span class='linkOff'>Eject Disk</span> "
|
||||
if(current_screen == "buffer") buttons += "<a href='?src=\ref[src];task=screen;text=mainmenu;'>Radiation Emitter Menu</a> "
|
||||
else buttons += "<a href='?src=\ref[src];task=screen;text=buffer;'>Buffer Menu</a> "
|
||||
|
||||
switch(current_screen)
|
||||
if("working")
|
||||
temp_html += status
|
||||
temp_html += "<h1>System Busy</h1>"
|
||||
temp_html += "Working ... Please wait ([radduration] Seconds)"
|
||||
if("buffer")
|
||||
temp_html += status
|
||||
temp_html += buttons
|
||||
temp_html += "<h1>Buffer Menu</h1>"
|
||||
|
||||
if(istype(buffer))
|
||||
for(var/i=1, i<=buffer.len, i++)
|
||||
temp_html += "<br>Slot [i]: "
|
||||
var/list/buffer_slot = buffer[i]
|
||||
if( !buffer_slot || !buffer_slot.len || !buffer_slot["name"] || !((buffer_slot["UI"] && buffer_slot["UE"]) || buffer_slot["SE"]) )
|
||||
temp_html += "<br>\tNo Data"
|
||||
if(viable_occupant) temp_html += "<br><a href='?src=\ref[src];task=setbuffer;num=[i];'>Save to Buffer</a> "
|
||||
else temp_html += "<br><span class='linkOff'>Save to Buffer</span> "
|
||||
temp_html += "<span class='linkOff'>Clear Buffer</span> "
|
||||
if(diskette) temp_html += "<a href='?src=\ref[src];task=loaddisk;num=[i];'>Load from Disk</a> "
|
||||
else temp_html += "<span class='linkOff'>Load from Disk</span> "
|
||||
temp_html += "<span class='linkOff'>Save to Disk</span> "
|
||||
else
|
||||
var/ui = buffer_slot["UI"]
|
||||
var/se = buffer_slot["SE"]
|
||||
var/ue = buffer_slot["UE"]
|
||||
var/name = buffer_slot["name"]
|
||||
var/label = buffer_slot["label"]
|
||||
var/blood_type = buffer_slot["blood_type"]
|
||||
temp_html += "<br>\t<a href='?src=\ref[src];task=setbufferlabel;num=[i];'>Label</a>: [label ? label : name]"
|
||||
temp_html += "<br>\tSubject: [name]"
|
||||
if(ue && name && blood_type)
|
||||
temp_html += "<br>\tBlood Type: [blood_type]"
|
||||
temp_html += "<br>\tUE: [ue] "
|
||||
if(viable_occupant) temp_html += "<a href='?src=\ref[src];task=transferbuffer;num=[i];text=ue'>Occupant</a> "
|
||||
else temp_html += "<span class='linkOff'>Occupant</span>"
|
||||
if(injectorready) temp_html += "<a href='?src=\ref[src];task=injector;num=[i];text=ue'>Injector</a>"
|
||||
else temp_html += "<span class='linkOff'>Injector</span>"
|
||||
else
|
||||
temp_html += "<br>\tBlood Type: No Data"
|
||||
temp_html += "<br>\tUE: No Data"
|
||||
if(ui)
|
||||
temp_html += "<br>\tUI: [ui] "
|
||||
if(viable_occupant) temp_html += "<a href='?src=\ref[src];task=transferbuffer;num=[i];text=ui'>Occupant</a> "
|
||||
else temp_html += "<span class='linkOff'>Occupant</span>"
|
||||
if(injectorready) temp_html += "<a href='?src=\ref[src];task=injector;num=[i];text=ui'>Injector</a>"
|
||||
else temp_html += "<span class='linkOff'>Injector</span>"
|
||||
else
|
||||
temp_html += "<br>\tUI: No Data"
|
||||
if(se)
|
||||
temp_html += "<br>\tSE: [se] "
|
||||
if(viable_occupant && viable_occupant.stat != DEAD) temp_html += "<a href='?src=\ref[src];task=transferbuffer;num=[i];text=se'>Occupant</a> "
|
||||
else temp_html += "<span class='linkOff'>Occupant</span> "
|
||||
if(injectorready) temp_html += "<a href='?src=\ref[src];task=injector;num=[i];text=se'>Injector</a>"
|
||||
else temp_html += "<span class='linkOff'>Injector</span>"
|
||||
else
|
||||
temp_html += "<br>\tSE: No Data"
|
||||
if(viable_occupant) temp_html += "<br><a href='?src=\ref[src];task=setbuffer;num=[i];'>Save to Buffer</a> "
|
||||
else temp_html += "<br><span class='linkOff'>Save to Buffer</span> "
|
||||
temp_html += "<a href='?src=\ref[src];task=clearbuffer;num=[i];'>Clear Buffer</a> "
|
||||
if(diskette) temp_html += "<a href='?src=\ref[src];task=loaddisk;num=[i];'>Load from Disk</a> "
|
||||
else temp_html += "<span class='linkOff'>Load from Disk</span> "
|
||||
if(diskette && !diskette.read_only) temp_html += "<a href='?src=\ref[src];task=savedisk;num=[i];'>Save to Disk</a> "
|
||||
else temp_html += "<span class='linkOff'>Save to Disk</span> "
|
||||
else
|
||||
temp_html += status
|
||||
temp_html += buttons
|
||||
temp_html += "<h1>Radiation Emitter Menu</h1>"
|
||||
|
||||
temp_html += "<a href='?src=\ref[src];task=setstrength;num=[radstrength-1];'>--</a> <a href='?src=\ref[src];task=setstrength;'>Output Level</a> <a href='?src=\ref[src];task=setstrength;num=[radstrength+1];'>++</a>"
|
||||
temp_html += "<br><a href='?src=\ref[src];task=setduration;num=[radduration-1];'>--</a> <a href='?src=\ref[src];task=setduration;'>Pulse Duration</a> <a href='?src=\ref[src];task=setduration;num=[radduration+1];'>++</a>"
|
||||
|
||||
temp_html += "<h3>Irradiate Subject</h3>"
|
||||
temp_html += "<div class='line'><div class='statusLabel'>Unique Identifier:</div><div class='statusValue'><div class='clearBoth'>"
|
||||
|
||||
var/max_line_len = 7*DNA_BLOCK_SIZE
|
||||
if(viable_occupant)
|
||||
temp_html += "<div class='dnaBlockNumber'>1</div>"
|
||||
var/len = length(viable_occupant.dna.uni_identity)
|
||||
for(var/i=1, i<=len, i++)
|
||||
temp_html += "<a class='dnaBlock' href='?src=\ref[src];task=pulseui;num=[i];'>[copytext(viable_occupant.dna.uni_identity,i,i+1)]</a>"
|
||||
if ((i % max_line_len) == 0)
|
||||
temp_html += "</div><div class='clearBoth'>"
|
||||
if((i % DNA_BLOCK_SIZE) == 0 && i < len)
|
||||
temp_html += "<div class='dnaBlockNumber'>[(i / DNA_BLOCK_SIZE) + 1]</div>"
|
||||
else
|
||||
temp_html += "----"
|
||||
temp_html += "</div></div></div><br>"
|
||||
|
||||
temp_html += "<br><div class='line'><div class='statusLabel'>Structural Enzymes:</div><div class='statusValue'><div class='clearBoth'>"
|
||||
if(viable_occupant)
|
||||
temp_html += "<div class='dnaBlockNumber'>1</div>"
|
||||
var/len = length(viable_occupant.dna.struc_enzymes)
|
||||
for(var/i=1, i<=len, i++)
|
||||
temp_html += "<a class='dnaBlock' href='?src=\ref[src];task=pulsese;num=[i];'>[copytext(viable_occupant.dna.struc_enzymes,i,i+1)]</a>"
|
||||
if ((i % max_line_len) == 0)
|
||||
temp_html += "</div><div class='clearBoth'>"
|
||||
if((i % DNA_BLOCK_SIZE) == 0 && i < len)
|
||||
temp_html += "<div class='dnaBlockNumber'>[(i / DNA_BLOCK_SIZE) + 1]</div>"
|
||||
else
|
||||
temp_html += "----"
|
||||
temp_html += "</div></div></div>"
|
||||
|
||||
popup.set_content(temp_html)
|
||||
popup.open()
|
||||
|
||||
|
||||
/obj/machinery/computer/scan_consolenew/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
if(!isturf(usr.loc))
|
||||
return
|
||||
if(!( (isturf(loc) && in_range(src, usr)) || istype(usr, /mob/living/silicon) ))
|
||||
return
|
||||
if(current_screen == "working")
|
||||
return
|
||||
|
||||
add_fingerprint(usr)
|
||||
usr.set_machine(src)
|
||||
|
||||
var/mob/living/carbon/viable_occupant
|
||||
if(connected)
|
||||
viable_occupant = connected.occupant
|
||||
if(!istype(viable_occupant) || !viable_occupant.dna || (viable_occupant.disabilities & NOCLONE))
|
||||
viable_occupant = null
|
||||
|
||||
//Basic Tasks///////////////////////////////////////////
|
||||
var/num = round(text2num(href_list["num"]))
|
||||
var/last_change
|
||||
switch(href_list["task"])
|
||||
if("togglelock")
|
||||
if(connected) connected.locked = !connected.locked
|
||||
if("toggleopen")
|
||||
if(connected) connected.toggle_open(usr)
|
||||
if("setduration")
|
||||
if(!num)
|
||||
num = round(input(usr, "Choose pulse duration:", "Input an Integer", null) as num|null)
|
||||
if(num)
|
||||
radduration = Wrap(num, 1, RADIATION_DURATION_MAX+1)
|
||||
if("setstrength")
|
||||
if(!num)
|
||||
num = round(input(usr, "Choose pulse strength:", "Input an Integer", null) as num|null)
|
||||
if(num)
|
||||
radstrength = Wrap(num, 1, RADIATION_STRENGTH_MAX+1)
|
||||
if("screen")
|
||||
current_screen = href_list["text"]
|
||||
if("rejuv")
|
||||
if(viable_occupant && viable_occupant.reagents)
|
||||
var/epinephrine_amount = viable_occupant.reagents.get_reagent_amount("epinephrine")
|
||||
var/can_add = max(min(REJUVENATORS_MAX - epinephrine_amount, REJUVENATORS_INJECT), 0)
|
||||
viable_occupant.reagents.add_reagent("epinephrine", can_add)
|
||||
if("setbufferlabel")
|
||||
var/text = sanitize(input(usr, "Input a new label:", "Input an Text", null) as text|null)
|
||||
if(num && text)
|
||||
num = Clamp(num, 1, NUMBER_OF_BUFFERS)
|
||||
var/list/buffer_slot = buffer[num]
|
||||
if(istype(buffer_slot))
|
||||
buffer_slot["label"] = text
|
||||
if("setbuffer")
|
||||
if(num && viable_occupant)
|
||||
num = Clamp(num, 1, NUMBER_OF_BUFFERS)
|
||||
buffer[num] = list(
|
||||
"label"="Buffer[num]:[viable_occupant.real_name]",
|
||||
"UI"=viable_occupant.dna.uni_identity,
|
||||
"SE"=viable_occupant.dna.struc_enzymes,
|
||||
"UE"=viable_occupant.dna.unique_enzymes,
|
||||
"name"=viable_occupant.real_name,
|
||||
"blood_type"=viable_occupant.dna.blood_type
|
||||
)
|
||||
if("clearbuffer")
|
||||
if(num)
|
||||
num = Clamp(num, 1, NUMBER_OF_BUFFERS)
|
||||
var/list/buffer_slot = buffer[num]
|
||||
if(istype(buffer_slot))
|
||||
buffer_slot.Cut()
|
||||
if("transferbuffer")
|
||||
if(num && viable_occupant && viable_occupant.stat != DEAD)
|
||||
num = Clamp(num, 1, NUMBER_OF_BUFFERS)
|
||||
var/list/buffer_slot = buffer[num]
|
||||
if(istype(buffer_slot)) //15 and 40 are just magic numbers that were here before so i didnt touch them, they are initial boundaries of damage
|
||||
viable_occupant.radiation += rand(15/(connected.damage_coeff ** 2),40/(connected.damage_coeff ** 2)) //Each laser level reduces damage by lvl^2, so no effect on 1 lvl, 4 times less damage on 2 and 9 times less damage on 3
|
||||
switch(href_list["text"]) //Numbers are this high because other way upgrading laser is just not worth the hassle, and i cant think of anything better to inmrove
|
||||
if("se")
|
||||
if(buffer_slot["SE"])
|
||||
viable_occupant.dna.struc_enzymes = buffer_slot["SE"]
|
||||
viable_occupant.domutcheck()
|
||||
if("ui")
|
||||
if(buffer_slot["UI"])
|
||||
viable_occupant.dna.uni_identity = buffer_slot["UI"]
|
||||
viable_occupant.updateappearance(mutations_overlay_update=1)
|
||||
else
|
||||
if(buffer_slot["name"] && buffer_slot["UE"] && buffer_slot["blood_type"])
|
||||
viable_occupant.real_name = buffer_slot["name"]
|
||||
viable_occupant.name = buffer_slot["name"]
|
||||
viable_occupant.dna.unique_enzymes = buffer_slot["UE"]
|
||||
viable_occupant.dna.blood_type = buffer_slot["blood_type"]
|
||||
if("injector")
|
||||
if(num && injectorready)
|
||||
num = Clamp(num, 1, NUMBER_OF_BUFFERS)
|
||||
var/list/buffer_slot = buffer[num]
|
||||
if(istype(buffer_slot))
|
||||
var/obj/item/weapon/dnainjector/I
|
||||
switch(href_list["text"])
|
||||
if("se")
|
||||
if(buffer_slot["SE"])
|
||||
I = new /obj/item/weapon/dnainjector(loc)
|
||||
for(var/datum/mutation/human/HM in good_mutations + bad_mutations + not_good_mutations)
|
||||
if(HM.check_block_string(buffer_slot["SE"]))
|
||||
if(prob(HM.get_chance))
|
||||
I.add_mutations.Add(HM)
|
||||
else
|
||||
I.remove_mutations.Add(HM)
|
||||
I.damage_coeff = connected.damage_coeff
|
||||
if("ui")
|
||||
if(buffer_slot["UI"])
|
||||
I = new /obj/item/weapon/dnainjector(loc)
|
||||
I.fields = list("UI"=buffer_slot["UI"])
|
||||
I.damage_coeff = connected.damage_coeff
|
||||
else
|
||||
if(buffer_slot["name"] && buffer_slot["UE"] && buffer_slot["blood_type"])
|
||||
I = new /obj/item/weapon/dnainjector(loc)
|
||||
I.fields = list("name"=buffer_slot["name"], "UE"=buffer_slot["UE"], "blood_type"=buffer_slot["blood_type"])
|
||||
I.damage_coeff = connected.damage_coeff
|
||||
if(I)
|
||||
injectorready = 0
|
||||
spawn(INJECTOR_TIMEOUT)
|
||||
injectorready = 1
|
||||
if("loaddisk")
|
||||
if(num && diskette && diskette.fields)
|
||||
num = Clamp(num, 1, NUMBER_OF_BUFFERS)
|
||||
buffer[num] = diskette.fields.Copy()
|
||||
if("savedisk")
|
||||
if(num && diskette && !diskette.read_only)
|
||||
num = Clamp(num, 1, NUMBER_OF_BUFFERS)
|
||||
var/list/buffer_slot = buffer[num]
|
||||
if(istype(buffer_slot))
|
||||
diskette.name = "data disk \[[buffer_slot["label"]]\]"
|
||||
diskette.fields = buffer_slot.Copy()
|
||||
if("ejectdisk")
|
||||
if(diskette)
|
||||
diskette.loc = get_turf(src)
|
||||
diskette = null
|
||||
if("pulseui","pulsese")
|
||||
if(num && viable_occupant && connected && viable_occupant.stat != DEAD)
|
||||
radduration = Wrap(radduration, 1, RADIATION_DURATION_MAX+1)
|
||||
radstrength = Wrap(radstrength, 1, RADIATION_STRENGTH_MAX+1)
|
||||
|
||||
var/locked_state = connected.locked
|
||||
connected.locked = 1
|
||||
|
||||
current_screen = "working"
|
||||
ShowInterface(usr)
|
||||
|
||||
sleep(radduration*10)
|
||||
current_screen = "mainmenu"
|
||||
|
||||
if(viable_occupant && connected && connected.occupant==viable_occupant)
|
||||
viable_occupant.radiation += (RADIATION_IRRADIATION_MULTIPLIER*radduration*radstrength)/(connected.damage_coeff ** 2) //Read comment in "transferbuffer" section above for explanation
|
||||
switch(href_list["task"]) //Same thing as there but values are even lower, on best part they are about 0.0*, effectively no damage
|
||||
if("pulseui")
|
||||
var/len = length(viable_occupant.dna.uni_identity)
|
||||
num = Wrap(num, 1, len+1)
|
||||
num = randomize_radiation_accuracy(num, radduration + (connected.precision_coeff ** 2), len) //Each manipulator level above 1 makes randomization as accurate as selected time + manipulator lvl^2
|
||||
//Value is this high for the same reason as with laser - not worth the hassle of upgrading if the bonus is low
|
||||
var/block = round((num-1)/DNA_BLOCK_SIZE)+1
|
||||
var/subblock = num - block*DNA_BLOCK_SIZE
|
||||
last_change = "UI #[block]-[subblock]; "
|
||||
|
||||
var/hex = copytext(viable_occupant.dna.uni_identity, num, num+1)
|
||||
last_change += "[hex]"
|
||||
hex = scramble(hex, radstrength, radduration)
|
||||
last_change += "->[hex]"
|
||||
|
||||
viable_occupant.dna.uni_identity = copytext(viable_occupant.dna.uni_identity, 1, num) + hex + copytext(viable_occupant.dna.uni_identity, num+1, 0)
|
||||
viable_occupant.updateappearance(mutations_overlay_update=1)
|
||||
if("pulsese")
|
||||
var/len = length(viable_occupant.dna.struc_enzymes)
|
||||
num = Wrap(num, 1, len+1)
|
||||
num = randomize_radiation_accuracy(num, radduration + (connected.precision_coeff ** 2), len)
|
||||
|
||||
var/block = round((num-1)/DNA_BLOCK_SIZE)+1
|
||||
var/subblock = num - block*DNA_BLOCK_SIZE
|
||||
last_change = "SE #[block]-[subblock]; "
|
||||
|
||||
var/hex = copytext(viable_occupant.dna.struc_enzymes, num, num+1)
|
||||
last_change += "[hex]"
|
||||
hex = scramble(hex, radstrength, radduration)
|
||||
last_change += "->[hex]"
|
||||
|
||||
viable_occupant.dna.struc_enzymes = copytext(viable_occupant.dna.struc_enzymes, 1, num) + hex + copytext(viable_occupant.dna.struc_enzymes, num+1, 0)
|
||||
viable_occupant.domutcheck()
|
||||
else
|
||||
current_screen = "mainmenu"
|
||||
|
||||
if(connected)
|
||||
connected.locked = locked_state
|
||||
|
||||
ShowInterface(usr,last_change)
|
||||
|
||||
/obj/machinery/computer/scan_consolenew/proc/scramble(input,rs,rd)
|
||||
var/length = length(input)
|
||||
var/ran = gaussian(0, rs*RADIATION_STRENGTH_MULTIPLIER)
|
||||
if(ran == 0) ran = pick(-1,1) //hacky, statistically should almost never happen. 0-change makes people mad though
|
||||
else if(ran < 0) ran = round(ran) //negative, so floor it
|
||||
else ran = -round(-ran) //positive, so ceiling it
|
||||
return num2hex(Wrap(hex2num(input)+ran, 0, 16**length), length)
|
||||
|
||||
/obj/machinery/computer/scan_consolenew/proc/randomize_radiation_accuracy(position_we_were_supposed_to_hit, radduration, number_of_blocks)
|
||||
return Wrap(round(position_we_were_supposed_to_hit + gaussian(0, RADIATION_ACCURACY_MULTIPLIER/radduration), 1), 1, number_of_blocks+1)
|
||||
|
||||
|
||||
|
||||
/////////////////////////// DNA MACHINES
|
||||
#undef INJECTOR_TIMEOUT
|
||||
#undef REJUVENATORS_INJECT
|
||||
#undef REJUVENATORS_MAX
|
||||
#undef NUMBER_OF_BUFFERS
|
||||
|
||||
#undef RADIATION_STRENGTH_MAX
|
||||
#undef RADIATION_STRENGTH_MULTIPLIER
|
||||
|
||||
#undef RADIATION_DURATION_MAX
|
||||
#undef RADIATION_ACCURACY_MULTIPLIER
|
||||
|
||||
#undef RADIATION_IRRADIATION_MULTIPLIER
|
||||
|
||||
//#undef BAD_MUTATION_DIFFICULTY
|
||||
//#undef GOOD_MUTATION_DIFFICULTY
|
||||
//#undef OP_MUTATION_DIFFICULTY
|
||||
@@ -33,7 +33,7 @@
|
||||
dat += "<H3>Prisoner Implant Management</H3>"
|
||||
dat += "<HR>Chemical Implants<BR>"
|
||||
var/turf/Tr = null
|
||||
for(var/obj/item/weapon/implant/chem/C in world)
|
||||
for(var/obj/item/weapon/implant/chem/C in tracking_implants)
|
||||
Tr = get_turf(C)
|
||||
if((Tr) && (Tr.z != src.z)) continue//Out of range
|
||||
if(!C.implanted) continue
|
||||
@@ -43,7 +43,7 @@
|
||||
dat += "<A href='?src=\ref[src];inject10=\ref[C]'>(<font class='bad'>(10)</font>)</A><BR>"
|
||||
dat += "********************************<BR>"
|
||||
dat += "<HR>Tracking Implants<BR>"
|
||||
for(var/obj/item/weapon/implant/tracking/T in world)
|
||||
for(var/obj/item/weapon/implant/tracking/T in tracking_implants)
|
||||
if(!iscarbon(T.imp_in))
|
||||
continue
|
||||
if(!T.implanted)
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
/obj/machinery/dna_scannernew
|
||||
name = "\improper DNA scanner"
|
||||
desc = "It scans DNA structures."
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "scanner"
|
||||
density = 1
|
||||
var/locked = 0
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 50
|
||||
active_power_usage = 300
|
||||
var/damage_coeff
|
||||
var/scan_level
|
||||
var/precision_coeff
|
||||
|
||||
/obj/machinery/dna_scannernew/New()
|
||||
..()
|
||||
component_parts = list()
|
||||
component_parts += new /obj/item/weapon/circuitboard/clonescanner(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/scanning_module(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/manipulator(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/micro_laser(null)
|
||||
component_parts += new /obj/item/weapon/stock_parts/console_screen(null)
|
||||
component_parts += new /obj/item/stack/cable_coil(null, 1)
|
||||
component_parts += new /obj/item/stack/cable_coil(null, 1)
|
||||
RefreshParts()
|
||||
|
||||
|
||||
/obj/machinery/dna_scannernew/RefreshParts()
|
||||
scan_level = 0
|
||||
damage_coeff = 0
|
||||
precision_coeff = 0
|
||||
for(var/obj/item/weapon/stock_parts/scanning_module/P in component_parts)
|
||||
scan_level += P.rating
|
||||
for(var/obj/item/weapon/stock_parts/manipulator/P in component_parts)
|
||||
precision_coeff = P.rating
|
||||
for(var/obj/item/weapon/stock_parts/micro_laser/P in component_parts)
|
||||
damage_coeff = P.rating
|
||||
|
||||
/obj/machinery/dna_scannernew/update_icon()
|
||||
|
||||
//no power or maintenance
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
icon_state = initial(icon_state)+ (state_open ? "_open" : "") + "_unpowered"
|
||||
return
|
||||
|
||||
if((stat & MAINT) || panel_open)
|
||||
icon_state = initial(icon_state)+ (state_open ? "_open" : "") + "_maintenance"
|
||||
return
|
||||
|
||||
//running and someone in there
|
||||
if(occupant)
|
||||
icon_state = initial(icon_state)+ "_occupied"
|
||||
return
|
||||
|
||||
//running
|
||||
icon_state = initial(icon_state)+ (state_open ? "_open" : "")
|
||||
|
||||
/obj/machinery/dna_scannernew/power_change()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/dna_scannernew/proc/toggle_open(mob/user)
|
||||
if(panel_open)
|
||||
user << "<span class='notice'>Close the maintenance panel first.</span>"
|
||||
return
|
||||
|
||||
if(state_open)
|
||||
close_machine()
|
||||
return
|
||||
|
||||
else if(locked)
|
||||
user << "<span class='notice'>The bolts are locked down, securing the door shut.</span>"
|
||||
return
|
||||
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/dna_scannernew/container_resist()
|
||||
var/mob/living/user = usr
|
||||
var/breakout_time = 2
|
||||
if(state_open || !locked) //Open and unlocked, no need to escape
|
||||
state_open = 1
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
user << "<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [breakout_time] minutes.)</span>"
|
||||
user.visible_message("<span class='italics'>You hear a metallic creaking from [src]!</span>")
|
||||
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open || !locked)
|
||||
return
|
||||
|
||||
locked = 0
|
||||
visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>")
|
||||
user << "<span class='notice'>You successfully break out of [src]!</span>"
|
||||
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/dna_scannernew/close_machine()
|
||||
if(!state_open)
|
||||
return 0
|
||||
|
||||
..()
|
||||
|
||||
// search for ghosts, if the corpse is empty and the scanner is connected to a cloner
|
||||
if(occupant)
|
||||
if(locate(/obj/machinery/computer/cloning, get_step(src, NORTH)) \
|
||||
|| locate(/obj/machinery/computer/cloning, get_step(src, SOUTH)) \
|
||||
|| locate(/obj/machinery/computer/cloning, get_step(src, EAST)) \
|
||||
|| locate(/obj/machinery/computer/cloning, get_step(src, WEST)))
|
||||
|
||||
occupant.notify_ghost_cloning("Your corpse has been placed into a cloning scanner. Re-enter your corpse if you want to be cloned!")
|
||||
return 1
|
||||
|
||||
/obj/machinery/dna_scannernew/open_machine()
|
||||
if(state_open)
|
||||
return 0
|
||||
|
||||
..()
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/dna_scannernew/relaymove(mob/user as mob)
|
||||
if(user.stat || locked)
|
||||
return
|
||||
|
||||
open_machine()
|
||||
return
|
||||
|
||||
/obj/machinery/dna_scannernew/attackby(obj/item/I, mob/user, params)
|
||||
|
||||
if(!occupant && default_deconstruction_screwdriver(user, icon_state, icon_state, I))//sent icon_state is irrelevant...
|
||||
update_icon()//..since we're updating the icon here, since the scanner can be unpowered when opened/closed
|
||||
return
|
||||
|
||||
if(exchange_parts(user, I))
|
||||
return
|
||||
|
||||
if(default_pry_open(I))
|
||||
return
|
||||
|
||||
if(default_deconstruction_crowbar(I))
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/weapon/grab))
|
||||
var/obj/item/weapon/grab/G = I
|
||||
if(!ismob(G.affecting))
|
||||
return
|
||||
|
||||
if(!state_open)
|
||||
user << "<span class='notice'>Open the scanner first.</span>"
|
||||
return
|
||||
|
||||
var/mob/M = G.affecting
|
||||
M.loc = loc
|
||||
user.stop_pulling()
|
||||
qdel(G)
|
||||
|
||||
/obj/machinery/dna_scannernew/attack_hand(mob/user)
|
||||
if(..(user,1,0)) //don't set the machine, since there's no dialog
|
||||
return
|
||||
|
||||
toggle_open(user)
|
||||
|
||||
/obj/machinery/dna_scannernew/blob_act()
|
||||
if(prob(75))
|
||||
qdel(src)
|
||||
@@ -259,6 +259,10 @@
|
||||
/obj/machinery/door/proc/hasPower()
|
||||
return !(stat & NOPOWER)
|
||||
|
||||
/obj/machinery/door/proc/update_freelook_sight()
|
||||
if(!glass && cameranet)
|
||||
cameranet.updateVisibility(src, 0)
|
||||
|
||||
/obj/machinery/door/BlockSuperconductivity() // All non-glass airlocks block heat, this is intended.
|
||||
if(opacity || heat_proof)
|
||||
return 1
|
||||
|
||||
@@ -124,9 +124,9 @@
|
||||
|
||||
var/mob/living/carbon/human/T = attached
|
||||
|
||||
if(!istype(T)) return
|
||||
if(!T.dna)
|
||||
if(!istype(T))
|
||||
return
|
||||
|
||||
if(T.disabilities & NOCLONE)
|
||||
return
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
areaindex[tmpname] = 1
|
||||
L[tmpname] = R
|
||||
|
||||
for (var/obj/item/weapon/implant/tracking/I in world)
|
||||
for (var/obj/item/weapon/implant/tracking/I in tracking_implants)
|
||||
if (!I.implanted || !ismob(I.loc))
|
||||
continue
|
||||
else
|
||||
@@ -315,8 +315,8 @@
|
||||
var/mob/living/carbon/human/human = M
|
||||
if(human.dna && human.dna.species.id == "human")
|
||||
M << "<span class='italics'>You hear a buzzing in your ears.</span>"
|
||||
hardset_dna(human, null, null, null, null, /datum/species/fly)
|
||||
human.regenerate_icons()
|
||||
human.set_species(/datum/species/fly)
|
||||
|
||||
human.apply_effect((rand(120 - accurate * 40, 180 - accurate * 60)), IRRADIATE, 0)
|
||||
calibrated = 0
|
||||
return
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<b>HONK pressure: </b>[cabin_pressure>WARNING_HIGH_PRESSURE ? "<font color='red'>[cabin_pressure]</font>": cabin_pressure]kPa<br>
|
||||
<b>HONK temperature: </b> [return_temperature()]°K|[return_temperature() - T0C]°C<br>
|
||||
<b>Lights: </b>[lights?"on":"off"]<br>
|
||||
[src.dna?"<b>DNA-locked:</b><br> <span style='font-size:10px;letter-spacing:-1px;'>[src.dna]</span> \[<a href='?src=\ref[src];reset_dna=1'>Reset</a>\]<br>":null]
|
||||
[dna_lock?"<b>DNA-locked:</b><br> <span style='font-size:10px;letter-spacing:-1px;'>[dna_lock]</span> \[<a href='?src=\ref[src];reset_dna=1'>Reset</a>\]<br>":null]
|
||||
"}
|
||||
return output
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
var/last_message = 0
|
||||
var/add_req_access = 1
|
||||
var/maint_access = 0
|
||||
var/dna //dna-locking the mech
|
||||
var/dna_lock//dna-locking the mech
|
||||
var/list/proc_res = list() //stores proc owners, like proc_res["functionname"] = owner reference
|
||||
var/datum/effect/effect/system/spark_spread/spark_system = new
|
||||
var/lights = 0
|
||||
@@ -557,7 +557,7 @@
|
||||
else if(AI.stat || !AI.client)
|
||||
user << "<span class='warning'>[AI.name] is currently unresponsive, and cannot be uploaded.</span>"
|
||||
return
|
||||
else if(occupant || dna) //Normal AIs cannot steal mechs!
|
||||
else if(occupant || dna_lock) //Normal AIs cannot steal mechs!
|
||||
user << "<span class='warning'>Access denied. [name] is [occupant ? "currently occupied" : "secured with a DNA lock"]."
|
||||
return
|
||||
AI.control_disabled = 0
|
||||
@@ -653,10 +653,10 @@
|
||||
log_append_to_last("Permission denied.")
|
||||
return
|
||||
var/passed
|
||||
if(dna)
|
||||
if(check_dna_integrity(user))
|
||||
if(dna_lock)
|
||||
if(user.has_dna())
|
||||
var/mob/living/carbon/C = user
|
||||
if(C.dna.unique_enzymes==src.dna)
|
||||
if(C.dna.unique_enzymes==dna_lock)
|
||||
passed = 1
|
||||
else if(operation_allowed(user))
|
||||
passed = 1
|
||||
@@ -711,8 +711,8 @@
|
||||
else if(occupant)
|
||||
user << "<span class='warning'>Occupant detected!</span>"
|
||||
return 0
|
||||
else if(dna && dna!=mmi_as_oc.brainmob.dna.unique_enzymes)
|
||||
user << "<span class='warning'>Stop it!</span>"
|
||||
else if(dna_lock && (!mmi_as_oc.brainmob.dna || dna_lock!=mmi_as_oc.brainmob.dna.unique_enzymes))
|
||||
user << "<span class='warning'>Access denied. [name] is secured with a DNA lock.</span>"
|
||||
return 0
|
||||
|
||||
visible_message("<span class='notice'>[user] starts to insert an MMI into [src.name].</span>")
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
<b>Airtank temperature: </b>[tank_temperature]°K|[tank_temperature - T0C]°C<br>
|
||||
<b>Cabin pressure: </b>[cabin_pressure>WARNING_HIGH_PRESSURE ? "<span class='danger'>[cabin_pressure]</span>": cabin_pressure]kPa<br>
|
||||
<b>Cabin temperature: </b> [return_temperature()]°K|[return_temperature() - T0C]°C<br>
|
||||
[src.dna?"<b>DNA-locked:</b><br> <span style='font-size:10px;letter-spacing:-1px;'>[src.dna]</span> \[<a href='?src=\ref[src];reset_dna=1'>Reset</a>\]<br>":null]
|
||||
[dna_lock?"<b>DNA-locked:</b><br> <span style='font-size:10px;letter-spacing:-1px;'>[dna_lock]</span> \[<a href='?src=\ref[src];reset_dna=1'>Reset</a>\]<br>":null]
|
||||
"}
|
||||
return output
|
||||
|
||||
@@ -300,11 +300,11 @@
|
||||
if(occupant && !iscarbon(occupant))
|
||||
occupant << "<span class='danger'> You do not have any DNA!</span>"
|
||||
return
|
||||
dna = src.occupant.dna.unique_enzymes
|
||||
dna_lock = occupant.dna.unique_enzymes
|
||||
occupant_message("You feel a prick as the needle takes your DNA sample.")
|
||||
|
||||
if(href_list["reset_dna"])
|
||||
dna = null
|
||||
dna_lock = null
|
||||
|
||||
if(href_list["repair_int_control_lost"])
|
||||
occupant_message("Recalibrating coordination system...")
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
sleep(3)
|
||||
if (i > 0)
|
||||
if (prob(40))
|
||||
/*var/obj/effect/decal/cleanable/oil/o =*/
|
||||
new /obj/effect/decal/cleanable/oil/streak(src.loc)
|
||||
else if (prob(10))
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
@@ -36,10 +35,10 @@
|
||||
random_icon_states = list("gibarm", "gibleg")
|
||||
|
||||
/obj/effect/decal/cleanable/robot_debris/up
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7","gibup1","gibup1") //2:7 is close enough to 1:4
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7","gibup1","gibup1")
|
||||
|
||||
/obj/effect/decal/cleanable/robot_debris/down
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7","gibdown1","gibdown1") //2:7 is close enough to 1:4
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7","gibdown1","gibdown1")
|
||||
|
||||
/obj/effect/decal/cleanable/oil
|
||||
name = "motor oil"
|
||||
@@ -66,4 +65,4 @@
|
||||
return ..()
|
||||
|
||||
/obj/effect/decal/cleanable/oil/streak
|
||||
random_icon_states = list("streak1", "streak2", "streak3", "streak4", "streak5")
|
||||
random_icon_states = list("streak1", "streak2", "streak3", "streak4", "streak5")
|
||||
|
||||
@@ -13,7 +13,14 @@ would spawn and follow the beaker, even if it is carried or thrown.
|
||||
unacidable = 1//So effect are not targeted by alien acid.
|
||||
pass_flags = PASSTABLE | PASSGRILLE
|
||||
|
||||
/obj/effect/effect/New()
|
||||
..()
|
||||
if(ticker)
|
||||
cameranet.updateVisibility(src)
|
||||
|
||||
/obj/effect/effect/Destroy()
|
||||
if(ticker)
|
||||
cameranet.updateVisibility(src)
|
||||
..()
|
||||
return QDEL_HINT_PUTINPOOL
|
||||
/*
|
||||
|
||||
@@ -12,6 +12,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
|
||||
item_state = "electronic"
|
||||
w_class = 1
|
||||
slot_flags = SLOT_ID | SLOT_BELT
|
||||
origin_tech = "programming=2"
|
||||
|
||||
//Main variables
|
||||
var/owner = null // String name of owner
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
item_state = "camera_bug"
|
||||
throw_speed = 4
|
||||
throw_range = 20
|
||||
origin_tech = "syndicate=3;engineering=;1"
|
||||
|
||||
var/obj/machinery/camera/current = null
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
force = 3
|
||||
attack_verb = list("blown up", "exploded", "detonated")
|
||||
materials = list(MAT_METAL=50, MAT_GLASS=30)
|
||||
origin_tech = "syndicate=3;combat=2,"
|
||||
|
||||
/obj/item/device/doorCharge/ex_act(severity, target)
|
||||
switch(severity)
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
return
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.dna && (H.dna.check_mutation(HULK) || NOGUNS in H.dna.species.specflags))
|
||||
if(H.dna.check_mutation(HULK) || NOGUNS in H.dna.species.specflags)
|
||||
user << "<span class='warning'>Your fingers can't press the button!</span>"
|
||||
return
|
||||
|
||||
|
||||
@@ -162,8 +162,7 @@ MASS SPECTROMETER
|
||||
// Species and body temperature
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.dna)
|
||||
user << "<span class='info'>Species: [H.dna.species.name]</span>"
|
||||
user << "<span class='info'>Species: [H.dna.species.name]</span>"
|
||||
user << "<span class='info'>Body temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F)</span>"
|
||||
|
||||
// Time of death
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
var/tape_type = /obj/item/holotape
|
||||
var/icon_base
|
||||
var/charging = 0
|
||||
origin_tech = "materials=1;engineering=1"
|
||||
|
||||
/obj/item/holotape
|
||||
icon = 'icons/obj/holotape.dmi'
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/obj/item/borg/upgrade/reset
|
||||
name = "cyborg module reset board"
|
||||
desc = "Used to reset a cyborg's module. Destroys any other upgrades applied to the cyborg."
|
||||
@@ -197,7 +196,7 @@
|
||||
R.module.rebuild()
|
||||
return 1
|
||||
|
||||
/obj/item/borg/upgrade/syndicate/
|
||||
/obj/item/borg/upgrade/syndicate
|
||||
name = "illegal equipment module"
|
||||
desc = "Unlocks the hidden, deadlier functions of a cyborg"
|
||||
icon_state = "cyborg_upgrade3"
|
||||
@@ -211,3 +210,85 @@
|
||||
|
||||
R.SetEmagged(1)
|
||||
return 1
|
||||
|
||||
/obj/item/borg/upgrade/selfrepair
|
||||
name = "self-repair module"
|
||||
desc = "This module will repair the cyborg over time."
|
||||
icon_state = "cyborg_upgrade5"
|
||||
require_module = 1
|
||||
var/repair_amount = -1
|
||||
var/repair_tick = 1
|
||||
var/msg_cooldown = 0
|
||||
var/on = 0
|
||||
var/powercost = 10
|
||||
var/mob/living/silicon/robot/cyborg
|
||||
|
||||
/obj/item/borg/upgrade/selfrepair/action(mob/living/silicon/robot/R)
|
||||
if(..())
|
||||
return 0
|
||||
var/obj/item/borg/upgrade/selfrepair/U = locate() in R
|
||||
if(U)
|
||||
usr << "<span class='warning'>This unit is already equipped with a self-repair module.</span>"
|
||||
return 0
|
||||
cyborg = R
|
||||
icon_state = "selfrepair_off"
|
||||
action_button_name = "Toggle Self-Repair"
|
||||
return 1
|
||||
|
||||
/obj/item/borg/upgrade/selfrepair/ui_action_click()
|
||||
on = !on
|
||||
if(on)
|
||||
cyborg << "<span class='notice'>You activate the self-repair module.</span>"
|
||||
SSobj.processing |= src
|
||||
else
|
||||
cyborg << "<span class='notice'>You deactivate the self-repair module.</span>"
|
||||
SSobj.processing -= src
|
||||
update_icon()
|
||||
|
||||
/obj/item/borg/upgrade/selfrepair/update_icon()
|
||||
if(cyborg)
|
||||
icon_state = "selfrepair_[on ? "on" : "off"]"
|
||||
else
|
||||
icon_state = "cyborg_upgrade5"
|
||||
|
||||
/obj/item/borg/upgrade/selfrepair/proc/deactivate()
|
||||
SSobj.processing -= src
|
||||
on = 0
|
||||
update_icon()
|
||||
|
||||
/obj/item/borg/upgrade/selfrepair/process()
|
||||
if(!repair_tick)
|
||||
repair_tick = 1
|
||||
return
|
||||
|
||||
if( cyborg && (cyborg.stat != DEAD) && on)
|
||||
if(cyborg.cell.charge < powercost*2)
|
||||
cyborg << "<span class='warning'>Self-repair module deactivated. Please recharge.</span>"
|
||||
deactivate()
|
||||
return
|
||||
|
||||
if(cyborg.health < cyborg.maxHealth)
|
||||
if(cyborg.health < 0)
|
||||
repair_amount = -2.5
|
||||
powercost = 30
|
||||
else
|
||||
repair_amount = -1
|
||||
powercost = 10
|
||||
cyborg.adjustBruteLoss(repair_amount)
|
||||
cyborg.adjustFireLoss(repair_amount)
|
||||
cyborg.updatehealth()
|
||||
cyborg.cell.use(powercost)
|
||||
else
|
||||
cyborg.cell.use(5)
|
||||
repair_tick = 0
|
||||
|
||||
if( (world.time - 2000) > msg_cooldown )
|
||||
var/msgmode = "standby"
|
||||
if(cyborg.health < 0)
|
||||
msgmode = "critical"
|
||||
else if(cyborg.health < cyborg.maxHealth)
|
||||
msgmode = "normal"
|
||||
cyborg << "<span class='notice'>Self-repair is active in <span class='boldnotice'>[msgmode]</span> mode.</span>"
|
||||
msg_cooldown = world.time
|
||||
else
|
||||
deactivate()
|
||||
|
||||
@@ -103,6 +103,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \
|
||||
new/datum/stack_recipe("book case", /obj/structure/bookcase, 4, time = 15, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("drying rack", /obj/machinery/smartfridge/drying_rack, 10, time = 15, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("dog bed", /obj/structure/stool/bed/dogbed, 10, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("display case chassis", /obj/structure/displaycase_chassis, 5, one_per_turf = 1, on_floor = 1), \
|
||||
)
|
||||
|
||||
/obj/item/stack/sheet/mineral/wood
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
|
||||
/obj/item/weapon/dnainjector/proc/inject(mob/living/carbon/M, mob/user)
|
||||
if(check_dna_integrity(M) && !(M.disabilities & NOCLONE))
|
||||
if(M.has_dna() && !(M.disabilities & NOCLONE))
|
||||
if(M.stat == DEAD) //prevents dead people from having their DNA changed
|
||||
user << "<span class='notice'>You can't modify [M]'s DNA while \he's dead.</span>"
|
||||
return
|
||||
@@ -38,7 +38,7 @@
|
||||
M.dna.blood_type = fields["blood_type"]
|
||||
if(fields["UI"]) //UI+UE
|
||||
M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"])
|
||||
updateappearance(M)
|
||||
M.updateappearance(mutations_overlay_update=1)
|
||||
log_attack(log_msg)
|
||||
else
|
||||
user << "<span class='notice'>It appears that [M] does not have compatible DNA.</span>"
|
||||
|
||||
@@ -87,6 +87,15 @@
|
||||
origin_tech = "materials=2;magnets=2;programming=2;biotech=2"
|
||||
var/id = 1
|
||||
|
||||
|
||||
/obj/item/weapon/implant/tracking/New()
|
||||
..()
|
||||
tracking_implants += src
|
||||
|
||||
/obj/item/weapon/implant/tracking/Destroy()
|
||||
..()
|
||||
tracking_implants -= src
|
||||
|
||||
/obj/item/weapon/implant/tracking/get_data()
|
||||
var/dat = {"<b>Implant Specifications:</b><BR>
|
||||
<b>Name:</b> Tracking Beacon<BR>
|
||||
|
||||
@@ -24,6 +24,14 @@
|
||||
/obj/item/weapon/implant/chem/New()
|
||||
..()
|
||||
create_reagents(50)
|
||||
tracking_implants += src
|
||||
|
||||
/obj/item/weapon/implant/chem/Destroy()
|
||||
..()
|
||||
tracking_implants -= src
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/implant/chem/trigger(emote, mob/source)
|
||||
if(emote == "deathgasp")
|
||||
|
||||
@@ -78,7 +78,7 @@ Frequency:
|
||||
src.temp += "[W.code]-[dir2text(get_dir(sr, tr))]-[direct]<BR>"
|
||||
|
||||
src.temp += "<B>Extranneous Signals:</B><BR>"
|
||||
for (var/obj/item/weapon/implant/tracking/W in world)
|
||||
for (var/obj/item/weapon/implant/tracking/W in tracking_implants)
|
||||
if (!W.implanted || !ismob(W.loc))
|
||||
continue
|
||||
else
|
||||
|
||||
@@ -244,7 +244,7 @@
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/twohanded/dualsaber/wield(mob/living/carbon/M) //Specific wield () hulk checks due to reflection chance for balance issues and switches hitsounds.
|
||||
if(istype(M))
|
||||
if(M.has_dna())
|
||||
if(M.dna.check_mutation(HULK))
|
||||
M << "<span class='warning'>You lack the grace to wield this!</span>"
|
||||
return
|
||||
|
||||
@@ -8,12 +8,16 @@
|
||||
smooth_icon(src)
|
||||
smooth_icon_neighbors(src)
|
||||
icon_state = ""
|
||||
if(ticker)
|
||||
cameranet.updateVisibility(src)
|
||||
|
||||
/obj/structure/blob_act()
|
||||
if(prob(50))
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/Destroy()
|
||||
if(ticker)
|
||||
cameranet.updateVisibility(src)
|
||||
if(opacity)
|
||||
UpdateAffectingLights()
|
||||
if(smooth)
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
/obj/structure/displaycase
|
||||
name = "display case"
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "glassbox1"
|
||||
desc = "A display case for prized possessions. Hooked up with an anti-theft system."
|
||||
icon_state = "glassbox0"
|
||||
desc = "A display case for prized possessions."
|
||||
density = 1
|
||||
anchored = 1
|
||||
unacidable = 1//Dissolving the case would also delete the gun.
|
||||
var/health = 30
|
||||
var/occupied = 1
|
||||
var/destroyed = 0
|
||||
var/obj/item/showpiece = null
|
||||
var/alert = 0
|
||||
var/open = 0
|
||||
var/obj/item/weapon/electronics/airlock/electronics
|
||||
|
||||
/obj/structure/displaycase/ex_act(severity, target)
|
||||
switch(severity)
|
||||
if (1)
|
||||
new /obj/item/weapon/shard( src.loc )
|
||||
if (occupied)
|
||||
new /obj/item/weapon/gun/energy/laser/captain( src.loc )
|
||||
occupied = 0
|
||||
dump()
|
||||
qdel(src)
|
||||
if (2)
|
||||
if (prob(50))
|
||||
@@ -27,6 +28,13 @@
|
||||
src.health -= 5
|
||||
src.healthcheck()
|
||||
|
||||
/obj/structure/displaycase/examine(mob/user)
|
||||
..()
|
||||
if(showpiece)
|
||||
user << "<span class='notice'>There's [showpiece] inside.</span>"
|
||||
if(alert)
|
||||
user << "<span class='notice'>Hooked up with an anti-theft system.</span>"
|
||||
|
||||
|
||||
/obj/structure/displaycase/bullet_act(obj/item/projectile/Proj)
|
||||
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
@@ -35,16 +43,17 @@
|
||||
src.healthcheck()
|
||||
return
|
||||
|
||||
/obj/structure/displaycase/proc/dump()
|
||||
if (showpiece)
|
||||
showpiece.loc = src.loc
|
||||
showpiece = null
|
||||
|
||||
/obj/structure/displaycase/blob_act()
|
||||
if (prob(75))
|
||||
new /obj/item/weapon/shard( src.loc )
|
||||
if (occupied)
|
||||
new /obj/item/weapon/gun/energy/laser/captain( src.loc )
|
||||
occupied = 0
|
||||
dump()
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/structure/displaycase/proc/healthcheck()
|
||||
if (src.health <= 0)
|
||||
if (!( src.destroyed ))
|
||||
@@ -55,27 +64,76 @@
|
||||
update_icon()
|
||||
|
||||
//Activate Anti-theft
|
||||
var/area/alarmed = get_area(src)
|
||||
alarmed.burglaralert(src)
|
||||
playsound(src, "sound/effects/alert.ogg", 50, 1)
|
||||
if(alert)
|
||||
var/area/alarmed = get_area(src)
|
||||
alarmed.burglaralert(src)
|
||||
playsound(src, "sound/effects/alert.ogg", 50, 1)
|
||||
|
||||
else
|
||||
playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
|
||||
return
|
||||
|
||||
/obj/structure/displaycase/update_icon()
|
||||
if(src.destroyed)
|
||||
src.icon_state = "glassboxb[src.occupied]"
|
||||
/obj/structure/displaycase/proc/is_directional(atom/A)
|
||||
try
|
||||
getFlatIcon(A,defdir=4)
|
||||
catch
|
||||
return 0
|
||||
return 1
|
||||
/obj/structure/displaycase/proc/get_flat_icon_directional(atom/A)
|
||||
//Get flatIcon even if dir is mismatched for directionless icons
|
||||
//SLOW
|
||||
var/icon/I
|
||||
if(is_directional(A))
|
||||
I = getFlatIcon(A)
|
||||
else
|
||||
src.icon_state = "glassbox[src.occupied]"
|
||||
var/old_dir = A.dir
|
||||
A.dir = 2
|
||||
I = getFlatIcon(A)
|
||||
A.dir = old_dir
|
||||
return I
|
||||
|
||||
/obj/structure/displaycase/update_icon()
|
||||
var/icon/I
|
||||
if(open)
|
||||
I = icon('icons/obj/stationobjs.dmi',"glassbox_open")
|
||||
else
|
||||
I = icon('icons/obj/stationobjs.dmi',"glassbox0")
|
||||
if(destroyed)
|
||||
I = icon('icons/obj/stationobjs.dmi',"glassboxb0")
|
||||
if(showpiece)
|
||||
var/icon/S = get_flat_icon_directional(showpiece)
|
||||
S.Scale(17,17)
|
||||
I.Blend(S,ICON_UNDERLAY,8,8)
|
||||
src.icon = I
|
||||
return
|
||||
|
||||
|
||||
/obj/structure/displaycase/attackby(obj/item/weapon/W, mob/user, params)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
src.health -= W.force
|
||||
src.healthcheck()
|
||||
..()
|
||||
if(istype(W, /obj/item/weapon/card) && electronics && !destroyed && allowed(user))
|
||||
user << "<span class='notice'>You [open ? "close":"open"] the [src]</span>"
|
||||
open = !open
|
||||
update_icon()
|
||||
return
|
||||
if(!alert && istype(W,/obj/item/weapon/crowbar))
|
||||
if(destroyed && !showpiece)
|
||||
user << "<span class='notice'>You remove the destroyed case</span>"
|
||||
qdel(src)
|
||||
return
|
||||
user << "<span class='notice'>You start to [open ? "close":"open"] the [src]</span>"
|
||||
if(do_after(user, 20, target = src))
|
||||
user << "<span class='notice'>You [open ? "close":"open"] the [src]</span>"
|
||||
open = !open
|
||||
update_icon()
|
||||
else if(open)
|
||||
if(user.unEquip(W))
|
||||
W.loc = src
|
||||
showpiece = W
|
||||
user << "<span class='notice'>You put [W] on display</span>"
|
||||
update_icon()
|
||||
else
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
src.health -= W.force
|
||||
src.healthcheck()
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/structure/displaycase/attack_paw(mob/user)
|
||||
@@ -83,10 +141,9 @@
|
||||
|
||||
/obj/structure/displaycase/attack_hand(mob/user)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
if (src.destroyed && src.occupied)
|
||||
new /obj/item/weapon/gun/energy/laser/captain( src.loc )
|
||||
if (showpiece && (destroyed || open))
|
||||
dump()
|
||||
user << "<span class='notice'>You deactivate the hover field built into the case.</span>"
|
||||
src.occupied = 0
|
||||
src.add_fingerprint(user)
|
||||
update_icon()
|
||||
return
|
||||
@@ -98,3 +155,71 @@
|
||||
return
|
||||
|
||||
|
||||
/obj/structure/displaycase_chassis
|
||||
anchored = 1
|
||||
density = 0
|
||||
name = "display case chassis"
|
||||
desc = "wooden base of display case"
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "glassbox_chassis"
|
||||
var/obj/item/weapon/electronics/airlock/electronics
|
||||
|
||||
|
||||
/obj/structure/displaycase_chassis/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/wrench))
|
||||
user << "<span class='notice'>You start disassembling [src]...</span>"
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
if(do_after(user, 30, target = src))
|
||||
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
new /obj/item/stack/sheet/mineral/wood(get_turf(src))
|
||||
qdel(src)
|
||||
return
|
||||
if(istype(I, /obj/item/weapon/electronics/airlock))
|
||||
user << "<span class='notice'>You start installing the electronics into [src]...</span>"
|
||||
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
|
||||
if(user.unEquip(I) && do_after(user, 30, target = src))
|
||||
I.loc = src
|
||||
electronics = I
|
||||
user << "<span class='notice'>You install the airlock electronics.</span>"
|
||||
return
|
||||
if(istype(I, /obj/item/stack/sheet/glass))
|
||||
var/obj/item/stack/sheet/glass/G = I
|
||||
if(G.get_amount() < 10)
|
||||
user << "<span class='warning'>You need ten glass sheets to do this!</span>"
|
||||
return
|
||||
user << "<span class='notice'>You start adding [G] to [src]...</span>"
|
||||
if(do_after(user, 20, target = src))
|
||||
G.use(10)
|
||||
var/obj/structure/displaycase/display = new(src.loc)
|
||||
if(electronics)
|
||||
electronics.loc = display
|
||||
display.electronics = electronics
|
||||
if(electronics.use_one_access)
|
||||
display.req_one_access = electronics.conf_access
|
||||
else
|
||||
display.req_access = electronics.conf_access
|
||||
qdel(src)
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
/obj/structure/displaycase/captain
|
||||
alert = 1
|
||||
|
||||
/obj/structure/displaycase/captain/New()
|
||||
..()
|
||||
showpiece = new /obj/item/weapon/gun/energy/laser/captain (src)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/displaycase/labcage
|
||||
name = "lab cage"
|
||||
desc = "A glass lab container for storing interesting creatures."
|
||||
|
||||
/obj/structure/displaycase/labcage/New()
|
||||
..()
|
||||
var/obj/item/clothing/mask/facehugger/A = new /obj/item/clothing/mask/facehugger(src)
|
||||
A.sterile = 1
|
||||
A.name = "Lamarr"
|
||||
showpiece = A
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
/obj/structure/lamarr
|
||||
name = "lab cage"
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "labcage1"
|
||||
desc = "A glass lab container for storing interesting creatures."
|
||||
density = 1
|
||||
anchored = 1
|
||||
unacidable = 1//Dissolving the case would also delete Lamarr
|
||||
var/health = 30
|
||||
var/occupied = 1
|
||||
var/destroyed = 0
|
||||
|
||||
/obj/structure/lamarr/ex_act(severity, target)
|
||||
switch(severity)
|
||||
if (1)
|
||||
new /obj/item/weapon/shard( src.loc )
|
||||
Break()
|
||||
qdel(src)
|
||||
if (2)
|
||||
if (prob(50))
|
||||
src.health -= 15
|
||||
src.healthcheck()
|
||||
if (3)
|
||||
if (prob(50))
|
||||
src.health -= 5
|
||||
src.healthcheck()
|
||||
|
||||
|
||||
/obj/structure/lamarr/bullet_act(obj/item/projectile/Proj)
|
||||
health -= Proj.damage
|
||||
..()
|
||||
src.healthcheck()
|
||||
return
|
||||
|
||||
|
||||
/obj/structure/lamarr/blob_act()
|
||||
if (prob(75))
|
||||
new /obj/item/weapon/shard( src.loc )
|
||||
Break()
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/structure/lamarr/proc/healthcheck()
|
||||
if (src.health <= 0)
|
||||
if (!( src.destroyed ))
|
||||
src.density = 0
|
||||
src.destroyed = 1
|
||||
new /obj/item/weapon/shard( src.loc )
|
||||
playsound(src, "shatter", 70, 1)
|
||||
Break()
|
||||
else
|
||||
playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
|
||||
return
|
||||
|
||||
/obj/structure/lamarr/update_icon()
|
||||
if(src.destroyed)
|
||||
src.icon_state = "labcageb[src.occupied]"
|
||||
else
|
||||
src.icon_state = "labcage[src.occupied]"
|
||||
return
|
||||
|
||||
|
||||
/obj/structure/lamarr/attackby(obj/item/weapon/W, mob/user, params)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
src.health -= W.force
|
||||
src.healthcheck()
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/structure/lamarr/attack_paw(mob/user)
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/structure/lamarr/attack_hand(mob/user)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
if (src.destroyed)
|
||||
return
|
||||
else
|
||||
user.visible_message("<span class='warning'>[user] kicks the lab cage.</span>", \
|
||||
"<span class='danger'>You kick the lab cage.</span>")
|
||||
src.health -= 2
|
||||
healthcheck()
|
||||
return
|
||||
|
||||
/obj/structure/lamarr/proc/Break()
|
||||
if(occupied)
|
||||
var/obj/item/clothing/mask/facehugger/A = new /obj/item/clothing/mask/facehugger( src.loc )
|
||||
A.sterile = 1
|
||||
A.name = "Lamarr"
|
||||
occupied = 0
|
||||
update_icon()
|
||||
return
|
||||
@@ -148,16 +148,17 @@
|
||||
var/racechoice = input(H, "What are we again?", "Race change") as null|anything in choosable_races
|
||||
newrace = species_list[racechoice]
|
||||
|
||||
if(!newrace || !H.dna)
|
||||
if(!newrace)
|
||||
return
|
||||
|
||||
hardset_dna(H, null, null, null, null, newrace)
|
||||
H.set_species(newrace, icon_update=0)
|
||||
|
||||
if(H.dna.species.use_skintones)
|
||||
var/new_s_tone = input(user, "Choose your skin tone:", "Race change") as null|anything in skin_tones
|
||||
|
||||
if(new_s_tone)
|
||||
H.skin_tone = new_s_tone
|
||||
H.dna.update_ui_block(DNA_SKIN_TONE_BLOCK)
|
||||
|
||||
if(MUTCOLORS in H.dna.species.specflags)
|
||||
var/new_mutantcolor = input(user, "Choose your skin color:", "Race change") as color|null
|
||||
@@ -170,7 +171,10 @@
|
||||
else
|
||||
H << "<span class='notice'>Invalid color. Your color is not bright enough.</span>"
|
||||
|
||||
H.regenerate_icons()
|
||||
H.update_body()
|
||||
H.update_hair()
|
||||
H.update_mutcolor()
|
||||
H.update_mutations_overlay() // no hulk lizard
|
||||
|
||||
if("gender")
|
||||
if(!(H.gender in list("male", "female"))) //blame the patriarchy
|
||||
@@ -180,12 +184,19 @@
|
||||
if(alert(H, "Become a Witch?", "Confirmation", "Yes", "No") == "Yes")
|
||||
H.gender = "female"
|
||||
H << "<span class='notice'>Man, you feel like a woman!</span>"
|
||||
H.regenerate_icons()
|
||||
else
|
||||
return
|
||||
|
||||
else
|
||||
if(alert(H, "Become a Warlock?", "Confirmation", "Yes", "No") == "Yes")
|
||||
H.gender = "male"
|
||||
H << "<span class='notice'>Whoa man, you feel like a man!</span>"
|
||||
H.regenerate_icons()
|
||||
else
|
||||
return
|
||||
H.dna.update_ui_block(DNA_GENDER_BLOCK)
|
||||
H.update_body()
|
||||
H.update_mutations_overlay() //(hulk male/female)
|
||||
|
||||
|
||||
if("hair")
|
||||
var/hairchoice = alert(H, "Hair style or hair color?", "Change Hair", "Style", "Color")
|
||||
@@ -196,15 +207,17 @@
|
||||
var/new_hair_color = input(H, "Choose your hair color", "Hair Color") as null|color
|
||||
if(new_hair_color)
|
||||
H.hair_color = sanitize_hexcolor(new_hair_color)
|
||||
H.dna.update_ui_block(DNA_HAIR_COLOR_BLOCK)
|
||||
if(H.gender == "male")
|
||||
var/new_face_color = input(H, "Choose your facial hair color", "Hair Color") as null|color
|
||||
if(new_face_color)
|
||||
H.facial_hair_color = sanitize_hexcolor(new_face_color)
|
||||
|
||||
H.dna.update_ui_block(DNA_FACIAL_HAIR_COLOR_BLOCK)
|
||||
H.update_hair()
|
||||
|
||||
if("eyes")
|
||||
var/new_eye_color = input(H, "Choose your eye color", "Eye Color") as null|color
|
||||
if(new_eye_color)
|
||||
H.eye_color = sanitize_hexcolor(new_eye_color)
|
||||
H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK)
|
||||
H.update_body()
|
||||
@@ -9,11 +9,7 @@
|
||||
var/to_be_destroyed = 0 //Used for fire, if a melting temperature was reached, it will be destroyed
|
||||
var/max_fire_temperature_sustained = 0 //The max temperature of the fire which it was subjected to
|
||||
|
||||
/turf/simulated/New()
|
||||
..()
|
||||
levelupdate()
|
||||
if(smooth)
|
||||
smooth_icon(src)
|
||||
|
||||
|
||||
/turf/simulated/proc/burn_tile()
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
/turf/simulated/wall/cult/break_wall()
|
||||
new /obj/effect/decal/cleanable/blood(src)
|
||||
new /obj/structure/cultgirder(src)
|
||||
return (new /obj/structure/cultgirder(src))
|
||||
|
||||
/turf/simulated/wall/cult/devastate_wall()
|
||||
new /obj/effect/decal/cleanable/blood(src)
|
||||
|
||||
+10
-1
@@ -26,11 +26,13 @@
|
||||
|
||||
flags = 0
|
||||
|
||||
var/image/obscured //camerachunks
|
||||
|
||||
/turf/New()
|
||||
..()
|
||||
for(var/atom/movable/AM in src)
|
||||
Entered(AM)
|
||||
return
|
||||
|
||||
/turf/Destroy()
|
||||
return QDEL_HINT_HARDDEL_NOW
|
||||
|
||||
@@ -196,6 +198,10 @@
|
||||
flags |= NOJAUNT
|
||||
|
||||
/turf/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
|
||||
if(src_object.contents.len)
|
||||
usr << "<span class='notice'>You start dumping out the contents...</span>"
|
||||
if(!do_after(usr,20,target=src_object))
|
||||
return 0
|
||||
for(var/obj/item/I in src_object)
|
||||
if(user.s_active != src_object)
|
||||
if(I.on_found(user))
|
||||
@@ -281,6 +287,9 @@
|
||||
/turf/proc/can_lay_cable()
|
||||
return can_have_cabling() & !intact
|
||||
|
||||
/turf/proc/visibilityChanged()
|
||||
if(ticker)
|
||||
cameranet.updateVisibility(src)
|
||||
|
||||
/turf/indestructible
|
||||
name = "wall"
|
||||
|
||||
@@ -220,7 +220,7 @@
|
||||
var/dat = "<B>Showing DNA from blood.</B><HR>"
|
||||
dat += "<table cellspacing=5><tr><th>Name</th><th>DNA</th><th>Blood Type</th></tr>"
|
||||
for(var/mob/living/carbon/human/H in mob_list)
|
||||
if(H.dna && H.ckey)
|
||||
if(H.ckey)
|
||||
dat += "<tr><td>[H]</td><td>[H.dna.unique_enzymes]</td><td>[H.dna.blood_type]</td></tr>"
|
||||
dat += "</table>"
|
||||
usr << browse(dat, "window=DNA;size=440x410")
|
||||
@@ -231,12 +231,7 @@
|
||||
dat += "<table cellspacing=5><tr><th>Name</th><th>Fingerprints</th></tr>"
|
||||
for(var/mob/living/carbon/human/H in mob_list)
|
||||
if(H.ckey)
|
||||
if(H.dna && H.dna.uni_identity)
|
||||
dat += "<tr><td>[H]</td><td>[md5(H.dna.uni_identity)]</td></tr>"
|
||||
else if(H.dna && !H.dna.uni_identity)
|
||||
dat += "<tr><td>[H]</td><td>H.dna.uni_identity = null</td></tr>"
|
||||
else if(!H.dna)
|
||||
dat += "<tr><td>[H]</td><td>H.dna = null</td></tr>"
|
||||
dat += "<tr><td>[H]</td><td>[md5(H.dna.uni_identity)]</td></tr>"
|
||||
dat += "</table>"
|
||||
usr << browse(dat, "window=fingerprints;size=440x410")
|
||||
|
||||
@@ -259,8 +254,7 @@
|
||||
message_admins("\blue [key_name_admin(usr)] turned all humans into [result]")
|
||||
var/newtype = species_list[result]
|
||||
for(var/mob/living/carbon/human/H in mob_list)
|
||||
hardset_dna(H, null, null, null, null, newtype)
|
||||
H.regenerate_icons()
|
||||
H.set_species(newtype)
|
||||
|
||||
if("corgi")
|
||||
if(!check_rights(R_FUN))
|
||||
|
||||
@@ -1527,7 +1527,6 @@
|
||||
var/client/C = usr.client
|
||||
if(!isobserver(usr)) C.admin_ghost()
|
||||
var/mob/dead/observer/A = C.mob
|
||||
sleep(2)
|
||||
A.ManualFollow(M)
|
||||
log_admin("[key_name(usr)] followed [key_name(M)]")
|
||||
message_admins("[key_name_admin(usr)] followed [key_name_admin(M)]")
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
for (var/mob/M in player_list)
|
||||
if (istype(M, /mob/new_player))
|
||||
continue
|
||||
if (M.stat == DEAD || (M.client && M.client.holder && (M.client.prefs.chat_toggles & CHAT_DEAD))) //admins can toggle deadchat on and off. This is a proc in admin.dm and is only give to Administrators and above
|
||||
if (M.stat == DEAD || istype(M, /mob/living/simple_animal/revenant) || (M.client && M.client.holder && (M.client.prefs.chat_toggles & CHAT_DEAD))) //admins can toggle deadchat on and off. This is a proc in admin.dm and is only give to Administrators and above
|
||||
M.show_message(rendered, 2)
|
||||
|
||||
feedback_add_details("admin_verb","D") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
@@ -232,7 +232,7 @@
|
||||
/datum/admins/proc/makeNukeTeam()
|
||||
|
||||
var/datum/game_mode/nuclear/temp = new
|
||||
var/list/mob/dead/observer/candidates = getCandidates("Do you wish to be considered for a nuke team being sent in?", "operative", temp)
|
||||
var/list/mob/dead/observer/candidates = pollCandidates("Do you wish to be considered for a nuke team being sent in?", "operative", temp)
|
||||
var/list/mob/dead/observer/chosen = list()
|
||||
var/mob/dead/observer/theghost = null
|
||||
|
||||
@@ -306,7 +306,7 @@
|
||||
// DEATH SQUADS
|
||||
/datum/admins/proc/makeDeathsquad()
|
||||
var/mission = input("Assign a mission to the deathsquad", "Assign Mission", "Leave no witnesses.")
|
||||
var/list/mob/dead/observer/candidates = getCandidates("Do you wish to be considered for an elite Nanotrasen Strike Team?", "deathsquad", null)
|
||||
var/list/mob/dead/observer/candidates = pollCandidates("Do you wish to be considered for an elite Nanotrasen Strike Team?", "deathsquad", null)
|
||||
var/squadSpawned = 0
|
||||
|
||||
if(candidates.len >= 2) //Minimum 2 to be considered a squad
|
||||
@@ -326,13 +326,13 @@
|
||||
//Spawn and equip the commando
|
||||
var/mob/living/carbon/human/Commando = new(spawnloc)
|
||||
chosen_candidate.client.prefs.copy_to(Commando)
|
||||
ready_dna(Commando)
|
||||
if(numagents == 1) //If Squad Leader
|
||||
Commando.real_name = "Officer [pick(commando_names)]"
|
||||
Commando.equipOutfit(/datum/outfit/death_commando/officer)
|
||||
else
|
||||
Commando.real_name = "Trooper [pick(commando_names)]"
|
||||
Commando.equipOutfit(/datum/outfit/death_commando)
|
||||
Commando.dna.update_dna_identity()
|
||||
Commando.key = chosen_candidate.key
|
||||
Commando.mind.assigned_role = "Death Commando"
|
||||
for(var/obj/machinery/door/poddoor/ert/door in airlocks)
|
||||
@@ -412,7 +412,7 @@
|
||||
|
||||
/datum/admins/proc/makeOfficial()
|
||||
var/mission = input("Assign a task for the official", "Assign Task", "Conduct a routine preformance review of [station_name()] and its Captain.")
|
||||
var/list/mob/dead/observer/candidates = getCandidates("Do you wish to be considered to be a Centcom Official?", "pAI")
|
||||
var/list/mob/dead/observer/candidates = pollCandidates("Do you wish to be considered to be a Centcom Official?", "pAI")
|
||||
|
||||
if(candidates.len)
|
||||
var/mob/dead/observer/chosen_candidate = pick(candidates)
|
||||
@@ -420,8 +420,8 @@
|
||||
//Create the official
|
||||
var/mob/living/carbon/human/newmob = new (pick(emergencyresponseteamspawn))
|
||||
chosen_candidate.client.prefs.copy_to(newmob)
|
||||
ready_dna(newmob)
|
||||
newmob.real_name = newmob.dna.species.random_name(newmob.gender,1)
|
||||
newmob.dna.update_dna_identity()
|
||||
newmob.key = chosen_candidate.key
|
||||
newmob.mind.assigned_role = "Centcom Official"
|
||||
newmob.equipOutfit(/datum/outfit/centcom_official)
|
||||
@@ -465,7 +465,7 @@
|
||||
return makeOfficial()
|
||||
var/teamsize = min(7,input("Maximum size of team? (7 max)", "Select Team Size",4) as null|num)
|
||||
var/mission = input("Assign a mission to the Emergency Response Team", "Assign Mission", "Assist the station.")
|
||||
var/list/mob/dead/observer/candidates = getCandidates("Do you wish to be considered for a Code [alert] Nanotrasen Emergency Response Team?", "deathsquad", null)
|
||||
var/list/mob/dead/observer/candidates = pollCandidates("Do you wish to be considered for a Code [alert] Nanotrasen Emergency Response Team?", "deathsquad", null)
|
||||
var/teamSpawned = 0
|
||||
|
||||
if(candidates.len > 0)
|
||||
@@ -490,7 +490,6 @@
|
||||
var/mob/living/carbon/human/ERTOperative = new(spawnloc)
|
||||
var/list/lastname = last_names
|
||||
chosen_candidate.client.prefs.copy_to(ERTOperative)
|
||||
ready_dna(ERTOperative)
|
||||
var/ertname = pick(lastname)
|
||||
switch(numagents)
|
||||
if(1)
|
||||
@@ -514,6 +513,7 @@
|
||||
if(7)
|
||||
ERTOperative.real_name = "Engineer [ertname]"
|
||||
ERTOperative.equipOutfit(redalert ? /datum/outfit/ert/engineer/alert : /datum/outfit/ert/engineer)
|
||||
ERTOperative.dna.update_dna_identity()
|
||||
ERTOperative.key = chosen_candidate.key
|
||||
ERTOperative.mind.assigned_role = "ERT"
|
||||
|
||||
@@ -558,50 +558,11 @@
|
||||
|
||||
//Abductors
|
||||
/datum/admins/proc/makeAbductorTeam()
|
||||
var/list/mob/dead/observer/candidates = getCandidates("Do you wish to be considered for an Abductor Team?", "abductor", null)
|
||||
|
||||
if(candidates.len >= 2)
|
||||
//Oh god why we can't have static functions
|
||||
var/number = ticker.mode.abductor_teams + 1
|
||||
|
||||
var/datum/game_mode/abduction/temp
|
||||
if(ticker.mode.config_tag == "abduction")
|
||||
temp = ticker.mode
|
||||
else
|
||||
temp = new
|
||||
|
||||
var/agent_mind = pick(candidates)
|
||||
candidates -= agent_mind
|
||||
var/scientist_mind = pick(candidates)
|
||||
|
||||
var/mob/living/carbon/human/agent=makeBody(agent_mind)
|
||||
var/mob/living/carbon/human/scientist=makeBody(scientist_mind)
|
||||
|
||||
agent_mind = agent.mind
|
||||
scientist_mind = scientist.mind
|
||||
|
||||
temp.scientists.len = number
|
||||
temp.agents.len = number
|
||||
temp.abductors.len = 2*number
|
||||
temp.team_objectives.len = number
|
||||
temp.team_names.len = number
|
||||
temp.scientists[number] = scientist_mind
|
||||
temp.agents[number] = agent_mind
|
||||
temp.abductors |= list(agent_mind,scientist_mind)
|
||||
temp.make_abductor_team(number,preset_scientist=scientist_mind,preset_agent=agent_mind)
|
||||
temp.post_setup_team(number)
|
||||
|
||||
ticker.mode.abductor_teams++
|
||||
|
||||
if(ticker.mode.config_tag != "abduction")
|
||||
ticker.mode.abductors |= temp.abductors
|
||||
|
||||
return 1
|
||||
else
|
||||
return
|
||||
new /datum/round_event/abductor
|
||||
return 1
|
||||
|
||||
/datum/admins/proc/makeRevenant()
|
||||
var/list/mob/dead/observer/candidates = getCandidates("Do you wish to be considered for becoming a revenant?", "revenant", null)
|
||||
var/list/mob/dead/observer/candidates = pollCandidates("Do you wish to be considered for becoming a revenant?", "revenant", null)
|
||||
if(candidates.len >= 1)
|
||||
var/spook_op = pick(candidates)
|
||||
var/mob/dead/observer/O = spook_op
|
||||
@@ -643,54 +604,3 @@
|
||||
candidates.Remove(H)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/admins/proc/getCandidates(var/Question, var/jobbanType, var/datum/game_mode/gametypeCheck)
|
||||
var/list/mob/dead/observer/candidates = list()
|
||||
var/time_passed = world.time
|
||||
if (!Question)
|
||||
Question = "Would you like to be a special role?"
|
||||
|
||||
for(var/mob/dead/observer/G in player_list)
|
||||
if(!G.key || !G.client)
|
||||
continue
|
||||
if (gametypeCheck)
|
||||
if(!gametypeCheck.age_check(G.client))
|
||||
continue
|
||||
if (jobbanType)
|
||||
if(jobban_isbanned(G, jobbanType) || jobban_isbanned(G, "Syndicate"))
|
||||
continue
|
||||
spawn(0)
|
||||
G << 'sound/misc/notice2.ogg' //Alerting them to their consideration
|
||||
switch(alert(G,Question,"Please answer in 30 seconds!","Yes","No"))
|
||||
if("Yes")
|
||||
G << "<span class='notice'>Choice registered: Yes.</span>"
|
||||
if((world.time-time_passed)>300)//If more than 30 game seconds passed.
|
||||
G << "<span class='danger'>Sorry, you were too late for the consideration!</span>"
|
||||
G << 'sound/machines/buzz-sigh.ogg'
|
||||
return
|
||||
candidates += G
|
||||
if("No")
|
||||
G << "<span class='danger'>Choice registered: No.</span>"
|
||||
return
|
||||
else
|
||||
return
|
||||
sleep(300)
|
||||
|
||||
//Check all our candidates, to make sure they didn't log off during the 30 second wait period.
|
||||
for(var/mob/dead/observer/G in candidates)
|
||||
if(!G.key || !G.client)
|
||||
candidates.Remove(G)
|
||||
|
||||
return candidates
|
||||
|
||||
/datum/admins/proc/makeBody(mob/dead/observer/G_found) // Uses stripped down and bastardized code from respawn character
|
||||
if(!G_found || !G_found.key) return
|
||||
|
||||
//First we spawn a dude.
|
||||
var/mob/living/carbon/human/new_character = new(pick(latejoin))//The mob being spawned.
|
||||
|
||||
G_found.client.prefs.copy_to(new_character)
|
||||
ready_dna(new_character)
|
||||
new_character.key = G_found.key
|
||||
|
||||
return new_character
|
||||
|
||||
@@ -300,15 +300,13 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
new_character.real_name = record_found.fields["name"]
|
||||
new_character.gender = record_found.fields["sex"]
|
||||
new_character.age = record_found.fields["age"]
|
||||
new_character.dna.blood_type = record_found.fields["blood_type"]
|
||||
new_character.hardset_dna(record_found.fields["identity"], record_found.fields["enzymes"], record_found.fields["name"], record_found.fields["blood_type"], record_found.fields["species"], record_found.fields["features"])
|
||||
else
|
||||
new_character.gender = pick(MALE,FEMALE)
|
||||
var/datum/preferences/A = new()
|
||||
A.real_name = G_found.real_name
|
||||
A.copy_to(new_character)
|
||||
A.real_name = G_found.real_name
|
||||
new_character.dna.update_dna_identity()
|
||||
|
||||
if(!new_character.real_name)
|
||||
new_character.real_name = new_character.dna.species.random_name(new_character.gender,1)
|
||||
new_character.name = new_character.real_name
|
||||
|
||||
if(G_found.mind && !G_found.mind.active)
|
||||
@@ -316,13 +314,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
new_character.mind.special_verbs = list()
|
||||
else
|
||||
new_character.mind_initialize()
|
||||
if(!new_character.mind.assigned_role) new_character.mind.assigned_role = "Assistant"//If they somehow got a null assigned role.
|
||||
|
||||
//DNA
|
||||
if(record_found)//Pull up their name from database records if they did have a mind.
|
||||
hardset_dna(new_character, record_found.fields["identity"], record_found.fields["enzymes"], record_found.fields["name"], record_found.fields["blood_type"], record_found.fields["species"], record_found.fields["features"])
|
||||
else//If they have no records, we just do a random DNA for them, based on their random appearance/savefile.
|
||||
ready_dna(new_character)
|
||||
if(!new_character.mind.assigned_role)
|
||||
new_character.mind.assigned_role = "Assistant"//If they somehow got a null assigned role.
|
||||
|
||||
new_character.key = G_found.key
|
||||
|
||||
@@ -822,7 +815,7 @@ var/list/datum/outfit/custom_outfits = list() //Admin created outfits
|
||||
id_select += "<option value=\"[path]\">[path]</option>"
|
||||
id_select += "</select>"
|
||||
|
||||
var/dat = {"
|
||||
var/dat = {"
|
||||
<html><head><title>Create Outfit</title></head><body>
|
||||
<form name="outfit" action="byond://?src=\ref[src]" method="get">
|
||||
<input type="hidden" name="src" value="\ref[src]">
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
var/turf/T = get_turf(src)
|
||||
T.visible_message("<span class='disarm'>[src] emits a blinding light!</span>")
|
||||
for(var/mob/living/carbon/M in viewers(3, null))
|
||||
flash_carbon(M, null, 2, 0)
|
||||
flash_carbon(M, null, 5, 0)
|
||||
|
||||
|
||||
/obj/item/device/assembly/flash/proc/burn_out() //Made so you can override it if you want to have an invincible flash from R&D or something.
|
||||
@@ -79,7 +79,7 @@
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/device/assembly/flash/proc/flash_carbon(mob/living/carbon/M, mob/user = null, power = 5, targeted = 1)
|
||||
/obj/item/device/assembly/flash/proc/flash_carbon(mob/living/carbon/M, mob/user = null, power = 15, targeted = 1)
|
||||
add_logs(user, M, "flashed", src)
|
||||
if(user && targeted)
|
||||
if(M.weakeyes)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
var/obj/machinery/gateway/centerstation/the_gateway = null
|
||||
|
||||
/obj/machinery/gateway
|
||||
name = "gateway"
|
||||
desc = "A mysterious gateway built by unknown hands, it allows for faster than light travel to far-flung locations."
|
||||
@@ -9,6 +11,18 @@
|
||||
var/active = 0
|
||||
|
||||
|
||||
/obj/machinery/gateway/centerstation/New()
|
||||
..()
|
||||
if(!the_gateway)
|
||||
the_gateway = src
|
||||
|
||||
|
||||
/obj/machinery/gateway/centerstation/Destroy()
|
||||
if(the_gateway == src)
|
||||
the_gateway = null
|
||||
..()
|
||||
|
||||
|
||||
/obj/machinery/gateway/initialize()
|
||||
update_icon()
|
||||
if(dir == 2)
|
||||
|
||||
@@ -80,20 +80,17 @@
|
||||
user.dna.add_mutation(LASEREYES)
|
||||
user.dna.add_mutation(COLDRES)
|
||||
user.dna.add_mutation(XRAY)
|
||||
hardset_dna(user, null, null, null, null, /datum/species/shadow)
|
||||
user.regenerate_icons()
|
||||
user.set_species(/datum/species/shadow)
|
||||
if("Wealth")
|
||||
user << "<B>Your wish is granted, but at a terrible cost...</B>"
|
||||
user << "The Wish Granter punishes you for your selfishness, claiming your soul and warping your body to match the darkness in your heart."
|
||||
new /obj/structure/closet/syndicate/resources/everything(loc)
|
||||
hardset_dna(user, null, null, null, null, /datum/species/shadow)
|
||||
user.regenerate_icons()
|
||||
user.set_species(/datum/species/shadow)
|
||||
if("Immortality")
|
||||
user << "<B>Your wish is granted, but at a terrible cost...</B>"
|
||||
user << "The Wish Granter punishes you for your selfishness, claiming your soul and warping your body to match the darkness in your heart."
|
||||
user.verbs += /mob/living/carbon/proc/immortality
|
||||
hardset_dna(user, null, null, null, null, /datum/species/shadow)
|
||||
user.regenerate_icons()
|
||||
user.set_species(/datum/species/shadow)
|
||||
if("To Kill")
|
||||
user << "<B>Your wish is granted, but at a terrible cost...</B>"
|
||||
user << "The Wish Granter punishes you for your wickedness, claiming your soul and warping your body to match the darkness in your heart."
|
||||
@@ -107,8 +104,7 @@
|
||||
for(var/datum/objective/OBJ in user.mind.objectives)
|
||||
user << "<B>Objective #[obj_count]</B>: [OBJ.explanation_text]"
|
||||
obj_count++
|
||||
hardset_dna(user, null, null, null, null, /datum/species/shadow)
|
||||
user.regenerate_icons()
|
||||
user.set_species(/datum/species/shadow)
|
||||
if("Peace")
|
||||
user << "<B>Whatever alien sentience that the Wish Granter possesses is satisfied with your wish. There is a distant wailing as the last of the Faithless begin to die, then silence.</B>"
|
||||
user << "You feel as if you just narrowly avoided a terrible fate..."
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user