mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-27 02:22:26 +00:00
Merge remote-tracking branch 'Aurorastation/development' into SQL-backend-import
# Conflicts: # code/modules/admin/admin.dm # code/modules/admin/admin_verbs.dm All conflicts cleared. Wind funciton needs a quick redo as a result.
This commit is contained in:
@@ -149,8 +149,10 @@ Works together with spawning an observer, noted above.
|
||||
if(key)
|
||||
var/mob/dead/observer/ghost = new(src) //Transfer safety to observer spawning proc.
|
||||
ghost.can_reenter_corpse = can_reenter_corpse
|
||||
ghost.timeofdeath = src.timeofdeath //BS12 EDIT
|
||||
ghost.timeofdeath = src.stat == DEAD ? src.timeofdeath : world.time
|
||||
ghost.key = key
|
||||
if(ghost.client)
|
||||
ghost.client.time_died_as_mouse = ghost.timeofdeath
|
||||
if(ghost.client && !ghost.client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
|
||||
ghost.verbs -= /mob/dead/observer/verb/toggle_antagHUD // Poor guys, don't know what they are missing!
|
||||
return ghost
|
||||
@@ -217,7 +219,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
return
|
||||
mind.current.ajourn=0
|
||||
mind.current.key = key
|
||||
mind.current.aghosted = null
|
||||
mind.current.teleop = null
|
||||
if(!admin_ghosted)
|
||||
announce_ghost_joinleave(mind, 0, "They now occupy their body again.")
|
||||
return 1
|
||||
@@ -422,6 +424,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
if(!MayRespawn(1))
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T || (T.z in config.admin_levels))
|
||||
src << "<span class='warning'>You may not spawn as a mouse on this Z-level.</span>"
|
||||
return
|
||||
|
||||
var/timedifference = world.time - client.time_died_as_mouse
|
||||
if(client.time_died_as_mouse && timedifference <= mouse_respawn_time * 600)
|
||||
var/timedifference_text
|
||||
@@ -437,8 +444,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
var/mob/living/simple_animal/mouse/host
|
||||
var/obj/machinery/atmospherics/unary/vent_pump/vent_found
|
||||
var/list/found_vents = list()
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/v in world)
|
||||
if(!v.welded && v.z == src.z)
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/v in machines)
|
||||
if(!v.welded && v.z == T.z)
|
||||
found_vents.Add(v)
|
||||
if(found_vents.len)
|
||||
vent_found = pick(found_vents)
|
||||
|
||||
@@ -103,64 +103,34 @@ var/list/slot_equipment_priority = list( \
|
||||
|
||||
//Puts the item into your l_hand if possible and calls all necessary triggers/updates. returns 1 on success.
|
||||
/mob/proc/put_in_l_hand(var/obj/item/W)
|
||||
if(lying) return 0
|
||||
if(!istype(W)) return 0
|
||||
if(!l_hand)
|
||||
W.forceMove(src) //TODO: move to equipped?
|
||||
l_hand = W
|
||||
W.layer = 20 //TODO: move to equipped?
|
||||
// l_hand.screen_loc = ui_lhand
|
||||
W.equipped(src,slot_l_hand)
|
||||
if(client) client.screen |= W
|
||||
if(pulling == W) stop_pulling()
|
||||
update_inv_l_hand()
|
||||
return 1
|
||||
return 0
|
||||
if(lying || !istype(W))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
//Puts the item into your r_hand if possible and calls all necessary triggers/updates. returns 1 on success.
|
||||
/mob/proc/put_in_r_hand(var/obj/item/W)
|
||||
if(lying) return 0
|
||||
if(!istype(W)) return 0
|
||||
if(!r_hand)
|
||||
W.forceMove(src)
|
||||
r_hand = W
|
||||
W.layer = 20
|
||||
// r_hand.screen_loc = ui_rhand
|
||||
W.equipped(src,slot_r_hand)
|
||||
if(client) client.screen |= W
|
||||
if(pulling == W) stop_pulling()
|
||||
update_inv_r_hand()
|
||||
return 1
|
||||
return 0
|
||||
if(lying || !istype(W))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
//Puts the item into our active hand if possible. returns 1 on success.
|
||||
/mob/proc/put_in_active_hand(var/obj/item/W)
|
||||
if(hand) return put_in_l_hand(W)
|
||||
else return put_in_r_hand(W)
|
||||
return 0 // Moved to human procs because only they need to use hands.
|
||||
|
||||
//Puts the item into our inactive hand if possible. returns 1 on success.
|
||||
/mob/proc/put_in_inactive_hand(var/obj/item/W)
|
||||
if(hand) return put_in_r_hand(W)
|
||||
else return put_in_l_hand(W)
|
||||
return 0 // As above.
|
||||
|
||||
//Puts the item our active hand if possible. Failing that it tries our inactive hand. Returns 1 on success.
|
||||
//If both fail it drops it on the floor and returns 0.
|
||||
//This is probably the main one you need to know :)
|
||||
/mob/proc/put_in_hands(var/obj/item/W)
|
||||
if(!W) return 0
|
||||
if(put_in_active_hand(W))
|
||||
update_inv_l_hand()
|
||||
update_inv_r_hand()
|
||||
return 1
|
||||
else if(put_in_inactive_hand(W))
|
||||
update_inv_l_hand()
|
||||
update_inv_r_hand()
|
||||
return 1
|
||||
else
|
||||
W.forceMove(get_turf(src))
|
||||
W.layer = initial(W.layer)
|
||||
W.dropped()
|
||||
if(!W)
|
||||
return 0
|
||||
W.forceMove(get_turf(src))
|
||||
W.layer = initial(W.layer)
|
||||
W.dropped()
|
||||
return 0
|
||||
|
||||
// Removes an item from inventory and places it in the target atom.
|
||||
// If canremove or other conditions need to be checked then use unEquip instead.
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
|
||||
var/datum/language/new_language = all_languages[language]
|
||||
|
||||
if(!istype(new_language) || new_language in languages)
|
||||
if(!istype(new_language) || (new_language in languages))
|
||||
return 0
|
||||
|
||||
languages.Add(new_language)
|
||||
@@ -188,4 +188,10 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/proc/transfer_languages(var/mob/source, var/mob/target, var/except_flags)
|
||||
for(var/datum/language/L in source.languages)
|
||||
if(L.flags & except_flags)
|
||||
continue
|
||||
target.add_language(L.name)
|
||||
|
||||
#undef SCRAMBLE_CACHE_LEN
|
||||
|
||||
@@ -66,6 +66,15 @@
|
||||
flags = WHITELISTED
|
||||
syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","*","!")
|
||||
|
||||
/datum/language/vaurcese
|
||||
name = "Vaurcese"
|
||||
desc = "Vaurca native language made of clicks and sputters, \"It's a bugs life.\""
|
||||
speech_verb = "clicks"
|
||||
colour = "vaurca"
|
||||
key = "p"
|
||||
flags = WHITELISTED
|
||||
syllables = list("kic","klic","\'tic","kit","lit","xic","vil","xrit","tshh","qix","qlit","zix","\'","!")
|
||||
|
||||
/datum/language/human
|
||||
name = "Sol Common"
|
||||
desc = "A bastardized hybrid of informal English and elements of Mandarin Chinese; the common language of the Sol system."
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
var/blood = 1
|
||||
var/list/target_types = list()
|
||||
|
||||
var/maximum_search_range = 7
|
||||
|
||||
/mob/living/bot/cleanbot/New()
|
||||
..()
|
||||
get_targets()
|
||||
@@ -36,6 +38,25 @@
|
||||
if(radio_controller)
|
||||
radio_controller.add_object(listener, beacon_freq, filter = RADIO_NAVBEACONS)
|
||||
|
||||
/mob/living/bot/cleanbot/proc/handle_target()
|
||||
if(loc == target.loc)
|
||||
if(!cleaning)
|
||||
UnarmedAttack(target)
|
||||
return 1
|
||||
if(!path.len)
|
||||
// spawn(0)
|
||||
path = AStar(loc, target.loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30, id = botcard)
|
||||
if(!path)
|
||||
custom_emote(2, "[src] can't reach the target and is giving up.")
|
||||
target = null
|
||||
path = list()
|
||||
return
|
||||
if(path.len)
|
||||
step_to(src, path[1])
|
||||
path -= path[1]
|
||||
return 1
|
||||
return
|
||||
|
||||
/mob/living/bot/cleanbot/Life()
|
||||
..()
|
||||
|
||||
@@ -46,7 +67,7 @@
|
||||
return
|
||||
if(cleaning)
|
||||
return
|
||||
|
||||
|
||||
if(!screwloose && !oddbutton && prob(5))
|
||||
custom_emote(2, "makes an excited beeping booping sound!")
|
||||
|
||||
@@ -74,65 +95,64 @@
|
||||
spawn(600)
|
||||
ignorelist -= gib
|
||||
|
||||
if(!target) // Find a target
|
||||
for(var/obj/effect/decal/cleanable/D in view(7, src))
|
||||
if(D in ignorelist)
|
||||
continue
|
||||
for(var/T in target_types)
|
||||
if(istype(D, T))
|
||||
target = D
|
||||
patrol_path = list()
|
||||
// Find a target
|
||||
|
||||
if(pulledby) // Don't wiggle if someone pulls you
|
||||
patrol_path = list()
|
||||
return
|
||||
|
||||
if(!target) // No targets in range
|
||||
if(!should_patrol)
|
||||
return
|
||||
var/found_spot
|
||||
search_loop:
|
||||
for(var/i=0, i <= maximum_search_range, i++)
|
||||
for(var/obj/effect/decal/cleanable/D in view(i, src))
|
||||
if(D in ignorelist)
|
||||
continue
|
||||
for(var/T in target_types)
|
||||
if(istype(D, T))
|
||||
patrol_path = list()
|
||||
target = D
|
||||
found_spot = handle_target()
|
||||
if (found_spot)
|
||||
break search_loop
|
||||
else
|
||||
target = null
|
||||
continue // no need to check the other types
|
||||
|
||||
if(!patrol_path || !patrol_path.len)
|
||||
if(!signal_sent || signal_sent > world.time + 200) // Waited enough or didn't send yet
|
||||
var/datum/radio_frequency/frequency = radio_controller.return_frequency(beacon_freq)
|
||||
if(!frequency)
|
||||
return
|
||||
|
||||
closest_dist = 9999
|
||||
next_dest = null
|
||||
next_dest_loc = null
|
||||
|
||||
var/datum/signal/signal = new()
|
||||
signal.source = src
|
||||
signal.transmission_method = 1
|
||||
signal.data = list("findbeakon" = "patrol")
|
||||
frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS)
|
||||
signal_sent = world.time
|
||||
else
|
||||
if(next_dest)
|
||||
next_dest_loc = listener.memorized[next_dest]
|
||||
if(next_dest_loc)
|
||||
patrol_path = AStar(loc, next_dest_loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id = botcard, exclude = null)
|
||||
signal_sent = 0
|
||||
else
|
||||
if(pulledby) // Don't wiggle if someone pulls you
|
||||
patrol_path = list()
|
||||
if(!found_spot && !target) // No targets in range
|
||||
if(!patrol_path || !patrol_path.len)
|
||||
if(!signal_sent || signal_sent > world.time + 200) // Waited enough or didn't send yet
|
||||
var/datum/radio_frequency/frequency = radio_controller.return_frequency(beacon_freq)
|
||||
if(!frequency)
|
||||
return
|
||||
if(patrol_path[1] == loc)
|
||||
patrol_path -= patrol_path[1]
|
||||
var/moved = step_towards(src, patrol_path[1])
|
||||
if(moved)
|
||||
patrol_path -= patrol_path[1]
|
||||
if(target)
|
||||
if(loc == target.loc)
|
||||
if(!cleaning)
|
||||
UnarmedAttack(target)
|
||||
|
||||
closest_dist = 9999
|
||||
next_dest = null
|
||||
next_dest_loc = null
|
||||
|
||||
var/datum/signal/signal = new()
|
||||
signal.source = src
|
||||
signal.transmission_method = 1
|
||||
signal.data = list("findbeakon" = "patrol")
|
||||
frequency.post_signal(src, signal, filter = RADIO_NAVBEACONS)
|
||||
signal_sent = world.time
|
||||
else
|
||||
if(next_dest)
|
||||
next_dest_loc = listener.memorized[next_dest]
|
||||
if(next_dest_loc)
|
||||
patrol_path = AStar(loc, next_dest_loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id = botcard, exclude = null)
|
||||
signal_sent = 0
|
||||
else
|
||||
if(pulledby) // Don't wiggle if someone pulls you
|
||||
patrol_path = list()
|
||||
return
|
||||
if(!path.len)
|
||||
spawn(0)
|
||||
path = AStar(loc, target.loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30, id = botcard)
|
||||
if(!path)
|
||||
path = list()
|
||||
return
|
||||
if(path.len)
|
||||
step_to(src, path[1])
|
||||
path -= path[1]
|
||||
return
|
||||
if(patrol_path[1] == loc)
|
||||
patrol_path -= patrol_path[1]
|
||||
var/moved = step_towards(src, patrol_path[1])
|
||||
if(moved)
|
||||
patrol_path -= patrol_path[1]
|
||||
|
||||
|
||||
|
||||
/mob/living/bot/cleanbot/UnarmedAttack(var/obj/effect/decal/cleanable/D, var/proximity)
|
||||
if(!..())
|
||||
@@ -145,7 +165,7 @@
|
||||
return
|
||||
|
||||
cleaning = 1
|
||||
custom_emote(2, "begins to clean up the [D]")
|
||||
custom_emote(2, "begins to clean up \the [D]")
|
||||
update_icons()
|
||||
var/cleantime = istype(D, /obj/effect/decal/cleanable/dirt) ? 10 : 50
|
||||
if(do_after(src, cleantime))
|
||||
@@ -155,6 +175,8 @@
|
||||
if(!D)
|
||||
return
|
||||
qdel(D)
|
||||
if(D == target)
|
||||
target = null
|
||||
cleaning = 0
|
||||
update_icons()
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
breath = environment.remove_volume(volume_needed)
|
||||
handle_chemical_smoke(environment) //handle chemical smoke while we're at it
|
||||
|
||||
if(breath)
|
||||
if(breath && breath.total_moles)
|
||||
//handle mask filtering
|
||||
if(istype(wear_mask, /obj/item/clothing/mask) && breath)
|
||||
var/obj/item/clothing/mask/M = wear_mask
|
||||
@@ -60,13 +60,15 @@
|
||||
|
||||
//Handle possble chem smoke effect
|
||||
/mob/living/carbon/proc/handle_chemical_smoke(var/datum/gas_mixture/environment)
|
||||
if(species && environment.return_pressure() < species.breath_pressure/5)
|
||||
return //pressure is too low to even breathe in.
|
||||
if(wear_mask && (wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT))
|
||||
return
|
||||
|
||||
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
|
||||
if(smoke.reagents.total_volume)
|
||||
smoke.reagents.trans_to_mob(src, 10, CHEM_INGEST, copy = 1)
|
||||
//maybe check air pressure here or something to see if breathing in smoke is even possible.
|
||||
smoke.reagents.trans_to_mob(src, 5, CHEM_INGEST, copy = 1)
|
||||
smoke.reagents.trans_to_mob(src, 5, CHEM_BLOOD, copy = 1)
|
||||
// I dunno, maybe the reagents enter the blood stream through the lungs?
|
||||
break // If they breathe in the nasty stuff once, no need to continue checking
|
||||
|
||||
|
||||
@@ -107,15 +107,16 @@
|
||||
|
||||
return
|
||||
|
||||
/mob/living/carbon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null)
|
||||
/mob/living/carbon/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/def_zone = null, var/tesla_shock = 0)
|
||||
if(status_flags & GODMODE) return 0 //godmode
|
||||
shock_damage *= siemens_coeff
|
||||
if (!tesla_shock)
|
||||
shock_damage *= siemens_coeff
|
||||
if (shock_damage<1)
|
||||
return 0
|
||||
|
||||
src.apply_damage(shock_damage, BURN, def_zone, used_weapon="Electrocution")
|
||||
playsound(loc, "sparks", 50, 1, -1)
|
||||
if (shock_damage > 15)
|
||||
if (shock_damage > 15 || tesla_shock)
|
||||
src.visible_message(
|
||||
"\red [src] was shocked by the [source]!", \
|
||||
"\red <B>You feel a powerful shock course through your body!</B>", \
|
||||
@@ -205,7 +206,7 @@
|
||||
if(40 to INFINITY)
|
||||
status += "peeling away"
|
||||
|
||||
if(org.status & ORGAN_DESTROYED)
|
||||
if(org.is_stump())
|
||||
status += "MISSING"
|
||||
if(org.status & ORGAN_MUTATED)
|
||||
status += "weirdly shapen"
|
||||
@@ -260,7 +261,7 @@
|
||||
var/show_ssd
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(istype(H)) show_ssd = H.species.show_ssd
|
||||
if(show_ssd && !client && !aghosted)
|
||||
if(show_ssd && !client && !teleop)
|
||||
M.visible_message("<span class='notice'>[M] shakes [src] trying to wake [t_him] up!</span>", \
|
||||
"<span class='notice'>You shake [src], but they do not respond... Maybe they have S.S.D?</span>")
|
||||
else if(lying || src.sleeping)
|
||||
|
||||
@@ -1,53 +1,42 @@
|
||||
mob/living/carbon/verb/give(var/mob/living/carbon/target in view(1)-usr)
|
||||
/mob/living/carbon/human/verb/give(var/mob/living/target in view(1)-usr)
|
||||
set category = "IC"
|
||||
set name = "Give"
|
||||
if(!istype(target) || target.stat == 2 || usr.stat == 2|| target.client == null)
|
||||
|
||||
// TODO : Change to incapacitated() on merge.
|
||||
if(usr.stat || usr.lying || usr.resting || usr.buckled)
|
||||
return
|
||||
var/obj/item/I
|
||||
if(!usr.hand && usr.r_hand == null)
|
||||
usr << "<span class='warning'>You don't have anything in your right hand to give to [target.name]</span>"
|
||||
if(!istype(target) || target.stat || target.lying || target.resting || target.buckled || target.client == null)
|
||||
return
|
||||
if(usr.hand && usr.l_hand == null)
|
||||
usr << "<span class='warning'>You don't have anything in your left hand to give to [target.name]</span>"
|
||||
return
|
||||
if(usr.hand)
|
||||
I = usr.l_hand
|
||||
else if(!usr.hand)
|
||||
I = usr.r_hand
|
||||
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
if(!I)
|
||||
I = usr.get_inactive_hand()
|
||||
if(!I)
|
||||
usr << "<span class='warning'>You don't have anything in your hands to give to \the [target].</span>"
|
||||
return
|
||||
if(target.r_hand == null || target.l_hand == null)
|
||||
switch(alert(target,"[usr] wants to give you \a [I]?",,"Yes","No"))
|
||||
if("Yes")
|
||||
if(!I)
|
||||
return
|
||||
if(!Adjacent(usr))
|
||||
usr << "<span class='warning'>You need to stay in reaching distance while giving an object.</span>"
|
||||
target << "<span class='warning'>[usr.name] moved too far away.</span>"
|
||||
return
|
||||
if((usr.hand && usr.l_hand != I) || (!usr.hand && usr.r_hand != I))
|
||||
usr << "<span class='warning'>You need to keep the item in your active hand.</span>"
|
||||
target << "<span class='warning'>[usr.name] seem to have given up on giving \the [I.name] to you.</span>"
|
||||
return
|
||||
if(target.r_hand != null && target.l_hand != null)
|
||||
target << "<span class='warning'>Your hands are full.</span>"
|
||||
usr << "<span class='warning'>Their hands are full.</span>"
|
||||
return
|
||||
else
|
||||
usr.drop_item()
|
||||
if(target.r_hand == null)
|
||||
target.r_hand = I
|
||||
else
|
||||
target.l_hand = I
|
||||
I.loc = target
|
||||
I.layer = 20
|
||||
I.add_fingerprint(target)
|
||||
target.update_inv_l_hand()
|
||||
target.update_inv_r_hand()
|
||||
usr.update_inv_l_hand()
|
||||
usr.update_inv_r_hand()
|
||||
target.visible_message("<span class='notice'>[usr.name] handed \the [I.name] to [target.name].</span>")
|
||||
if("No")
|
||||
target.visible_message("<span class='warning'>[usr.name] tried to hand [I.name] to [target.name] but [target.name] didn't want it.</span>")
|
||||
else
|
||||
usr << "<span class='warning'>[target.name]'s hands are full.</span>"
|
||||
|
||||
if(alert(target,"[usr] wants to give you \a [I]. Will you accept it?",,"No","Yes") == "No")
|
||||
target.visible_message("<span class='notice'>\The [usr] tried to hand \the [I] to \the [target], \
|
||||
but \the [target] didn't want it.</span>")
|
||||
return
|
||||
|
||||
if(!I) return
|
||||
|
||||
if(!Adjacent(target))
|
||||
usr << "<span class='warning'>You need to stay in reaching distance while giving an object.</span>"
|
||||
target << "<span class='warning'>\The [usr] moved too far away.</span>"
|
||||
return
|
||||
|
||||
if(I.loc != usr || (usr.l_hand != I && usr.r_hand != I))
|
||||
usr << "<span class='warning'>You need to keep the item in your hands.</span>"
|
||||
target << "<span class='warning'>\The [usr] seems to have given up on passing \the [I] to you.</span>"
|
||||
return
|
||||
|
||||
if(target.r_hand != null && target.l_hand != null)
|
||||
target << "<span class='warning'>Your hands are full.</span>"
|
||||
usr << "<span class='warning'>Their hands are full.</span>"
|
||||
return
|
||||
|
||||
if(usr.unEquip(I))
|
||||
target.put_in_hands(I) // If this fails it will just end up on the floor, but that's fitting for things like dionaea.
|
||||
target.visible_message("<span class='notice'>\The [usr] handed \the [I] to \the [target].</span>")
|
||||
|
||||
@@ -262,43 +262,36 @@
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] [species.show_ssd].</span>\n"
|
||||
|
||||
var/list/wound_flavor_text = list()
|
||||
var/list/is_destroyed = list()
|
||||
var/list/is_bleeding = list()
|
||||
|
||||
for(var/organ_tag in species.has_limbs)
|
||||
|
||||
var/list/organ_data = species.has_limbs[organ_tag]
|
||||
var/organ_descriptor = organ_data["descriptor"]
|
||||
is_destroyed["organ_descriptor"] = 1
|
||||
|
||||
var/obj/item/organ/external/E = organs_by_name[organ_tag]
|
||||
if(!E)
|
||||
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[t_He] is missing [t_his] [organ_descriptor].</b></span>\n"
|
||||
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[t_He] [t_is] missing [t_his] [organ_descriptor].</b></span>\n"
|
||||
else if(E.is_stump())
|
||||
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[t_He] has a stump where [t_his] [organ_descriptor] should be.</b></span>\n"
|
||||
wound_flavor_text["[organ_descriptor]"] = "<span class='warning'><b>[t_He] [t_has] a stump where [t_his] [organ_descriptor] should be.</b></span>\n"
|
||||
else
|
||||
is_destroyed["organ_descriptor"] = 0
|
||||
continue
|
||||
|
||||
for(var/obj/item/organ/external/temp in organs)
|
||||
if(temp)
|
||||
if(temp.status & ORGAN_DESTROYED)
|
||||
is_destroyed["[temp.name]"] = 1
|
||||
wound_flavor_text["[temp.name]"] = "<span class='warning'><b>[t_He] [t_is] missing [t_his] [temp.name].</b></span>\n"
|
||||
continue
|
||||
if(temp.status & ORGAN_ROBOT)
|
||||
if(!(temp.brute_dam + temp.burn_dam))
|
||||
if(!species.flags & IS_SYNTHETIC)
|
||||
wound_flavor_text["[temp.name]"] = "<span class='warning'>[t_He] [t_has] a robot [temp.name]!</span>\n"
|
||||
continue
|
||||
else
|
||||
wound_flavor_text["[temp.name]"] = "<span class='warning'>[t_He] has a robot [temp.name]. It has[temp.get_wounds_desc()]!</span>\n"
|
||||
wound_flavor_text["[temp.name]"] = "<span class='warning'>[t_He] [t_has] a robot [temp.name]. It has[temp.get_wounds_desc()]!</span>\n"
|
||||
else if(temp.wounds.len > 0 || temp.open)
|
||||
if(temp.is_stump() && temp.parent_organ && organs_by_name[temp.parent_organ])
|
||||
var/obj/item/organ/external/parent = organs_by_name[temp.parent_organ]
|
||||
wound_flavor_text["[temp.name]"] = "<span class='warning'>[t_He] has [temp.get_wounds_desc()] on [t_his] [parent.name].</span><br>"
|
||||
wound_flavor_text["[temp.name]"] = "<span class='warning'>[t_He] [t_has] [temp.get_wounds_desc()] on [t_his] [parent.name].</span><br>"
|
||||
else
|
||||
wound_flavor_text["[temp.name]"] = "<span class='warning'>[t_He] has [temp.get_wounds_desc()] on [t_his] [temp.name].</span><br>"
|
||||
wound_flavor_text["[temp.name]"] = "<span class='warning'>[t_He] [t_has] [temp.get_wounds_desc()] on [t_his] [temp.name].</span><br>"
|
||||
if(temp.status & ORGAN_BLEEDING)
|
||||
is_bleeding["[temp.name]"] = "<span class='danger'>[capitalize(t_his)] [temp.name] is bleeding!</span><br>"
|
||||
else
|
||||
|
||||
@@ -342,7 +342,7 @@
|
||||
//Returns "Unknown" if facially disfigured and real_name if not. Useful for setting name when polyacided or when updating a human's name variable
|
||||
/mob/living/carbon/human/proc/get_face_name()
|
||||
var/obj/item/organ/external/head = get_organ("head")
|
||||
if(!head || head.disfigured || (head.status & ORGAN_DESTROYED) || !real_name || (HUSK in mutations) ) //disfigured. use id-name if possible
|
||||
if(!head || head.disfigured || head.is_stump() || !real_name || (HUSK in mutations) ) //disfigured. use id-name if possible
|
||||
return "Unknown"
|
||||
return real_name
|
||||
|
||||
@@ -366,7 +366,7 @@
|
||||
|
||||
//Removed the horrible safety parameter. It was only being used by ninja code anyways.
|
||||
//Now checks siemens_coefficient of the affected area by default
|
||||
/mob/living/carbon/human/electrocute_act(var/shock_damage, var/obj/source, var/base_siemens_coeff = 1.0, var/def_zone = null)
|
||||
/mob/living/carbon/human/electrocute_act(var/shock_damage, var/obj/source, var/base_siemens_coeff = 1.0, var/def_zone = null, var/tesla_shock = 0)
|
||||
if(status_flags & GODMODE) return 0 //godmode
|
||||
|
||||
if (!def_zone)
|
||||
@@ -375,7 +375,7 @@
|
||||
var/obj/item/organ/external/affected_organ = get_organ(check_zone(def_zone))
|
||||
var/siemens_coeff = base_siemens_coeff * get_siemens_coefficient_organ(affected_organ)
|
||||
|
||||
return ..(shock_damage, source, siemens_coeff, def_zone)
|
||||
return ..(shock_damage, source, siemens_coeff, def_zone, tesla_shock)
|
||||
|
||||
|
||||
/mob/living/carbon/human/Topic(href, href_list)
|
||||
@@ -967,7 +967,7 @@
|
||||
|
||||
if(L && !L.is_bruised())
|
||||
src.custom_pain("You feel a stabbing pain in your chest!", 1)
|
||||
L.damage = L.min_bruised_damage
|
||||
L.bruise()
|
||||
|
||||
/*
|
||||
/mob/living/carbon/human/verb/simulate()
|
||||
@@ -1165,10 +1165,6 @@
|
||||
else
|
||||
return 0
|
||||
|
||||
mob_bump_flag = species.bump_flag
|
||||
mob_swap_flags = species.swap_flags
|
||||
mob_push_flags = species.push_flags
|
||||
|
||||
/mob/living/carbon/human/proc/bloody_doodle()
|
||||
set category = "IC"
|
||||
set name = "Write in blood"
|
||||
@@ -1273,11 +1269,10 @@
|
||||
if(C.body_parts_covered & FEET)
|
||||
feet_exposed = 0
|
||||
|
||||
flavor_text = flavor_texts["general"]
|
||||
flavor_text += "\n\n"
|
||||
flavor_text = ""
|
||||
for (var/T in flavor_texts)
|
||||
if(flavor_texts[T] && flavor_texts[T] != "")
|
||||
if((T == "head" && head_exposed) || (T == "face" && face_exposed) || (T == "eyes" && eyes_exposed) || (T == "torso" && torso_exposed) || (T == "arms" && arms_exposed) || (T == "hands" && hands_exposed) || (T == "legs" && legs_exposed) || (T == "feet" && feet_exposed))
|
||||
if((T == "general") || (T == "head" && head_exposed) || (T == "face" && face_exposed) || (T == "eyes" && eyes_exposed) || (T == "torso" && torso_exposed) || (T == "arms" && arms_exposed) || (T == "hands" && hands_exposed) || (T == "legs" && legs_exposed) || (T == "feet" && feet_exposed))
|
||||
flavor_text += flavor_texts[T]
|
||||
flavor_text += "\n\n"
|
||||
if(!shrink)
|
||||
@@ -1384,7 +1379,49 @@
|
||||
|
||||
/mob/living/carbon/human/MouseDrop(var/atom/over_object)
|
||||
var/mob/living/carbon/human/H = over_object
|
||||
if(holder_type && a_intent == "help" && H.a_intent == "help" && istype(H) && !issmall(H) && Adjacent(H))
|
||||
if(holder_type && a_intent == I_HELP && istype(H) && H == usr && H.a_intent == I_HELP && !issmall(H) && Adjacent(H))
|
||||
get_scooped(H)
|
||||
return
|
||||
return ..()
|
||||
|
||||
//Puts the item into our active hand if possible. returns 1 on success.
|
||||
/mob/living/carbon/human/put_in_active_hand(var/obj/item/W)
|
||||
return (hand ? put_in_l_hand(W) : put_in_r_hand(W))
|
||||
|
||||
//Puts the item into our inactive hand if possible. returns 1 on success.
|
||||
/mob/living/carbon/human/put_in_inactive_hand(var/obj/item/W)
|
||||
return (hand ? put_in_r_hand(W) : put_in_l_hand(W))
|
||||
|
||||
/mob/living/carbon/human/put_in_hands(var/obj/item/W)
|
||||
if(!W)
|
||||
return 0
|
||||
if(put_in_active_hand(W))
|
||||
update_inv_l_hand()
|
||||
update_inv_r_hand()
|
||||
return 1
|
||||
else if(put_in_inactive_hand(W))
|
||||
update_inv_l_hand()
|
||||
update_inv_r_hand()
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/put_in_l_hand(var/obj/item/W)
|
||||
if(!..() || l_hand)
|
||||
return 0
|
||||
W.forceMove(src)
|
||||
l_hand = W
|
||||
W.equipped(src,slot_l_hand)
|
||||
W.add_fingerprint(src)
|
||||
update_inv_l_hand()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/put_in_r_hand(var/obj/item/W)
|
||||
if(!..() || r_hand)
|
||||
return 0
|
||||
W.forceMove(src)
|
||||
r_hand = W
|
||||
W.equipped(src,slot_r_hand)
|
||||
W.add_fingerprint(src)
|
||||
update_inv_r_hand()
|
||||
return 1
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
var/hit_zone = H.zone_sel.selecting
|
||||
var/obj/item/organ/external/affecting = get_organ(hit_zone)
|
||||
|
||||
if(!affecting || affecting.is_stump() || (affecting.status & ORGAN_DESTROYED))
|
||||
if(!affecting || affecting.is_stump())
|
||||
M << "<span class='danger'>They are missing that limb!</span>"
|
||||
return 1
|
||||
|
||||
|
||||
@@ -182,7 +182,6 @@ emp_act
|
||||
if(!O) continue
|
||||
O.emp_act(severity)
|
||||
for(var/obj/item/organ/external/O in organs)
|
||||
if(O.status & ORGAN_DESTROYED) continue
|
||||
O.emp_act(severity)
|
||||
for(var/obj/item/organ/I in O.internal_organs)
|
||||
if(I.robotic == 0) continue
|
||||
@@ -204,7 +203,7 @@ emp_act
|
||||
|
||||
var/obj/item/organ/external/affecting = get_organ(target_zone)
|
||||
|
||||
if (!affecting || (affecting.status & ORGAN_DESTROYED) || affecting.is_stump())
|
||||
if (!affecting || affecting.is_stump())
|
||||
user << "<span class='danger'>They are missing that limb!</span>"
|
||||
return
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
if(istype(buckled, /obj/structure/bed/chair/wheelchair))
|
||||
for(var/organ_name in list("l_hand","r_hand","l_arm","r_arm"))
|
||||
var/obj/item/organ/external/E = get_organ(organ_name)
|
||||
if(!E || (E.status & ORGAN_DESTROYED))
|
||||
if(!E || E.is_stump())
|
||||
tally += 4
|
||||
if(E.status & ORGAN_SPLINTED)
|
||||
tally += 0.5
|
||||
@@ -40,9 +40,9 @@
|
||||
|
||||
for(var/organ_name in list("l_foot","r_foot","l_leg","r_leg"))
|
||||
var/obj/item/organ/external/E = get_organ(organ_name)
|
||||
if(!E || (E.status & ORGAN_DESTROYED))
|
||||
if(!E || E.is_stump())
|
||||
tally += 4
|
||||
if(E.status & ORGAN_SPLINTED)
|
||||
else if(E.status & ORGAN_SPLINTED)
|
||||
tally += 0.5
|
||||
else if(E.status & ORGAN_BROKEN)
|
||||
tally += 1.5
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
for(var/limb_tag in list("l_leg","r_leg","l_foot","r_foot"))
|
||||
var/obj/item/organ/external/E = organs_by_name[limb_tag]
|
||||
if(!E || (E.status & (ORGAN_DESTROYED|ORGAN_DEAD)))
|
||||
if(!E || (E.status & (ORGAN_MUTATED|ORGAN_DEAD)) || E.is_stump()) //should just be !E.is_usable() here but dislocation screws that up.
|
||||
stance_damage += 2 // let it fail even if just foot&leg
|
||||
else if (E.is_malfunctioning())
|
||||
//malfunctioning only happens intermittently so treat it as a missing limb when it procs
|
||||
|
||||
@@ -224,11 +224,14 @@
|
||||
set name = "Split"
|
||||
set desc = "Split your humanoid form into its constituent nymphs."
|
||||
set category = "Abilities"
|
||||
diona_split_into_nymphs(5) // Separate proc to void argments being supplied when used as a verb
|
||||
|
||||
/mob/living/carbon/human/proc/diona_split_into_nymphs(var/number_of_resulting_nymphs)
|
||||
var/turf/T = get_turf(src)
|
||||
|
||||
var/mob/living/carbon/alien/diona/S = new(T)
|
||||
S.set_dir(dir)
|
||||
transfer_languages(src, S)
|
||||
if(mind)
|
||||
mind.transfer_to(S)
|
||||
|
||||
@@ -239,20 +242,55 @@
|
||||
|
||||
for(var/mob/living/carbon/alien/diona/D in src)
|
||||
nymphs++
|
||||
D.loc = T
|
||||
D.forceMove(T)
|
||||
transfer_languages(src, D, WHITELISTED|RESTRICTED)
|
||||
D.set_dir(pick(NORTH, SOUTH, EAST, WEST))
|
||||
|
||||
if(nymphs < 5)
|
||||
for(var/i in nymphs to 4)
|
||||
if(nymphs < number_of_resulting_nymphs)
|
||||
for(var/i in nymphs to (number_of_resulting_nymphs - 1))
|
||||
var/mob/M = new /mob/living/carbon/alien/diona(T)
|
||||
transfer_languages(src, M, WHITELISTED|RESTRICTED)
|
||||
M.set_dir(pick(NORTH, SOUTH, EAST, WEST))
|
||||
|
||||
|
||||
for(var/obj/item/W in src)
|
||||
drop_from_inventory(W)
|
||||
|
||||
visible_message("<span class='warning'>\The [src] quivers slightly, then splits apart with a wet slithering noise.</span>")
|
||||
|
||||
qdel(src)
|
||||
|
||||
/mob/living/carbon/human/proc/bugbite()
|
||||
set category = "Abilities"
|
||||
set name = "Bite"
|
||||
set desc = "While grabbing someone aggressively, tear into them with your mandibles."
|
||||
|
||||
if(last_special > world.time)
|
||||
return
|
||||
|
||||
if(stat || paralysis || stunned || weakened || lying)
|
||||
src << "\red You cannot do that in your current state."
|
||||
return
|
||||
|
||||
var/obj/item/weapon/grab/G = locate() in src
|
||||
if(!G || !istype(G))
|
||||
src << "\red You are not grabbing anyone."
|
||||
return
|
||||
|
||||
if(G.state < GRAB_AGGRESSIVE)
|
||||
src << "\red You must have an aggressive grab to gut your prey!"
|
||||
return
|
||||
|
||||
last_special = world.time + 50
|
||||
|
||||
visible_message("<span class='warning'><b>\The [src]</b> rips viciously at \the [G.affecting]'s flesh with its mandibles!</span>")
|
||||
|
||||
if(istype(G.affecting,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = G.affecting
|
||||
H.apply_damage(30,BRUTE)
|
||||
// if(H.stat == 2) //no gibbing humans but i'll let you gib like a mouse or something that's cool
|
||||
// H.gib()
|
||||
else
|
||||
var/mob/living/M = G.affecting
|
||||
if(!istype(M)) return //wut
|
||||
M.apply_damage(30,BRUTE)
|
||||
if(M.stat == 2)
|
||||
M.gib()
|
||||
@@ -36,3 +36,6 @@
|
||||
|
||||
/mob/living/carbon/human/stok/New(var/new_loc)
|
||||
..(new_loc, "Stok")
|
||||
|
||||
/mob/living/carbon/human/bug/New(var/new_loc)
|
||||
..(new_loc, "Vaurca")
|
||||
@@ -1,15 +1,7 @@
|
||||
/*
|
||||
Add fingerprints to items when we put them in our hands.
|
||||
This saves us from having to call add_fingerprint() any time something is put in a human's hands programmatically.
|
||||
|
||||
*/
|
||||
/mob/living/carbon/human/put_in_l_hand(var/obj/item/W)
|
||||
. = ..()
|
||||
if(.) W.add_fingerprint(src)
|
||||
|
||||
/mob/living/carbon/human/put_in_r_hand(var/obj/item/W)
|
||||
. = ..()
|
||||
if(.) W.add_fingerprint(src)
|
||||
|
||||
/mob/living/carbon/human/verb/quick_equip()
|
||||
set name = "quick-equip"
|
||||
@@ -41,7 +33,7 @@ This saves us from having to call add_fingerprint() any time something is put in
|
||||
/mob/living/carbon/human/proc/has_organ(name)
|
||||
var/obj/item/organ/external/O = organs_by_name[name]
|
||||
|
||||
return (O && !(O.status & ORGAN_DESTROYED) && !O.is_stump())
|
||||
return (O && !O.is_stump())
|
||||
|
||||
/mob/living/carbon/human/proc/has_organ_for_slot(slot)
|
||||
switch(slot)
|
||||
|
||||
@@ -258,7 +258,7 @@
|
||||
|
||||
proc/handle_mutations_and_radiation()
|
||||
|
||||
if(species.flags & IS_SYNTHETIC) //Robots don't suffer from mutations or radloss.
|
||||
if(species.flags & IS_SYNTHETIC || species.flags & IS_BUG) //Robots/bugs don't suffer from mutations or radloss.
|
||||
return
|
||||
|
||||
if(getFireLoss())
|
||||
@@ -364,12 +364,24 @@
|
||||
internals.icon_state = "internal0"
|
||||
return null
|
||||
|
||||
get_breath_from_environment(var/volume_needed=BREATH_VOLUME)
|
||||
var/datum/gas_mixture/breath = ..()
|
||||
|
||||
if(breath)
|
||||
//exposure to extreme pressures can rupture lungs
|
||||
var/check_pressure = breath.return_pressure()
|
||||
if(check_pressure < ONE_ATMOSPHERE / 5 || check_pressure > ONE_ATMOSPHERE * 5)
|
||||
if(!is_lung_ruptured() && prob(5))
|
||||
rupture_lung()
|
||||
|
||||
return breath
|
||||
|
||||
handle_breath(datum/gas_mixture/breath)
|
||||
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
|
||||
//check if we actually need to process breath
|
||||
if(!breath || (breath.total_moles == 0) || suiciding)
|
||||
failed_last_breath = 1
|
||||
if(suiciding)
|
||||
@@ -385,7 +397,7 @@
|
||||
|
||||
return 0
|
||||
|
||||
var/safe_pressure_min = 16 // Minimum safe partial pressure of breathable gas in kPa
|
||||
var/safe_pressure_min = species.breath_pressure // Minimum safe partial pressure of breathable gas in kPa
|
||||
|
||||
// Lung damage increases the minimum safe pressure.
|
||||
if(species.has_organ["lungs"])
|
||||
@@ -397,6 +409,15 @@
|
||||
else if(L.is_bruised())
|
||||
safe_pressure_min *= 1.25
|
||||
|
||||
if(species.has_organ["breathing apparatus"])
|
||||
var/obj/item/organ/vaurca/breathingapparatus/L = internal_organs_by_name["breathing apparatus"]
|
||||
if(isnull(L))
|
||||
safe_pressure_min = INFINITY //No wannabe-lungs, how are you breathing? FOR VAURCA
|
||||
else if(L.is_broken())
|
||||
safe_pressure_min *= 1.5
|
||||
else if(L.is_bruised())
|
||||
safe_pressure_min *= 1.25
|
||||
|
||||
var/safe_exhaled_max = 10
|
||||
var/safe_toxins_max = 0.005
|
||||
var/SA_para_min = 1
|
||||
@@ -884,9 +905,9 @@
|
||||
var/turf/T = loc
|
||||
var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T
|
||||
if(L)
|
||||
light_amount = min(10,L.lum_r + L.lum_g + L.lum_b) - 5 //hardcapped so it's not abused by having a ton of flashlights
|
||||
light_amount = min(10,L.lum_r + L.lum_g + L.lum_b) - 2 //hardcapped so it's not abused by having a ton of flashlights
|
||||
else
|
||||
light_amount = 5
|
||||
light_amount = 1
|
||||
nutrition += light_amount
|
||||
traumatic_shock -= light_amount
|
||||
|
||||
@@ -941,7 +962,7 @@
|
||||
if(status_flags & GODMODE) return 0
|
||||
|
||||
//SSD check, if a logged player is awake put them back to sleep!
|
||||
if(species.show_ssd && !client && !aghosted)
|
||||
if(species.show_ssd && !client && !teleop)
|
||||
Sleeping(2)
|
||||
|
||||
if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
|
||||
@@ -1254,7 +1275,7 @@
|
||||
|
||||
if(healths)
|
||||
if (analgesic > 100)
|
||||
healths.icon_state = "health_health_numb"
|
||||
healths.icon_state = "health_numb"
|
||||
else
|
||||
switch(hal_screwyhud)
|
||||
if(1) healths.icon_state = "health6"
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
|
||||
// Environment tolerance/life processes vars.
|
||||
var/reagent_tag //Used for metabolizing reagents.
|
||||
var/breath_pressure = 16 // Minimum partial pressure safe for breathing, kPa
|
||||
var/breath_type = "oxygen" // Non-oxygen gas breathed, if any.
|
||||
var/poison_type = "phoron" // Poisonous air.
|
||||
var/exhale_type = "carbon_dioxide" // Exhaled gas type.
|
||||
@@ -212,23 +213,29 @@
|
||||
var/obj/item/organ/O = new limb_path(H)
|
||||
organ_data["descriptor"] = O.name
|
||||
|
||||
for(var/organ in has_organ)
|
||||
var/organ_type = has_organ[organ]
|
||||
H.internal_organs_by_name[organ] = new organ_type(H,1)
|
||||
|
||||
for(var/name in H.organs_by_name)
|
||||
H.organs |= H.organs_by_name[name]
|
||||
|
||||
for(var/obj/item/organ/external/O in H.organs)
|
||||
O.owner = H
|
||||
for(var/organ_tag in has_organ)
|
||||
var/organ_type = has_organ[organ_tag]
|
||||
var/obj/item/organ/O = new organ_type(H,1)
|
||||
if(organ_tag != O.organ_tag)
|
||||
warning("[O.type] has a default organ tag \"[O.organ_tag]\" that differs from the species' organ tag \"[organ_tag]\". Updating organ_tag to match.")
|
||||
O.organ_tag = organ_tag
|
||||
H.internal_organs_by_name[organ_tag] = O
|
||||
|
||||
if(flags & IS_SYNTHETIC)
|
||||
for(var/obj/item/organ/external/E in H.organs)
|
||||
if(E.status & ORGAN_CUT_AWAY || E.status & ORGAN_DESTROYED) continue
|
||||
if(E.status & ORGAN_CUT_AWAY || E.is_stump()) continue
|
||||
E.robotize()
|
||||
for(var/obj/item/organ/I in H.internal_organs)
|
||||
I.robotize()
|
||||
|
||||
if(flags & IS_BUG)
|
||||
for (var/obj/item/organ/external/E in H.organs)
|
||||
if ((E.status & ORGAN_CUT_AWAY) || (E.status & ORGAN_DESTROYED))
|
||||
continue
|
||||
E.status |= ORGAN_ADV_ROBOT
|
||||
for(var/obj/item/organ/I in H.internal_organs)
|
||||
I.robotize()
|
||||
|
||||
/datum/species/proc/hug(var/mob/living/carbon/human/H,var/mob/living/target)
|
||||
|
||||
var/t_him = "them"
|
||||
@@ -255,6 +262,9 @@
|
||||
|
||||
/datum/species/proc/handle_post_spawn(var/mob/living/carbon/human/H) //Handles anything not already covered by basic species assignment.
|
||||
add_inherent_verbs(H)
|
||||
H.mob_bump_flag = bump_flag
|
||||
H.mob_swap_flags = swap_flags
|
||||
H.mob_push_flags = push_flags
|
||||
|
||||
/datum/species/proc/handle_death(var/mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns).
|
||||
return
|
||||
|
||||
@@ -221,19 +221,7 @@
|
||||
return ..()
|
||||
|
||||
/datum/species/diona/handle_death(var/mob/living/carbon/human/H)
|
||||
|
||||
var/mob/living/carbon/alien/diona/S = new(get_turf(H))
|
||||
|
||||
if(H.mind)
|
||||
H.mind.transfer_to(S)
|
||||
|
||||
for(var/mob/living/carbon/alien/diona/D in H.contents)
|
||||
if(D.client)
|
||||
D.loc = H.loc
|
||||
else
|
||||
qdel(D)
|
||||
|
||||
H.visible_message("\red[H] splits apart with a wet slithering noise!")
|
||||
H.diona_split_into_nymphs(0)
|
||||
|
||||
/datum/species/machine
|
||||
name = "Machine"
|
||||
@@ -278,3 +266,47 @@
|
||||
H.h_style = ""
|
||||
spawn(100)
|
||||
if(H) H.update_hair()
|
||||
|
||||
/datum/species/bug
|
||||
name = "Vaurca"
|
||||
name_plural = "varucae"
|
||||
|
||||
icobase = 'icons/mob/human_races/r_vaurca.dmi'
|
||||
deform = 'icons/mob/human_races/r_vaurca.dmi'
|
||||
language = "Vaurcese"
|
||||
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp)
|
||||
rarity_value = 2
|
||||
slowdown = 1
|
||||
darksight = 5 //USELESS
|
||||
eyes = "blank_eyes"
|
||||
brute_mod = 0.5 //note to self: remove is_synthetic checks for brmod and burnmod
|
||||
burn_mod = 2
|
||||
warning_low_pressure = 50
|
||||
hazard_low_pressure = 0
|
||||
|
||||
cold_level_1 = 50
|
||||
cold_level_2 = -1
|
||||
cold_level_3 = -1
|
||||
|
||||
heat_level_1 = 330 //Default 360
|
||||
heat_level_2 = 380 //Default 400
|
||||
heat_level_3 = 600 //Default 1000
|
||||
flags = CAN_JOIN | IS_WHITELISTED | NO_SLIP | IS_BUG | NO_SCAN
|
||||
blood_color = "#E6E600" // dark yellow
|
||||
flesh_color = "#575757"
|
||||
|
||||
inherent_verbs = list(
|
||||
/mob/living/carbon/human/proc/bugbite //weaker version of gut.
|
||||
)
|
||||
|
||||
|
||||
has_organ = list(
|
||||
"neural socket" = /obj/item/organ/vaurca/neuralsocket,
|
||||
"breathing apparatus" = /obj/item/organ/vaurca/breathingapparatus,
|
||||
"heart" = /obj/item/organ/heart,
|
||||
"second heart" = /obj/item/organ/heart,
|
||||
"liver" = /obj/item/organ/liver,
|
||||
"kidneys" = /obj/item/organ/kidneys,
|
||||
"brain" = /obj/item/organ/brain,
|
||||
"eyes" = /obj/item/organ/eyes,
|
||||
)
|
||||
@@ -70,6 +70,7 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/equipped(mob/M)
|
||||
..()
|
||||
Attach(M)
|
||||
|
||||
/obj/item/clothing/mask/facehugger/Crossed(atom/target)
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
|
||||
// Check if they have a functioning hand.
|
||||
var/obj/item/organ/external/E = user.organs_by_name["l_hand"]
|
||||
if(E && !(E.status & ORGAN_DESTROYED))
|
||||
if(E && !E.is_stump())
|
||||
return 1
|
||||
|
||||
E = user.organs_by_name["r_hand"]
|
||||
if(E && !(E.status & ORGAN_DESTROYED))
|
||||
if(E && !E.is_stump())
|
||||
return 1
|
||||
|
||||
return 0
|
||||
@@ -32,6 +32,9 @@
|
||||
|
||||
/datum/unarmed_attack/proc/apply_effects(var/mob/living/carbon/human/user,var/mob/living/carbon/human/target,var/armour,var/attack_damage,var/zone)
|
||||
|
||||
if(target.stat == DEAD)
|
||||
return
|
||||
|
||||
var/stun_chance = rand(0, 100)
|
||||
|
||||
if(attack_damage >= 5 && armour < 2 && !(target == user) && stun_chance <= attack_damage * 5) // 25% standard chance
|
||||
@@ -167,11 +170,11 @@
|
||||
return 0
|
||||
|
||||
var/obj/item/organ/external/E = user.organs_by_name["l_foot"]
|
||||
if(E && !(E.status & ORGAN_DESTROYED))
|
||||
if(E && !E.is_stump())
|
||||
return 1
|
||||
|
||||
E = user.organs_by_name["r_foot"]
|
||||
if(E && !(E.status & ORGAN_DESTROYED))
|
||||
if(E && !E.is_stump())
|
||||
return 1
|
||||
|
||||
return 0
|
||||
@@ -211,11 +214,11 @@
|
||||
if(target.grabbed_by == user && target.lying)
|
||||
return 0
|
||||
var/obj/item/organ/external/E = user.organs_by_name["l_foot"]
|
||||
if(E && !(E.status & ORGAN_DESTROYED))
|
||||
if(E && !E.is_stump())
|
||||
return 1
|
||||
|
||||
E = user.organs_by_name["r_foot"]
|
||||
if(E && !(E.status & ORGAN_DESTROYED))
|
||||
if(E && !E.is_stump())
|
||||
return 1
|
||||
|
||||
return 0
|
||||
@@ -233,4 +236,4 @@
|
||||
|
||||
switch(attack_damage)
|
||||
if(1 to 4) user.visible_message("<span class='danger'>[pick("[user] stomped on", "[user] slammed \his [shoes ? copytext(shoes.name, 1, -1) : "foot"] down onto")] [target]'s [organ]!</span>")
|
||||
if(5) user.visible_message("<span class='danger'>[pick("[user] landed a powerful stomp on", "[user] stomped down hard on", "[user] slammed \his [shoes ? copytext(shoes.name, 1, -1) : "foot"] down hard onto")] [target]'s [organ]!</span>") //Devastated lol. No. We want to say that the stomp was powerful or forceful, not that it /wrought devastation/
|
||||
if(5) user.visible_message("<span class='danger'>[pick("[user] landed a powerful stomp on", "[user] stomped down hard on", "[user] slammed \his [shoes ? copytext(shoes.name, 1, -1) : "foot"] down hard onto")] [target]'s [organ]!</span>") //Devastated lol. No. We want to say that the stomp was powerful or forceful, not that it /wrought devastation/
|
||||
|
||||
@@ -186,9 +186,10 @@ var/global/list/damage_icon_parts = list()
|
||||
for(var/obj/item/organ/external/O in organs)
|
||||
if(O.is_stump())
|
||||
continue
|
||||
if(O.status & ORGAN_DESTROYED) damage_appearance += "d"
|
||||
else
|
||||
damage_appearance += O.damage_state
|
||||
//if(O.status & ORGAN_DESTROYED) damage_appearance += "d" //what is this?
|
||||
//else
|
||||
// damage_appearance += O.damage_state
|
||||
damage_appearance += O.damage_state
|
||||
|
||||
if(damage_appearance == previous_damage_appearance)
|
||||
// nothing to do here
|
||||
@@ -204,20 +205,20 @@ var/global/list/damage_icon_parts = list()
|
||||
for(var/obj/item/organ/external/O in organs)
|
||||
if(O.is_stump())
|
||||
continue
|
||||
if(!(O.status & ORGAN_DESTROYED))
|
||||
O.update_icon()
|
||||
if(O.damage_state == "00") continue
|
||||
var/icon/DI
|
||||
var/cache_index = "[O.damage_state]/[O.icon_name]/[species.blood_color]/[species.get_bodytype()]"
|
||||
if(damage_icon_parts[cache_index] == null)
|
||||
DI = new /icon(species.damage_overlays, O.damage_state) // the damage icon for whole human
|
||||
DI.Blend(new /icon(species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels
|
||||
DI.Blend(species.blood_color, ICON_MULTIPLY)
|
||||
damage_icon_parts[cache_index] = DI
|
||||
else
|
||||
DI = damage_icon_parts[cache_index]
|
||||
|
||||
standing_image.overlays += DI
|
||||
O.update_icon()
|
||||
if(O.damage_state == "00") continue
|
||||
var/icon/DI
|
||||
var/cache_index = "[O.damage_state]/[O.icon_name]/[species.blood_color]/[species.get_bodytype()]"
|
||||
if(damage_icon_parts[cache_index] == null)
|
||||
DI = new /icon(species.damage_overlays, O.damage_state) // the damage icon for whole human
|
||||
DI.Blend(new /icon(species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels
|
||||
DI.Blend(species.blood_color, ICON_MULTIPLY)
|
||||
damage_icon_parts[cache_index] = DI
|
||||
else
|
||||
DI = damage_icon_parts[cache_index]
|
||||
|
||||
standing_image.overlays += DI
|
||||
|
||||
overlays_standing[DAMAGE_LAYER] = standing_image
|
||||
|
||||
@@ -257,7 +258,7 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
for(var/organ_tag in species.has_limbs)
|
||||
var/obj/item/organ/external/part = organs_by_name[organ_tag]
|
||||
if(isnull(part) || part.is_stump() || (part.status & ORGAN_DESTROYED))
|
||||
if(isnull(part) || part.is_stump())
|
||||
icon_key += "0"
|
||||
else if(part.status & ORGAN_ROBOT)
|
||||
icon_key += "2[part.model ? "-[part.model]": ""]"
|
||||
@@ -336,7 +337,7 @@ var/global/list/damage_icon_parts = list()
|
||||
overlays_standing[HAIR_LAYER] = null
|
||||
|
||||
var/obj/item/organ/external/head/head_organ = get_organ("head")
|
||||
if(!head_organ || head_organ.is_stump() || (head_organ.status & ORGAN_DESTROYED) )
|
||||
if(!head_organ || head_organ.is_stump() )
|
||||
if(update_icons) update_icons()
|
||||
return
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
origin_tech = "biotech=4"
|
||||
var/Uses = 1 // uses before it goes inert
|
||||
var/enhanced = 0 //has it been enhanced before?
|
||||
flags = OPENCONTAINER
|
||||
|
||||
attackby(obj/item/O as obj, mob/user as mob)
|
||||
if(istype(O, /obj/item/weapon/slimesteroid2))
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
apply_effect(STUTTER, agony_amount/10)
|
||||
apply_effect(EYE_BLUR, agony_amount/10)
|
||||
|
||||
/mob/living/proc/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0)
|
||||
/mob/living/proc/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/tesla_shock = 0)
|
||||
return 0 //only carbon liveforms have this proc
|
||||
|
||||
/mob/living/emp_act(severity)
|
||||
@@ -219,7 +219,7 @@
|
||||
|
||||
/mob/living/proc/handle_fire()
|
||||
if(fire_stacks < 0)
|
||||
fire_stacks = max(0, fire_stacks++) //If we've doused ourselves in water to avoid fire, dry off slowly
|
||||
fire_stacks = min(0, ++fire_stacks) //If we've doused ourselves in water to avoid fire, dry off slowly
|
||||
|
||||
if(!on_fire)
|
||||
return 1
|
||||
@@ -251,7 +251,7 @@
|
||||
return 0
|
||||
|
||||
//Scale quadratically so that single digit numbers of fire stacks don't burn ridiculously hot.
|
||||
//lower limit of 700 K, same as matches and roughly the temperature of a cool flame.
|
||||
//lower limit of 700 K, same as matches and roughly the temperature of a cool flame.
|
||||
return max(2.25*round(FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE*(fire_stacks/FIRE_MAX_FIRESUIT_STACKS)**2), 700)
|
||||
|
||||
/mob/living/proc/reagent_permeability()
|
||||
|
||||
@@ -39,4 +39,4 @@
|
||||
var/mob_size // Used by lockers.
|
||||
var/on_fire = 0 //The "Are we on fire?" var
|
||||
var/fire_stacks
|
||||
|
||||
var/footstep = 0
|
||||
|
||||
@@ -158,7 +158,6 @@ var/list/ai_verbs_default = list(
|
||||
spawn(5)
|
||||
new /obj/machinery/ai_powersupply(src)
|
||||
|
||||
|
||||
hud_list[HEALTH_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
|
||||
hud_list[STATUS_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
|
||||
hud_list[LIFE_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
|
||||
@@ -199,8 +198,23 @@ var/list/ai_verbs_default = list(
|
||||
|
||||
/mob/living/silicon/ai/Destroy()
|
||||
ai_list -= src
|
||||
|
||||
qdel(eyeobj)
|
||||
..()
|
||||
eyeobj = null
|
||||
|
||||
qdel(psupply)
|
||||
psupply = null
|
||||
|
||||
qdel(aiMulti)
|
||||
aiMulti = null
|
||||
|
||||
qdel(aiRadio)
|
||||
aiRadio = null
|
||||
|
||||
qdel(aiCamera)
|
||||
aiCamera = null
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/ai/pointed(atom/A as mob|obj|turf in view())
|
||||
set popup_menu = 0
|
||||
@@ -234,20 +248,22 @@ var/list/ai_verbs_default = list(
|
||||
/obj/machinery/ai_powersupply/New(var/mob/living/silicon/ai/ai=null)
|
||||
powered_ai = ai
|
||||
powered_ai.psupply = src
|
||||
if(isnull(powered_ai))
|
||||
qdel(src)
|
||||
|
||||
loc = powered_ai.loc
|
||||
use_power(1) // Just incase we need to wake up the power system.
|
||||
forceMove(powered_ai.loc)
|
||||
|
||||
..()
|
||||
use_power(1) // Just incase we need to wake up the power system.
|
||||
|
||||
/obj/machinery/ai_powersupply/Destroy()
|
||||
. = ..()
|
||||
powered_ai = null
|
||||
|
||||
/obj/machinery/ai_powersupply/process()
|
||||
if(!powered_ai || powered_ai.stat & DEAD)
|
||||
qdel()
|
||||
if(!powered_ai || powered_ai.stat == DEAD)
|
||||
qdel(src)
|
||||
return
|
||||
if(powered_ai.psupply != src) // For some reason, the AI has different powersupply object. Delete this one, it's no longer needed.
|
||||
qdel(src)
|
||||
return
|
||||
if(powered_ai.APU_power)
|
||||
use_power = 0
|
||||
return
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
msg += "It looks slightly charred.\n"
|
||||
else
|
||||
msg += "<B>Its casing is melted and heat-warped!</B>\n"
|
||||
if (src.getOxyLoss())
|
||||
if (src.getOxyLoss() && (aiRestorePowerRoutine != 0 && !APU_power))
|
||||
if (src.getOxyLoss() > 175)
|
||||
msg += "<B>It seems to be running on backup power. Its display is blinking a \"BACKUP POWER CRITICAL\" warning.</B>\n"
|
||||
else if(src.getOxyLoss() > 100)
|
||||
|
||||
8
code/modules/mob/living/silicon/ai/nano.dm
Normal file
8
code/modules/mob/living/silicon/ai/nano.dm
Normal file
@@ -0,0 +1,8 @@
|
||||
var/obj/nano_module/crew_monitor/crew_monitor
|
||||
|
||||
/mob/living/silicon/ai/proc/nano_crew_monitor()
|
||||
set category = "AI Commands"
|
||||
set name = "Crew Monitor"
|
||||
if (!crew_monitor)
|
||||
init_subsystems()
|
||||
crew_monitor.ui_interact(usr)
|
||||
@@ -12,7 +12,7 @@
|
||||
/mob/living/silicon/proc/set_zeroth_law(var/law, var/law_borg)
|
||||
laws_sanity_check()
|
||||
laws.set_zeroth_law(law, law_borg)
|
||||
log_and_message_admins("has given [src] the zeroth laws: [law]/[law_borg ? law_borg : "N/A"]")
|
||||
log_law("has given [src] the zeroth law: '[law]'[law_borg ? " / '[law_borg]'" : ""]")
|
||||
|
||||
/mob/living/silicon/robot/set_zeroth_law(var/law, var/law_borg)
|
||||
..()
|
||||
@@ -22,40 +22,40 @@
|
||||
/mob/living/silicon/proc/add_ion_law(var/law)
|
||||
laws_sanity_check()
|
||||
laws.add_ion_law(law)
|
||||
log_and_message_admins("has given [src] the ion law: [law]")
|
||||
log_law("has given [src] the ion law: [law]")
|
||||
|
||||
/mob/living/silicon/proc/add_inherent_law(var/law)
|
||||
laws_sanity_check()
|
||||
laws.add_inherent_law(law)
|
||||
log_and_message_admins("has given [src] the inherent law: [law]")
|
||||
log_law("has given [src] the inherent law: [law]")
|
||||
|
||||
/mob/living/silicon/proc/add_supplied_law(var/number, var/law)
|
||||
laws_sanity_check()
|
||||
laws.add_supplied_law(number, law)
|
||||
log_and_message_admins("has given [src] the supplied law: [law]")
|
||||
log_law("has given [src] the supplied law: [law]")
|
||||
|
||||
/mob/living/silicon/proc/delete_law(var/datum/ai_law/law)
|
||||
laws_sanity_check()
|
||||
laws.delete_law(law)
|
||||
log_and_message_admins("has deleted a law belonging to [src]: [law.law]")
|
||||
log_law("has deleted a law belonging to [src]: [law.law]")
|
||||
|
||||
/mob/living/silicon/proc/clear_inherent_laws(var/silent = 0)
|
||||
laws_sanity_check()
|
||||
laws.clear_inherent_laws()
|
||||
if(!silent)
|
||||
log_and_message_admins("cleared the inherent laws of [src]")
|
||||
log_law("cleared the inherent laws of [src]")
|
||||
|
||||
/mob/living/silicon/proc/clear_ion_laws(var/silent = 0)
|
||||
laws_sanity_check()
|
||||
laws.clear_ion_laws()
|
||||
if(!silent)
|
||||
log_and_message_admins("cleared the ion laws of [src]")
|
||||
log_law("cleared the ion laws of [src]")
|
||||
|
||||
/mob/living/silicon/proc/clear_supplied_laws(var/silent = 0)
|
||||
laws_sanity_check()
|
||||
laws.clear_supplied_laws()
|
||||
if(!silent)
|
||||
log_and_message_admins("cleared the supplied laws of [src]")
|
||||
log_law("cleared the supplied laws of [src]")
|
||||
|
||||
/mob/living/silicon/proc/statelaws(var/datum/ai_laws/laws)
|
||||
var/prefix = ""
|
||||
@@ -102,3 +102,7 @@
|
||||
/mob/living/silicon/proc/lawsync()
|
||||
laws_sanity_check()
|
||||
laws.sort_laws()
|
||||
|
||||
/mob/living/silicon/proc/log_law(var/law_message)
|
||||
log_and_message_admins(law_message)
|
||||
lawchanges += "[worldtime2text()] - [usr ? "[key_name(usr)]" : "EVENT"] [law_message]"
|
||||
|
||||
@@ -145,13 +145,13 @@
|
||||
|
||||
/mob/living/silicon/robot/proc/handle_regular_hud_updates()
|
||||
|
||||
if (src.stat == 2 || XRAY in mutations || src.sight_mode & BORGXRAY)
|
||||
if (src.stat == 2 || (XRAY in mutations) || (src.sight_mode & BORGXRAY))
|
||||
src.sight |= SEE_TURFS
|
||||
src.sight |= SEE_MOBS
|
||||
src.sight |= SEE_OBJS
|
||||
src.see_in_dark = 8
|
||||
src.see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
else if (src.sight_mode & BORGMESON && src.sight_mode & BORGTHERM)
|
||||
else if ((src.sight_mode & BORGMESON) && (src.sight_mode & BORGTHERM))
|
||||
src.sight |= SEE_TURFS
|
||||
src.sight |= SEE_MOBS
|
||||
src.see_in_dark = 8
|
||||
@@ -160,6 +160,10 @@
|
||||
src.sight |= SEE_TURFS
|
||||
src.see_in_dark = 8
|
||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
else if (src.sight_mode & BORGMATERIAL)
|
||||
src.sight |= SEE_OBJS
|
||||
src.see_in_dark = 8
|
||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
else if (src.sight_mode & BORGTHERM)
|
||||
src.sight |= SEE_MOBS
|
||||
src.see_in_dark = 8
|
||||
|
||||
@@ -33,7 +33,9 @@
|
||||
for(var/T in temp_tech)
|
||||
files.UpdateTech(T, temp_tech[T])
|
||||
user << "\The [loaded_item] had level [temp_tech[T]] in [T]."
|
||||
loaded_item = null
|
||||
else
|
||||
user << "\The [loaded_item] was not reliable enough to advance research."
|
||||
loaded_item = null
|
||||
for(var/obj/I in contents)
|
||||
for(var/mob/M in I.contents)
|
||||
M.death()
|
||||
|
||||
@@ -34,7 +34,7 @@ var/global/list/robot_modules = list(
|
||||
var/list/obj/item/borg/upgrade/supported_upgrades = list()
|
||||
|
||||
// Bookkeeping
|
||||
var/list/added_languages = list()
|
||||
var/list/original_languages = list()
|
||||
var/list/added_networks = list()
|
||||
|
||||
/obj/item/weapon/robot_module/New(var/mob/living/silicon/robot/R)
|
||||
@@ -63,12 +63,14 @@ var/global/list/robot_modules = list(
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/robot_module/Destroy()
|
||||
qdel(modules)
|
||||
qdel(synths)
|
||||
for(var/obj/O in modules)
|
||||
qdel(O)
|
||||
modules.Cut()
|
||||
for(var/datum/matter_synth/S in synths)
|
||||
qdel(S)
|
||||
synths.Cut()
|
||||
qdel(emag)
|
||||
qdel(jetpack)
|
||||
modules = null
|
||||
synths = null
|
||||
emag = null
|
||||
jetpack = null
|
||||
return ..()
|
||||
@@ -86,6 +88,15 @@ var/global/list/robot_modules = list(
|
||||
return
|
||||
|
||||
/obj/item/weapon/robot_module/proc/respawn_consumable(var/mob/living/silicon/robot/R, var/rate)
|
||||
var/obj/item/device/flash/F = locate() in src.modules
|
||||
if(F)
|
||||
if(F.broken)
|
||||
F.broken = 0
|
||||
F.times_used = 0
|
||||
F.icon_state = "flash"
|
||||
else if(F.times_used)
|
||||
F.times_used--
|
||||
|
||||
if(!synths || !synths.len)
|
||||
return
|
||||
|
||||
@@ -100,14 +111,22 @@ var/global/list/robot_modules = list(
|
||||
modules += O
|
||||
|
||||
/obj/item/weapon/robot_module/proc/add_languages(var/mob/living/silicon/robot/R)
|
||||
// Stores the languages as they were before receiving the module, and whether they could be synthezized.
|
||||
for(var/datum/language/language_datum in R.languages)
|
||||
original_languages[language_datum] = (language_datum in R.speech_synthesizer_langs)
|
||||
|
||||
for(var/language in languages)
|
||||
if(R.add_language(language, languages[language]))
|
||||
added_languages |= language
|
||||
R.add_language(language, languages[language])
|
||||
|
||||
/obj/item/weapon/robot_module/proc/remove_languages(var/mob/living/silicon/robot/R)
|
||||
for(var/language in added_languages)
|
||||
// Clear all added languages, whether or not we originally had them.
|
||||
for(var/language in languages)
|
||||
R.remove_language(language)
|
||||
added_languages.Cut()
|
||||
|
||||
// Then add back all the original languages, and the relevant synthezising ability
|
||||
for(var/original_language in original_languages)
|
||||
R.add_language(original_language, original_languages[original_language])
|
||||
original_languages.Cut()
|
||||
|
||||
/obj/item/weapon/robot_module/proc/add_camera_networks(var/mob/living/silicon/robot/R)
|
||||
if(R.camera && (NETWORK_ROBOTS in R.camera.network))
|
||||
@@ -261,7 +280,6 @@ var/global/list/robot_modules = list(
|
||||
return
|
||||
|
||||
/obj/item/weapon/robot_module/medical/crisis/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
|
||||
|
||||
var/obj/item/weapon/reagent_containers/syringe/S = locate() in src.modules
|
||||
if(S.mode == 2)
|
||||
S.reagents.clear_reagents()
|
||||
@@ -304,6 +322,7 @@ var/global/list/robot_modules = list(
|
||||
src.modules += new /obj/item/weapon/crowbar(src)
|
||||
src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src)
|
||||
src.modules += new /obj/item/device/pipe_painter(src)
|
||||
src.modules += new /obj/item/weapon/gripper/no_use/loader(src)
|
||||
|
||||
var/datum/matter_synth/metal = new /datum/matter_synth/metal()
|
||||
var/datum/matter_synth/plasteel = new /datum/matter_synth/plasteel()
|
||||
@@ -414,13 +433,7 @@ var/global/list/robot_modules = list(
|
||||
return
|
||||
|
||||
/obj/item/weapon/robot_module/security/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
|
||||
var/obj/item/device/flash/F = locate() in src.modules
|
||||
if(F.broken)
|
||||
F.broken = 0
|
||||
F.times_used = 0
|
||||
F.icon_state = "flash"
|
||||
else if(F.times_used)
|
||||
F.times_used--
|
||||
..()
|
||||
var/obj/item/weapon/gun/energy/taser/mounted/cyborg/T = locate() in src.modules
|
||||
if(T.power_supply.charge < T.power_supply.maxcharge)
|
||||
T.power_supply.give(T.charge_cost * amount)
|
||||
@@ -454,6 +467,7 @@ var/global/list/robot_modules = list(
|
||||
return
|
||||
|
||||
/obj/item/weapon/robot_module/janitor/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
|
||||
..()
|
||||
var/obj/item/device/lightreplacer/LR = locate() in src.modules
|
||||
LR.Charge(R, amount)
|
||||
if(src.emag)
|
||||
@@ -537,6 +551,7 @@ var/global/list/robot_modules = list(
|
||||
src.emag = new /obj/item/weapon/stamp/denied(src)
|
||||
|
||||
/obj/item/weapon/robot_module/general/butler/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
|
||||
..()
|
||||
var/obj/item/weapon/reagent_containers/food/condiment/enzyme/E = locate() in src.modules
|
||||
E.reagents.add_reagent("enzyme", 2 * amount)
|
||||
if(src.emag)
|
||||
@@ -558,7 +573,7 @@ var/global/list/robot_modules = list(
|
||||
/obj/item/weapon/robot_module/miner/New()
|
||||
..()
|
||||
src.modules += new /obj/item/device/flash(src)
|
||||
src.modules += new /obj/item/borg/sight/meson(src)
|
||||
src.modules += new /obj/item/borg/sight/material(src)
|
||||
src.modules += new /obj/item/weapon/wrench(src)
|
||||
src.modules += new /obj/item/weapon/screwdriver(src)
|
||||
src.modules += new /obj/item/weapon/storage/bag/ore(src)
|
||||
@@ -661,6 +676,7 @@ var/global/list/robot_modules = list(
|
||||
src.modules += new /obj/item/device/lightreplacer(src)
|
||||
src.modules += new /obj/item/weapon/gripper(src)
|
||||
src.modules += new /obj/item/weapon/soap(src)
|
||||
src.modules += new /obj/item/weapon/gripper/no_use/loader(src)
|
||||
src.emag = new /obj/item/weapon/pickaxe/plasmacutter(src)
|
||||
src.emag.name = "Plasma Cutter"
|
||||
|
||||
|
||||
@@ -68,31 +68,46 @@
|
||||
if (!message)
|
||||
return
|
||||
|
||||
var/obj/machinery/hologram/holopad/T = src.holo
|
||||
if(T && T.masters[src])//If there is a hologram and its master is the user.
|
||||
|
||||
//Human-like, sorta, heard by those who understand humans.
|
||||
var/rendered_a
|
||||
//Speach distorted, heard by those who do not understand AIs.
|
||||
var/message_stars = stars(message)
|
||||
var/rendered_b
|
||||
var/obj/machinery/hologram/holopad/H = src.holo
|
||||
if(H && H.masters[src])//If there is a hologram and its master is the user.
|
||||
|
||||
// AI can hear their own message, this formats it for them.
|
||||
if(speaking)
|
||||
rendered_a = "<span class='game say'><span class='name'>[name]</span> [speaking.format_message(message, verb)]</span>"
|
||||
rendered_b = "<span class='game say'><span class='name'>[voice_name]</span> [speaking.format_message(message_stars, verb)]</span>"
|
||||
src << "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> [speaking.format_message(message, verb)]</span></i>"//The AI can "hear" its own message.
|
||||
src << "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> [speaking.format_message(message, verb)]</span></i>"
|
||||
else
|
||||
rendered_a = "<span class='game say'><span class='name'>[name]</span> [verb], <span class='message'>\"[message]\"</span></span>"
|
||||
rendered_b = "<span class='game say'><span class='name'>[voice_name]</span> [verb], <span class='message'>\"[message_stars]\"</span></span>"
|
||||
src << "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> [verb], <span class='message'><span class='body'>\"[message]\"</span></span></span></i>"//The AI can "hear" its own message.
|
||||
src << "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> [verb], <span class='message'><span class='body'>\"[message]\"</span></span></span></i>"
|
||||
|
||||
//This is so pAI's and people inside lockers/boxes,etc can hear the AI Holopad, the alternative being recursion through contents.
|
||||
//This is much faster.
|
||||
var/list/listening = list()
|
||||
var/list/listening_obj = list()
|
||||
var/turf/T = get_turf(H)
|
||||
|
||||
if(T)
|
||||
var/list/hear = hear(7, T)
|
||||
var/list/hearturfs = list()
|
||||
|
||||
for(var/I in hear)
|
||||
if(istype(I, /mob/))
|
||||
var/mob/M = I
|
||||
listening += M
|
||||
hearturfs += M.locs[1]
|
||||
for(var/obj/O in M.contents)
|
||||
listening_obj |= O
|
||||
else if(istype(I, /obj/))
|
||||
var/obj/O = I
|
||||
hearturfs += O.locs[1]
|
||||
listening_obj |= O
|
||||
|
||||
|
||||
for(var/mob/M in player_list)
|
||||
if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS))
|
||||
M.hear_say(message,verb,speaking,null,null, src)
|
||||
continue
|
||||
if(M.loc && M.locs[1] in hearturfs)
|
||||
M.hear_say(message,verb,speaking,null,null, src)
|
||||
|
||||
|
||||
for(var/mob/M in hearers(T.loc))//The location is the object, default distance.
|
||||
if(M.say_understands(src))//If they understand AI speak. Humans and the like will be able to.
|
||||
M.show_message(rendered_a, 2)
|
||||
else//If they do not.
|
||||
M.show_message(rendered_b, 2)
|
||||
/*Radios "filter out" this conversation channel so we don't need to account for them.
|
||||
This is another way of saying that we won't bother dealing with them.*/
|
||||
else
|
||||
src << "No holopad connected."
|
||||
return 0
|
||||
|
||||
@@ -188,16 +188,22 @@
|
||||
return universal_speak || (speaking in src.speech_synthesizer_langs) //need speech synthesizer support to vocalize a language
|
||||
|
||||
/mob/living/silicon/add_language(var/language, var/can_speak=1)
|
||||
if (..(language) && can_speak)
|
||||
speech_synthesizer_langs.Add(all_languages[language])
|
||||
var/var/datum/language/added_language = all_languages[language]
|
||||
if(!added_language)
|
||||
return
|
||||
|
||||
. = ..(language)
|
||||
if (can_speak && (added_language in languages) && !(added_language in speech_synthesizer_langs))
|
||||
speech_synthesizer_langs += added_language
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/remove_language(var/rem_language)
|
||||
..(rem_language)
|
||||
var/var/datum/language/removed_language = all_languages[rem_language]
|
||||
if(!removed_language)
|
||||
return
|
||||
|
||||
for (var/datum/language/L in speech_synthesizer_langs)
|
||||
if (L.name == rem_language)
|
||||
speech_synthesizer_langs -= L
|
||||
..(rem_language)
|
||||
speech_synthesizer_langs -= removed_language
|
||||
|
||||
/mob/living/silicon/check_languages()
|
||||
set name = "Check Known Languages"
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
set name = "Law Manager"
|
||||
set category = "Subystems"
|
||||
|
||||
law_manager.ui_interact(usr, state = self_state)
|
||||
law_manager.ui_interact(usr, state = conscious_state)
|
||||
|
||||
/********************
|
||||
* Power Monitor *
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
var/mob/living/carbon/human/H = M
|
||||
|
||||
var/obj/item/organ/external/E = H.organs_by_name["head"]
|
||||
if(!E || (E.status & ORGAN_DESTROYED))
|
||||
if(!E || E.is_stump())
|
||||
src << "\The [H] does not have a head!"
|
||||
|
||||
if(!H.species.has_organ["brain"])
|
||||
|
||||
@@ -14,74 +14,68 @@
|
||||
|
||||
//////////////////////////////Capturing////////////////////////////////////////////////////////
|
||||
|
||||
attack(mob/living/carbon/human/M as mob, mob/user as mob)
|
||||
if(!istype(M, /mob/living/carbon/human))//If target is not a human.
|
||||
return ..()
|
||||
if(istype(M, /mob/living/carbon/human/dummy))
|
||||
return..()
|
||||
/obj/item/device/soulstone/attack(mob/living/carbon/human/M as mob, mob/user as mob)
|
||||
if(!istype(M, /mob/living/carbon/human))//If target is not a human.
|
||||
return ..()
|
||||
if(istype(M, /mob/living/carbon/human/dummy))
|
||||
return..()
|
||||
|
||||
if(M.has_brain_worms()) //Borer stuff - RR
|
||||
user << "<span class='warning'>This being is corrupted by an alien intelligence and cannot be soul trapped.</span>"
|
||||
return..()
|
||||
if(M.has_brain_worms()) //Borer stuff - RR
|
||||
user << "<span class='warning'>This being is corrupted by an alien intelligence and cannot be soul trapped.</span>"
|
||||
return..()
|
||||
|
||||
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their soul captured with [src.name] by [user.name] ([user.ckey])</font>")
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to capture the soul of [M.name] ([M.ckey])</font>")
|
||||
msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to capture the soul of [M.name] ([M.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has had their soul captured with [src.name] by [user.name] ([user.ckey])</font>")
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to capture the soul of [M.name] ([M.ckey])</font>")
|
||||
msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to capture the soul of [M.name] ([M.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
|
||||
transfer_soul("VICTIM", M, user)
|
||||
return
|
||||
transfer_soul("VICTIM", M, user)
|
||||
return
|
||||
|
||||
/*attack(mob/living/simple_animal/shade/M as mob, mob/user as mob)//APPARENTLY THEY NEED THEIR OWN SPECIAL SNOWFLAKE CODE IN THE LIVING ANIMAL DEFINES
|
||||
if(!istype(M, /mob/living/simple_animal/shade))//If target is not a shade
|
||||
return ..()
|
||||
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to capture the soul of [M.name] ([M.ckey])</font>")
|
||||
|
||||
transfer_soul("SHADE", M, user)
|
||||
return*/
|
||||
///////////////////Options for using captured souls///////////////////////////////////////
|
||||
|
||||
attack_self(mob/user)
|
||||
if (!in_range(src, user))
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = "<TT><B>Soul Stone</B><BR>"
|
||||
for(var/mob/living/simple_animal/shade/A in src)
|
||||
dat += "Captured Soul: [A.name]<br>"
|
||||
dat += {"<A href='byond://?src=\ref[src];choice=Summon'>Summon Shade</A>"}
|
||||
dat += "<br>"
|
||||
dat += {"<a href='byond://?src=\ref[src];choice=Close'> Close</a>"}
|
||||
user << browse(dat, "window=aicard")
|
||||
onclose(user, "aicard")
|
||||
/obj/item/device/soulstone/attack_self(mob/user)
|
||||
if (!in_range(src, user))
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = "<TT><B>Soul Stone</B><BR>"
|
||||
for(var/mob/living/simple_animal/shade/A in src)
|
||||
dat += "Captured Soul: [A.name]<br>"
|
||||
dat += {"<A href='byond://?src=\ref[src];choice=Summon'>Summon Shade</A>"}
|
||||
dat += "<br>"
|
||||
dat += {"<a href='byond://?src=\ref[src];choice=Close'> Close</a>"}
|
||||
user << browse(dat, "window=aicard")
|
||||
onclose(user, "aicard")
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/device/soulstone/Topic(href, href_list)
|
||||
var/mob/U = usr
|
||||
if (!in_range(src, U)||U.machine!=src)
|
||||
U << browse(null, "window=aicard")
|
||||
U.unset_machine()
|
||||
return
|
||||
|
||||
add_fingerprint(U)
|
||||
U.set_machine(src)
|
||||
|
||||
|
||||
|
||||
Topic(href, href_list)
|
||||
var/mob/U = usr
|
||||
if (!in_range(src, U)||U.machine!=src)
|
||||
switch(href_list["choice"])//Now we switch based on choice.
|
||||
if ("Close")
|
||||
U << browse(null, "window=aicard")
|
||||
U.unset_machine()
|
||||
return
|
||||
|
||||
add_fingerprint(U)
|
||||
U.set_machine(src)
|
||||
|
||||
switch(href_list["choice"])//Now we switch based on choice.
|
||||
if ("Close")
|
||||
U << browse(null, "window=aicard")
|
||||
U.unset_machine()
|
||||
return
|
||||
|
||||
if ("Summon")
|
||||
for(var/mob/living/simple_animal/shade/A in src)
|
||||
A.status_flags &= ~GODMODE
|
||||
A.canmove = 1
|
||||
A << "<b>You have been released from your prison, but you are still bound to [U.name]'s will. Help them suceed in their goals at all costs.</b>"
|
||||
A.loc = U.loc
|
||||
A.cancel_camera()
|
||||
src.icon_state = "soulstone"
|
||||
attack_self(U)
|
||||
if ("Summon")
|
||||
for(var/mob/living/simple_animal/shade/A in src)
|
||||
A.status_flags &= ~GODMODE
|
||||
A.canmove = 1
|
||||
A << "<b>You have been released from your prison, but you are still bound to [U.name]'s will. Help them suceed in their goals at all costs.</b>"
|
||||
A.forceMove(U.loc)
|
||||
A.cancel_camera()
|
||||
src.icon_state = "soulstone"
|
||||
attack_self(U)
|
||||
|
||||
///////////////////////////Transferring to constructs/////////////////////////////////////////////////////
|
||||
/obj/structure/constructshell
|
||||
@@ -99,118 +93,127 @@
|
||||
|
||||
/obj/structure/constructshell/attackby(obj/item/O as obj, mob/user as mob)
|
||||
if(istype(O, /obj/item/device/soulstone))
|
||||
O.transfer_soul("CONSTRUCT",src,user)
|
||||
var/obj/item/device/soulstone/S = O;
|
||||
S.transfer_soul("CONSTRUCT",src,user)
|
||||
|
||||
|
||||
////////////////////////////Proc for moving soul in and out off stone//////////////////////////////////////
|
||||
/obj/item/device/soulstone/proc/transfer_human(var/mob/living/carbon/human/T,var/mob/U)
|
||||
if(!istype(T))
|
||||
return;
|
||||
if(src.imprinted != "empty")
|
||||
U << "<span class='danger'>Capture failed!</span>: The soul stone has already been imprinted with [src.imprinted]'s mind!"
|
||||
return
|
||||
if ((T.health + T.halloss) > config.health_threshold_crit && T.stat != DEAD)
|
||||
U << "<span class='danger'>Capture failed!</span>: Kill or maim the victim first!"
|
||||
return
|
||||
if(T.client == null)
|
||||
U << "<span class='danger'>Capture failed!</span>: The soul has already fled it's mortal frame."
|
||||
return
|
||||
if(src.contents.len)
|
||||
U << "<span class='danger'>Capture failed!</span>: The soul stone is full! Use or free an existing soul to make room."
|
||||
return
|
||||
|
||||
for(var/obj/item/W in T)
|
||||
T.drop_from_inventory(W)
|
||||
|
||||
new /obj/effect/decal/remains/human(T.loc) //Spawns a skeleton
|
||||
T.invisibility = 101
|
||||
|
||||
var/atom/movable/overlay/animation = new /atom/movable/overlay( T.loc )
|
||||
animation.icon_state = "blank"
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.master = T
|
||||
flick("dust-h", animation)
|
||||
qdel(animation)
|
||||
|
||||
var/mob/living/simple_animal/shade/S = new /mob/living/simple_animal/shade( T.loc )
|
||||
S.loc = src //put shade in stone
|
||||
S.status_flags |= GODMODE //So they won't die inside the stone somehow
|
||||
S.canmove = 0//Can't move out of the soul stone
|
||||
S.name = "Shade of [T.real_name]"
|
||||
S.real_name = "Shade of [T.real_name]"
|
||||
S.icon = T.icon
|
||||
S.icon_state = T.icon_state
|
||||
S.overlays = T.overlays
|
||||
S.color = rgb(254,0,0)
|
||||
S.alpha = 127
|
||||
if (T.client)
|
||||
T.client.mob = S
|
||||
S.cancel_camera()
|
||||
|
||||
|
||||
/obj/item/proc/transfer_soul(var/choice as text, var/target, var/mob/U as mob).
|
||||
src.icon_state = "soulstone2"
|
||||
src.name = "Soul Stone: [S.real_name]"
|
||||
S << "Your soul has been captured! You are now bound to [U.name]'s will, help them suceed in their goals at all costs."
|
||||
U << "<span class='notice'>Capture successful!</span> : [T.real_name]'s soul has been ripped from their body and stored within the soul stone."
|
||||
U << "The soulstone has been imprinted with [S.real_name]'s mind, it will no longer react to other souls."
|
||||
src.imprinted = "[S.name]"
|
||||
qdel(T)
|
||||
|
||||
/obj/item/device/soulstone/proc/transfer_shade(var/mob/living/simple_animal/shade/T,var/mob/U)
|
||||
if(!istype(T))
|
||||
return;
|
||||
if (T.stat == DEAD)
|
||||
U << "<span class='danger'>Capture failed!</span>: The shade has already been banished!"
|
||||
return
|
||||
if(src.contents.len)
|
||||
U << "<span class='danger'>Capture failed!</span>: The soul stone is full! Use or free an existing soul to make room."
|
||||
return
|
||||
if(T.name != src.imprinted)
|
||||
U << "<span class='danger'>Capture failed!</span>: The soul stone has already been imprinted with [src.imprinted]'s mind!"
|
||||
return
|
||||
|
||||
T.loc = src //put shade in stone
|
||||
T.status_flags |= GODMODE
|
||||
T.canmove = 0
|
||||
T.health = T.maxHealth
|
||||
src.icon_state = "soulstone2"
|
||||
|
||||
T << "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form"
|
||||
U << "<span class='notice'>Capture successful!</span> : [T.name]'s has been recaptured and stored within the soul stone."
|
||||
/obj/item/device/soulstone/proc/transfer_construct(var/obj/structure/constructshell/T,var/mob/U)
|
||||
var/mob/living/simple_animal/shade/A = locate() in src
|
||||
if(!A)
|
||||
U << "<span class='danger'>Capture failed!</span>: The soul stone is empty! Go kill someone!"
|
||||
return;
|
||||
var/construct_class = alert(U, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer")
|
||||
switch(construct_class)
|
||||
if("Juggernaut")
|
||||
var/mob/living/simple_animal/construct/armoured/Z = new /mob/living/simple_animal/construct/armoured (get_turf(T.loc))
|
||||
Z.key = A.key
|
||||
if(iscultist(U))
|
||||
cult.add_antagonist(Z.mind)
|
||||
qdel(T)
|
||||
Z << "<B>You are playing a Juggernaut. Though slow, you can withstand extreme punishment, and rip apart enemies and walls alike.</B>"
|
||||
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
|
||||
Z.cancel_camera()
|
||||
qdel(src)
|
||||
if("Wraith")
|
||||
var/mob/living/simple_animal/construct/wraith/Z = new /mob/living/simple_animal/construct/wraith (get_turf(T.loc))
|
||||
Z.key = A.key
|
||||
if(iscultist(U))
|
||||
cult.add_antagonist(Z.mind)
|
||||
qdel(T)
|
||||
Z << "<B>You are playing a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.</B>"
|
||||
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
|
||||
Z.cancel_camera()
|
||||
qdel(src)
|
||||
if("Artificer")
|
||||
var/mob/living/simple_animal/construct/builder/Z = new /mob/living/simple_animal/construct/builder (get_turf(T.loc))
|
||||
Z.key = A.key
|
||||
if(iscultist(U))
|
||||
cult.add_antagonist(Z.mind)
|
||||
qdel(T)
|
||||
Z << "<B>You are playing an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, repair allied constructs (by clicking on them), and even create new constructs</B>"
|
||||
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
|
||||
Z.cancel_camera()
|
||||
qdel(src)
|
||||
/obj/item/device/soulstone/proc/transfer_soul(var/choice as text, var/target, var/mob/U as mob).
|
||||
switch(choice)
|
||||
if("VICTIM")
|
||||
var/mob/living/carbon/human/T = target
|
||||
var/obj/item/device/soulstone/C = src
|
||||
if(C.imprinted != "empty")
|
||||
U << "\red <b>Capture failed!</b>: \black The soul stone has already been imprinted with [C.imprinted]'s mind!"
|
||||
else
|
||||
if ((T.health + T.halloss) > config.health_threshold_crit)
|
||||
U << "\red <b>Capture failed!</b>: \black Kill or maim the victim first!"
|
||||
else
|
||||
if(T.client == null)
|
||||
U << "\red <b>Capture failed!</b>: \black The soul has already fled it's mortal frame."
|
||||
else
|
||||
if(C.contents.len)
|
||||
U << "\red <b>Capture failed!</b>: \black The soul stone is full! Use or free an existing soul to make room."
|
||||
else
|
||||
for(var/obj/item/W in T)
|
||||
T.drop_from_inventory(W)
|
||||
new /obj/effect/decal/remains/human(T.loc) //Spawns a skeleton
|
||||
T.invisibility = 101
|
||||
var/atom/movable/overlay/animation = new /atom/movable/overlay( T.loc )
|
||||
animation.icon_state = "blank"
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.master = T
|
||||
flick("dust-h", animation)
|
||||
qdel(animation)
|
||||
var/mob/living/simple_animal/shade/S = new /mob/living/simple_animal/shade( T.loc )
|
||||
S.loc = C //put shade in stone
|
||||
S.status_flags |= GODMODE //So they won't die inside the stone somehow
|
||||
S.canmove = 0//Can't move out of the soul stone
|
||||
S.name = "Shade of [T.real_name]"
|
||||
S.real_name = "Shade of [T.real_name]"
|
||||
S.icon = T.icon
|
||||
S.icon_state = T.icon_state
|
||||
S.overlays = T.overlays
|
||||
S.color = rgb(254,0,0)
|
||||
S.alpha = 127
|
||||
if (T.client)
|
||||
T.client.mob = S
|
||||
S.cancel_camera()
|
||||
C.icon_state = "soulstone2"
|
||||
C.name = "Soul Stone: [S.real_name]"
|
||||
S << "Your soul has been captured! You are now bound to [U.name]'s will, help them suceed in their goals at all costs."
|
||||
U << "\blue <b>Capture successful!</b>: \black [T.real_name]'s soul has been ripped from their body and stored within the soul stone."
|
||||
U << "The soulstone has been imprinted with [S.real_name]'s mind, it will no longer react to other souls."
|
||||
C.imprinted = "[S.name]"
|
||||
qdel(T)
|
||||
transfer_human(target,U)
|
||||
if("SHADE")
|
||||
var/mob/living/simple_animal/shade/T = target
|
||||
var/obj/item/device/soulstone/C = src
|
||||
if (T.stat == DEAD)
|
||||
U << "\red <b>Capture failed!</b>: \black The shade has already been banished!"
|
||||
else
|
||||
if(C.contents.len)
|
||||
U << "\red <b>Capture failed!</b>: \black The soul stone is full! Use or free an existing soul to make room."
|
||||
else
|
||||
if(T.name != C.imprinted)
|
||||
U << "\red <b>Capture failed!</b>: \black The soul stone has already been imprinted with [C.imprinted]'s mind!"
|
||||
else
|
||||
T.loc = C //put shade in stone
|
||||
T.status_flags |= GODMODE
|
||||
T.canmove = 0
|
||||
T.health = T.maxHealth
|
||||
C.icon_state = "soulstone2"
|
||||
T << "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form"
|
||||
U << "\blue <b>Capture successful!</b>: \black [T.name]'s has been recaptured and stored within the soul stone."
|
||||
transfer_shade(target,U)
|
||||
if("CONSTRUCT")
|
||||
var/obj/structure/constructshell/T = target
|
||||
var/obj/item/device/soulstone/C = src
|
||||
var/mob/living/simple_animal/shade/A = locate() in C
|
||||
if(A)
|
||||
var/construct_class = alert(U, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer")
|
||||
switch(construct_class)
|
||||
if("Juggernaut")
|
||||
var/mob/living/simple_animal/construct/armoured/Z = new /mob/living/simple_animal/construct/armoured (get_turf(T.loc))
|
||||
Z.key = A.key
|
||||
if(iscultist(U))
|
||||
cult.add_antagonist(Z.mind)
|
||||
qdel(T)
|
||||
Z << "<B>You are playing a Juggernaut. Though slow, you can withstand extreme punishment, and rip apart enemies and walls alike.</B>"
|
||||
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
|
||||
Z.cancel_camera()
|
||||
qdel(C)
|
||||
|
||||
if("Wraith")
|
||||
var/mob/living/simple_animal/construct/wraith/Z = new /mob/living/simple_animal/construct/wraith (get_turf(T.loc))
|
||||
Z.key = A.key
|
||||
if(iscultist(U))
|
||||
cult.add_antagonist(Z.mind)
|
||||
qdel(T)
|
||||
Z << "<B>You are playing a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.</B>"
|
||||
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
|
||||
Z.cancel_camera()
|
||||
qdel(C)
|
||||
|
||||
if("Artificer")
|
||||
var/mob/living/simple_animal/construct/builder/Z = new /mob/living/simple_animal/construct/builder (get_turf(T.loc))
|
||||
Z.key = A.key
|
||||
if(iscultist(U))
|
||||
cult.add_antagonist(Z.mind)
|
||||
qdel(T)
|
||||
Z << "<B>You are playing an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, repair allied constructs (by clicking on them), and even create new constructs</B>"
|
||||
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
|
||||
Z.cancel_camera()
|
||||
qdel(C)
|
||||
else
|
||||
U << "\red <b>Creation failed!</b>: \black The soul stone is empty! Go kill someone!"
|
||||
return
|
||||
transfer_construct(target,U)
|
||||
|
||||
@@ -37,7 +37,8 @@
|
||||
|
||||
/mob/living/simple_animal/shade/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri
|
||||
if(istype(O, /obj/item/device/soulstone))
|
||||
O.transfer_soul("SHADE", src, user)
|
||||
var/obj/item/device/soulstone/S = O;
|
||||
S.transfer_soul("SHADE", src, user)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/shade/proc/OnDeathInLife()
|
||||
|
||||
@@ -658,17 +658,17 @@
|
||||
if(!TurfAdjacent(listed_turf))
|
||||
listed_turf = null
|
||||
else
|
||||
statpanel(listed_turf.name, null, listed_turf)
|
||||
for(var/atom/A in listed_turf)
|
||||
if(!A.mouse_opacity)
|
||||
continue
|
||||
if(A.invisibility > see_invisible)
|
||||
continue
|
||||
if(is_type_in_list(A, shouldnt_see))
|
||||
continue
|
||||
statpanel(listed_turf.name, null, A)
|
||||
if(statpanel("Turf"))
|
||||
stat("\icon[listed_turf]", listed_turf.name)
|
||||
for(var/atom/A in listed_turf)
|
||||
if(!A.mouse_opacity)
|
||||
continue
|
||||
if(A.invisibility > see_invisible)
|
||||
continue
|
||||
if(is_type_in_list(A, shouldnt_see))
|
||||
continue
|
||||
stat(A)
|
||||
|
||||
sleep(4) //Prevent updating the stat panel for the next .4 seconds, prevents clientside latency from updates
|
||||
|
||||
// facing verbs
|
||||
/mob/proc/canface()
|
||||
|
||||
@@ -214,8 +214,9 @@
|
||||
|
||||
var/stance_damage = 0 //Whether this mob's ability to stand has been affected
|
||||
|
||||
//Indicates if a clientless mob is actually an admin aghosting
|
||||
var/mob/dead/observer/aghosted = null
|
||||
//If set, indicates that the client "belonging" to this (clientless) mob is currently controlling some other mob
|
||||
//so don't treat them as being SSD even though their client var is null.
|
||||
var/mob/teleop = null
|
||||
|
||||
var/turf/listed_turf = null //the current turf being examined in the stat panel
|
||||
var/list/shouldnt_see = list() //list of objects that this mob shouldn't see in the stat panel. this silliness is needed because of AI alt+click and cult blood runes
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
var/obj/item/organ/external/E = H.get_organ(target_zone)
|
||||
|
||||
if(!E || (E.status & ORGAN_DESTROYED))
|
||||
if(!E || E.is_stump())
|
||||
user << "<span class='notice'>[H] is missing that bodypart.</span>"
|
||||
return
|
||||
|
||||
|
||||
@@ -640,7 +640,7 @@ proc/is_blind(A)
|
||||
// A proper CentCom id is hard currency.
|
||||
else if(id && istype(id, /obj/item/weapon/card/id/centcom))
|
||||
return SAFE_PERP
|
||||
|
||||
|
||||
if(check_access && !access_obj.allowed(src))
|
||||
threatcount += 4
|
||||
|
||||
|
||||
@@ -295,7 +295,7 @@
|
||||
var/mob/living/carbon/human/driver = mob.buckled
|
||||
var/obj/item/organ/external/l_hand = driver.get_organ("l_hand")
|
||||
var/obj/item/organ/external/r_hand = driver.get_organ("r_hand")
|
||||
if((!l_hand || (l_hand.status & ORGAN_DESTROYED)) && (!r_hand || (r_hand.status & ORGAN_DESTROYED)))
|
||||
if((!l_hand || l_hand.is_stump()) && (!r_hand || r_hand.is_stump()))
|
||||
return // No hands to drive your chair? Tough luck!
|
||||
//drunk wheelchair driving
|
||||
if(mob.confused)
|
||||
|
||||
@@ -289,7 +289,7 @@
|
||||
|
||||
|
||||
proc/AttemptLateSpawn(rank,var/spawning_at)
|
||||
if (src != usr)
|
||||
if(src != usr)
|
||||
return 0
|
||||
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
|
||||
usr << "\red The round is either not ready, or has already finished..."
|
||||
@@ -323,7 +323,7 @@
|
||||
character.loc = C.loc
|
||||
|
||||
AnnounceCyborg(character, rank, "has been downloaded to the empty core in \the [character.loc.loc]")
|
||||
ticker.mode.latespawn(character)
|
||||
ticker.mode.handle_latejoin(character)
|
||||
|
||||
qdel(C)
|
||||
qdel(src)
|
||||
@@ -354,7 +354,7 @@
|
||||
character.buckled.loc = character.loc
|
||||
character.buckled.set_dir(character.dir)
|
||||
|
||||
ticker.mode.latespawn(character)
|
||||
ticker.mode.handle_latejoin(character)
|
||||
|
||||
if(character.mind.assigned_role != "Cyborg")
|
||||
data_core.manifest_inject(character)
|
||||
|
||||
Reference in New Issue
Block a user