Merge branch 'master' into FERMICHEMCurTweaks

This commit is contained in:
Thalpy
2019-10-11 22:23:18 +01:00
committed by GitHub
215 changed files with 56945 additions and 56254 deletions
-61
View File
@@ -1,61 +0,0 @@
/mob/living/carbon/human/virtual_reality
var/datum/mind/real_mind // where is my mind t. pixies
var/obj/machinery/vr_sleeper/vr_sleeper
var/datum/action/quit_vr/quit_action
/mob/living/carbon/human/virtual_reality/Initialize()
. = ..()
quit_action = new()
quit_action.Grant(src)
/mob/living/carbon/human/virtual_reality/death()
revert_to_reality()
..()
/mob/living/carbon/human/virtual_reality/Destroy()
revert_to_reality()
return ..()
/mob/living/carbon/human/virtual_reality/Life()
. = ..()
if(real_mind)
var/mob/living/real_me = real_mind.current
if (real_me && real_me.stat == CONSCIOUS)
return
revert_to_reality(FALSE)
/mob/living/carbon/human/virtual_reality/ghostize()
stack_trace("Ghostize was called on a virtual reality mob")
/mob/living/carbon/human/virtual_reality/ghost()
set category = "OOC"
set name = "Ghost"
set desc = "Relinquish your life and enter the land of the dead."
revert_to_reality(FALSE)
/mob/living/carbon/human/virtual_reality/proc/revert_to_reality(deathchecks = TRUE)
if(real_mind && mind)
real_mind.current.audiovisual_redirect = null
real_mind.current.ckey = ckey
real_mind.current.stop_sound_channel(CHANNEL_HEARTBEAT)
if(deathchecks && vr_sleeper)
if(vr_sleeper.you_die_in_the_game_you_die_for_real)
to_chat(real_mind, "<span class='warning'>You feel everything fading away...</span>")
real_mind.current.death(0)
if(deathchecks && vr_sleeper)
vr_sleeper.vr_human = null
vr_sleeper = null
real_mind = null
/datum/action/quit_vr
name = "Quit Virtual Reality"
icon_icon = 'icons/mob/actions/actions_vr.dmi'
button_icon_state = "logout"
/datum/action/quit_vr/Trigger()
if(..())
if(istype(owner, /mob/living/carbon/human/virtual_reality))
var/mob/living/carbon/human/virtual_reality/VR = owner
VR.revert_to_reality(FALSE)
else
Remove(owner)
+44
View File
@@ -0,0 +1,44 @@
/mob/proc/build_virtual_character(mob/M)
mind_initialize()
if(!M)
return FALSE
name = M.name
real_name = M.real_name
mind.name = M.real_name
return TRUE
/mob/living/carbon/build_virtual_character(mob/M)
. = ..()
if(!.)
return
if(iscarbon(M))
var/mob/living/carbon/C = M
C.dna?.transfer_identity(src)
/mob/living/carbon/human/build_virtual_character(mob/M, datum/outfit/outfit)
. = ..()
if(!.)
return
var/mob/living/carbon/human/H
if(ishuman(M))
H = M
socks = H ? H.socks : random_socks()
socks_color = H ? H.socks_color : random_color()
undershirt = H ? H.undershirt : random_undershirt(M.gender)
shirt_color = H ? H.shirt_color : random_color()
underwear = H ? H.underwear : random_underwear(M.gender)
undie_color = H ? H.undie_color : random_color()
give_genitals(TRUE)
if(outfit)
var/datum/outfit/O = new outfit()
O.equip(src)
/datum/action/quit_vr
name = "Quit Virtual Reality"
icon_icon = 'icons/mob/actions/actions_vr.dmi'
button_icon_state = "logout"
/datum/action/quit_vr/Trigger() //this merely a trigger for /datum/component/virtual_reality
. = ..()
if(!.)
Remove(owner)
+56 -69
View File
@@ -1,5 +1,3 @@
//Glorified teleporter that puts you in a new human body.
// it's """VR"""
/obj/machinery/vr_sleeper
@@ -12,9 +10,10 @@
circuit = /obj/item/circuitboard/machine/vr_sleeper
var/you_die_in_the_game_you_die_for_real = FALSE
var/datum/effect_system/spark_spread/sparks
var/mob/living/carbon/human/virtual_reality/vr_human
var/mob/living/vr_mob
var/virtual_mob_type = /mob/living/carbon/human
var/vr_category = "default" //Specific category of spawn points to pick from
var/allow_creating_vr_humans = TRUE //So you can have vr_sleepers that always spawn you as a specific person or 1 life/chance vr games
var/allow_creating_vr_mobs = TRUE //So you can have vr_sleepers that always spawn you as a specific person or 1 life/chance vr games
var/only_current_user_can_interact = FALSE
/obj/machinery/vr_sleeper/Initialize()
@@ -44,7 +43,7 @@
/obj/machinery/vr_sleeper/Destroy()
open_machine()
cleanup_vr_human()
cleanup_vr_mob()
QDEL_NULL(sparks)
return ..()
@@ -58,8 +57,9 @@
/obj/machinery/vr_sleeper/emag_act(mob/user)
. = ..()
if(you_die_in_the_game_you_die_for_real)
if(!(obj_flags & EMAGGED))
return
obj_flags |= EMAGGED
you_die_in_the_game_you_die_for_real = TRUE
sparks.start()
addtimer(CALLBACK(src, .proc/emagNotify), 150)
@@ -69,12 +69,11 @@
icon_state = "[initial(icon_state)][state_open ? "-open" : ""]"
/obj/machinery/vr_sleeper/open_machine()
if(!state_open)
if(vr_human)
vr_human.revert_to_reality(FALSE)
if(occupant)
SStgui.close_user_uis(occupant, src)
..()
if(state_open)
return
if(occupant)
SStgui.close_user_uis(occupant, src)
return ..()
/obj/machinery/vr_sleeper/MouseDrop_T(mob/target, mob/user)
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
@@ -94,22 +93,20 @@
if("vr_connect")
var/mob/living/carbon/human/human_occupant = occupant
if(human_occupant && human_occupant.mind && usr == occupant)
to_chat(occupant, "<span class='warning'>Transferring to virtual reality...</span>")
if(vr_human && vr_human.stat == CONSCIOUS && !vr_human.real_mind)
SStgui.close_user_uis(occupant, src)
human_occupant.audiovisual_redirect = vr_human
vr_human.real_mind = human_occupant.mind
vr_human.ckey = human_occupant.ckey
to_chat(vr_human, "<span class='notice'>Transfer successful! You are now playing as [vr_human] in VR!</span>")
if(vr_mob && (!istype(vr_mob) || !vr_mob.InCritical()) && !vr_mob.GetComponent(/datum/component/virtual_reality))
vr_mob.AddComponent(/datum/component/virtual_reality, human_occupant, src, you_die_in_the_game_you_die_for_real)
to_chat(vr_mob, "<span class='notice'>Transfer successful! You are now playing as [vr_mob] in VR!</span>")
else
if(allow_creating_vr_humans)
if(allow_creating_vr_mobs)
to_chat(occupant, "<span class='warning'>Virtual avatar not found, attempting to create one...</span>")
var/obj/effect/landmark/vr_spawn/V = get_vr_spawnpoint()
var/turf/T = get_turf(V)
if(T)
SStgui.close_user_uis(occupant, src)
build_virtual_human(occupant, T, V.vr_outfit)
to_chat(vr_human, "<span class='notice'>Transfer successful! You are now playing as [vr_human] in VR!</span>")
new_player(occupant, T, V.vr_outfit)
to_chat(vr_mob, "<span class='notice'>Transfer successful! You are now playing as [vr_mob] in VR!</span>")
else
to_chat(occupant, "<span class='warning'>Virtual world misconfigured, aborting transfer</span>")
else
@@ -117,8 +114,8 @@
. = TRUE
if("delete_avatar")
if(!occupant || usr == occupant)
if(vr_human)
cleanup_vr_human()
if(vr_mob)
cleanup_vr_mob()
else
to_chat(usr, "<span class='warning'>The VR Sleeper's safeties prevent you from doing that.</span>")
. = TRUE
@@ -131,19 +128,22 @@
/obj/machinery/vr_sleeper/ui_data(mob/user)
var/list/data = list()
if(vr_human && !QDELETED(vr_human))
if(vr_mob && !QDELETED(vr_mob))
data["can_delete_avatar"] = TRUE
var/status
switch(vr_human.stat)
if(CONSCIOUS)
status = "Conscious"
if(DEAD)
status = "Dead"
if(UNCONSCIOUS)
status = "Unconscious"
if(SOFT_CRIT)
status = "Barely Conscious"
data["vr_avatar"] = list("name" = vr_human.name, "status" = status, "health" = vr_human.health, "maxhealth" = vr_human.maxHealth)
data["vr_avatar"] = list("name" = vr_mob.name)
data["isliving"] = istype(vr_mob)
if(data["isliving"])
var/status
switch(vr_mob.stat)
if(CONSCIOUS)
status = "Conscious"
if(DEAD)
status = "Dead"
if(UNCONSCIOUS)
status = "Unconscious"
if(SOFT_CRIT)
status = "Barely Conscious"
data["vr_avatar"] += list("status" = status, "health" = vr_mob.health, "maxhealth" = vr_mob.maxHealth)
data["toggle_open"] = state_open
data["emagged"] = you_die_in_the_game_you_die_for_real
data["isoccupant"] = (user == occupant)
@@ -157,40 +157,25 @@
for(var/obj/effect/landmark/vr_spawn/V in GLOB.landmarks_list)
GLOB.vr_spawnpoints[V.vr_category] = V
/obj/machinery/vr_sleeper/proc/build_virtual_human(mob/living/carbon/human/H, location, var/datum/outfit/outfit, transfer = TRUE)
if(H)
cleanup_vr_human()
vr_human = new /mob/living/carbon/human/virtual_reality(location)
vr_human.mind_initialize()
vr_human.vr_sleeper = src
vr_human.real_mind = H.mind
H.dna.transfer_identity(vr_human)
vr_human.name = H.name
vr_human.real_name = H.real_name
vr_human.socks = H.socks
vr_human.socks_color = H.socks_color
vr_human.undershirt = H.undershirt
vr_human.shirt_color = H.shirt_color
vr_human.underwear = H.underwear
vr_human.undie_color = H.undie_color
vr_human.updateappearance(TRUE, TRUE, TRUE)
vr_human.give_genitals(TRUE) //CITADEL ADD
if(outfit)
var/datum/outfit/O = new outfit()
O.equip(vr_human)
if(transfer && H.mind)
SStgui.close_user_uis(H, src)
H.audiovisual_redirect = vr_human
vr_human.ckey = H.ckey
/obj/machinery/vr_sleeper/proc/new_player(mob/living/carbon/human/H, location, datum/outfit/outfit, transfer = TRUE)
if(!H)
return
cleanup_vr_mob()
vr_mob = new virtual_mob_type(location)
if(vr_mob.build_virtual_character(H, outfit))
var/mob/living/carbon/human/vr_H = vr_mob
vr_H.updateappearance(TRUE, TRUE, TRUE)
if(!transfer || !H.mind)
return
vr_mob.AddComponent(/datum/component/virtual_reality, H, src, you_die_in_the_game_you_die_for_real)
/obj/machinery/vr_sleeper/proc/cleanup_vr_human()
if(vr_human)
vr_human.vr_sleeper = null // Prevents race condition where a new human could get created out of order and set to null.
QDEL_NULL(vr_human)
/obj/machinery/vr_sleeper/proc/cleanup_vr_mob()
if(vr_mob)
QDEL_NULL(vr_mob)
/obj/machinery/vr_sleeper/proc/emagNotify()
if(vr_human)
vr_human.Dizzy(10)
if(vr_mob)
vr_mob.Dizzy(10)
/obj/effect/landmark/vr_spawn //places you can spawn in VR, auto selected by the vr_sleeper during get_vr_spawnpoint()
var/vr_category = "default" //So we can have specific sleepers, eg: "Basketball VR Sleeper", etc.
@@ -222,6 +207,7 @@
color = "#00FF00"
invisibility = INVISIBILITY_ABSTRACT
var/area/vr_area
var/list/corpse_party
/obj/effect/vr_clean_master/Initialize()
. = ..()
@@ -234,7 +220,8 @@
qdel(casing)
for(var/obj/effect/decal/cleanable/C in vr_area)
qdel(C)
for (var/mob/living/carbon/human/virtual_reality/H in vr_area)
if (H.stat == DEAD && !H.vr_sleeper && !H.real_mind)
qdel(H)
for (var/A in corpse_party)
var/mob/M = A
if(get_area(M) == vr_area && M.stat == DEAD)
qdel(M)
addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES)
+1 -1
View File
@@ -61,7 +61,7 @@
to_chat(body, "Your mob has been taken over by a ghost!")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(body)])")
body.ghostize(0)
body.key = C.key
C.transfer_ckey(body)
new /obj/effect/temp_visual/gravpush(get_turf(body))
/obj/effect/fun_balloon/sentience/emergency_shuttle
+1 -1
View File
@@ -744,7 +744,7 @@
var/mob/chosen = players[1]
if (chosen.client)
chosen.client.prefs.copy_to(spawnedMob)
spawnedMob.key = chosen.key
chosen.transfer_ckey(spawnedMob)
players -= chosen
if (ishuman(spawnedMob) && ispath(humanoutfit, /datum/outfit))
var/mob/living/carbon/human/H = spawnedMob
+1 -1
View File
@@ -306,7 +306,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
var/mob/living/silicon/pai/pai = new(card)
pai.name = input(choice, "Enter your pAI name:", "pAI Name", "Personal AI") as text
pai.real_name = pai.name
pai.key = choice.key
choice.transfer_ckey(pai)
card.setPersonality(pai)
for(var/datum/paiCandidate/candidate in SSpai.candidates)
if(candidate.key == choice.key)
+1 -1
View File
@@ -412,7 +412,7 @@
//Spawn the body
var/mob/living/carbon/human/ERTOperative = new ertemplate.mobtype(spawnloc)
chosen_candidate.client.prefs.copy_to(ERTOperative)
ERTOperative.key = chosen_candidate.key
chosen_candidate.transfer_ckey(ERTOperative)
if(ertemplate.enforce_human || ERTOperative.dna.species.dangerous_existence) // Don't want any exploding plasmemes
ERTOperative.set_species(/datum/species/human)
+3 -3
View File
@@ -384,7 +384,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
//Now to give them their mind back.
G_found.mind.transfer_to(new_xeno) //be careful when doing stuff like this! I've already checked the mind isn't in use
new_xeno.key = G_found.key
G_found.transfer_ckey(new_xeno, FALSE)
to_chat(new_xeno, "You have been fully respawned. Enjoy the game.")
var/msg = "<span class='adminnotice'>[key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno.</span>"
message_admins(msg)
@@ -397,7 +397,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/mob/living/carbon/monkey/new_monkey = new
SSjob.SendToLateJoin(new_monkey)
G_found.mind.transfer_to(new_monkey) //be careful when doing stuff like this! I've already checked the mind isn't in use
new_monkey.key = G_found.key
G_found.transfer_ckey(new_monkey, FALSE)
to_chat(new_monkey, "You have been fully respawned. Enjoy the game.")
var/msg = "<span class='adminnotice'>[key_name_admin(usr)] has respawned [new_monkey.key] as a filthy xeno.</span>"
message_admins(msg)
@@ -437,7 +437,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
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
G_found.transfer_ckey(new_character, FALSE)
/*
The code below functions with the assumption that the mob is already a traitor if they have a special role.
@@ -15,7 +15,7 @@ GLOBAL_LIST_EMPTY(antagonists)
var/antag_memory = ""//These will be removed with antag datum
var/antag_moodlet //typepath of moodlet that the mob will gain with their status
var/can_hijack = HIJACK_NEUTRAL //If these antags are alone on shuttle hijack happens.
//Antag panel properties
var/show_in_antagpanel = TRUE //This will hide adding this antag type in antag panel, use only for internal subtypes that shouldn't be added directly but still show if possessed by mind
var/antagpanel_category = "Uncategorized" //Antagpanel will display these together, REQUIRED
@@ -87,7 +87,7 @@ GLOBAL_LIST_EMPTY(antagonists)
to_chat(owner, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(owner.current)]) to replace a jobbaned player.")
owner.current.ghostize(0)
owner.current.key = C.key
C.transfer_ckey(owner.current, FALSE)
/datum/antagonist/proc/on_removal()
remove_innate_effects()
@@ -52,5 +52,5 @@
/datum/outfit/abductor/scientist/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()
if(!visualsOnly)
var/obj/item/implant/abductor/beamplant = new /obj/item/implant/abductor(H)
var/obj/item/implant/abductor/beamplant = new
beamplant.implant(H)
+1 -1
View File
@@ -172,7 +172,7 @@
blobber.adjustHealth(blobber.maxHealth * 0.5)
blob_mobs += blobber
var/mob/dead/observer/C = pick(candidates)
blobber.key = C.key
C.transfer_ckey(blobber)
SEND_SOUND(blobber, sound('sound/effects/blobattack.ogg'))
SEND_SOUND(blobber, sound('sound/effects/attackblob.ogg'))
to_chat(blobber, "<b>You are a blobbernaut!</b>")
@@ -349,7 +349,7 @@
to_chat(L, "<span class='userdanger'>Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form!</span>")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(L)]) to replace an inactive clock cultist.")
L.ghostize(0)
L.key = C.key
C.transfer_ckey(L, FALSE)
var/obj/effect/temp_visual/ratvar/sigil/vitality/V = new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src))
animate(V, alpha = 0, transform = matrix()*2, time = 8)
playsound(L, 'sound/magic/staff_healing.ogg', 50, 1)
@@ -55,7 +55,7 @@
pre_spawn()
visible_message(creation_message)
var/mob/living/construct = new construct_type(get_turf(src))
construct.key = user.key
user.transfer_ckey(construct, FALSE)
post_spawn(construct)
qdel(user)
qdel(src)
@@ -216,6 +216,9 @@
if(is_reebe(invoker.z))
to_chat(invoker, "<span class='danger'>You're already at Reebe.</span>")
return
if(!isturf(invoker.loc))
to_chat(invoker, "<span class='danger'>You must be visible to return!</span>")
return
return TRUE
/datum/clockwork_scripture/abscond/recital()
@@ -64,7 +64,7 @@
message_admins("<span class='danger'>Admin [key_name_admin(user)] directly became the Eminence of the cult!</span>")
log_admin("Admin [key_name(user)] made themselves the Eminence.")
var/mob/camera/eminence/eminence = new(get_turf(src))
eminence.key = user.key
user.transfer_ckey(eminence, FALSE)
hierophant_message("<span class='bold large_brass'>Ratvar has directly assigned the Eminence!</span>")
for(var/mob/M in servants_and_ghosts())
M.playsound_local(M, 'sound/machines/clockcult/eminence_selected.ogg', 50, FALSE)
@@ -138,7 +138,7 @@
playsound(src, 'sound/machines/clockcult/ark_damage.ogg', 50, FALSE)
var/mob/camera/eminence/eminence = new(get_turf(src))
eminence_nominee = pick(candidates)
eminence.key = eminence_nominee.key
eminence_nominee.transfer_ckey(eminence)
hierophant_message("<span class='bold large_brass'>A ghost has ascended into the Eminence!</span>")
for(var/mob/M in servants_and_ghosts())
M.playsound_local(M, 'sound/machines/clockcult/eminence_selected.ogg', 50, FALSE)
@@ -45,7 +45,7 @@
return FALSE
var/mob/living/simple_animal/drone/cogscarab/ratvar/R = new/mob/living/simple_animal/drone/cogscarab/ratvar(get_turf(src))
R.visible_message("<span class='heavy_brass'>[R] forms, and its eyes blink open, glowing bright red!</span>")
R.key = O.key
O.transfer_ckey(R, FALSE)
/obj/structure/destructible/clockwork/massive/ratvar/Bump(atom/A)
var/turf/T = get_turf(A)
+2 -2
View File
@@ -575,7 +575,7 @@ structure_check() searches for nearby cultist structures required for the invoca
to_chat(mob_to_revive.mind, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form.")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(mob_to_revive)]) to replace an AFK player.")
mob_to_revive.ghostize(0)
mob_to_revive.key = C.key
C.transfer_ckey(mob_to_revive, FALSE)
else
fail_invoke()
return
@@ -870,7 +870,7 @@ structure_check() searches for nearby cultist structures required for the invoca
visible_message("<span class='warning'>A cloud of red mist forms above [src], and from within steps... a [new_human.gender == FEMALE ? "wo":""]man.</span>")
to_chat(user, "<span class='cultitalic'>Your blood begins flowing into [src]. You must remain in place and conscious to maintain the forms of those summoned. This will hurt you slowly but surely...</span>")
var/obj/structure/emergency_shield/invoker/N = new(T)
new_human.key = ghost_to_spawn.key
ghost_to_spawn.transfer_ckey(new_human, FALSE)
SSticker.mode.add_cultist(new_human.mind, 0)
to_chat(new_human, "<span class='cultitalic'><b>You are a servant of the Geometer. You have been made semi-corporeal by the cult of Nar'Sie, and you are to serve them at all costs.</b></span>")
@@ -146,7 +146,7 @@
/mob/living/carbon/true_devil/attack_ghost(mob/dead/observer/user as mob)
if(ascended || user.mind.soulOwner == src.mind)
var/mob/living/simple_animal/imp/S = new(get_turf(loc))
S.key = user.key
user.transfer_ckey(S, FALSE)
S.mind.assigned_role = "Imp"
S.mind.special_role = "Imp"
var/datum/objective/newobjective = new
@@ -18,7 +18,7 @@
var/mob/dead/observer/selected = pick_n_take(candidates)
var/mob/camera/disease/virus = new /mob/camera/disease(SSmapping.get_station_center())
virus.key = selected.key
selected.transfer_ckey(virus, FALSE)
INVOKE_ASYNC(virus, /mob/camera/disease/proc/pick_name)
message_admins("[ADMIN_LOOKUPFLW(virus)] has been made into a sentient disease by an event.")
log_game("[key_name(virus)] was spawned as a sentient disease by an event.")
@@ -1,7 +1,8 @@
#define CHALLENGE_TELECRYSTALS 280
#define PLAYER_SCALING 1.5
#define CHALLENGE_TIME_LIMIT 3000
#define CHALLENGE_MIN_PLAYERS 50
#define CHALLENGE_PLAYERS_TARGET 50 //target players population. anything below is a malus to the challenge tc bonus.
#define TELECRYSTALS_MALUS_SCALING 1 //the higher the value, the bigger the malus.
#define CHALLENGE_SHUTTLE_DELAY 15000 // 25 minutes, so the ops have at least 5 minutes before the shuttle is callable.
GLOBAL_LIST_EMPTY(jam_on_wardec)
@@ -62,12 +63,15 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
for(var/obj/machinery/computer/camera_advanced/shuttle_docker/D in GLOB.jam_on_wardec)
D.jammed = TRUE
GLOB.war_declared = TRUE
var/list/nukeops = get_antag_minds(/datum/antagonist/nukeop)
var/actual_players = GLOB.joined_player_list.len - nukeops.len
var/tc_malus = 0
if(actual_players < CHALLENGE_PLAYERS_TARGET)
tc_malus = FLOOR(((CHALLENGE_TELECRYSTALS / CHALLENGE_PLAYERS_TARGET) * (CHALLENGE_PLAYERS_TARGET - actual_players)) * TELECRYSTALS_MALUS_SCALING, 1)
new uplink_type(get_turf(user), user.key, CHALLENGE_TELECRYSTALS + CEILING(PLAYER_SCALING * actual_players, 1))
new uplink_type(get_turf(user), user.key, CHALLENGE_TELECRYSTALS - tc_malus + CEILING(PLAYER_SCALING * actual_players, 1))
CONFIG_SET(number/shuttle_refuel_delay, max(CONFIG_GET(number/shuttle_refuel_delay), CHALLENGE_SHUTTLE_DELAY))
SSblackbox.record_feedback("amount", "nuclear_challenge_mode", 1)
@@ -79,11 +83,6 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
to_chat(user, "You are already in the process of declaring war! Make your mind up.")
return FALSE
var/list/nukeops = get_antag_minds(/datum/antagonist/nukeop)
var/actual_players = GLOB.joined_player_list.len - nukeops.len
if(actual_players < CHALLENGE_MIN_PLAYERS)
to_chat(user, "The enemy crew is too small to be worth declaring war on.")
return FALSE
if(!user.onSyndieBase())
to_chat(user, "You have to be at your base to use this.")
return FALSE
@@ -102,5 +101,6 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
#undef CHALLENGE_TELECRYSTALS
#undef CHALLENGE_TIME_LIMIT
#undef CHALLENGE_MIN_PLAYERS
#undef CHALLENGE_PLAYERS_TARGET
#undef TELECRYSTALS_MALUS_SCALING
#undef CHALLENGE_SHUTTLE_DELAY
@@ -107,9 +107,9 @@
/datum/antagonist/overthrow/proc/equip_overthrow()
if(!owner || !owner.current || !ishuman(owner.current)) // only equip existing human overthrow members. This excludes the AI, in particular.
return
var/obj/item/implant/storage/S = locate(/obj/item/implant/storage) in owner.current
var/obj/item/implant/storage/S = locate(/obj/item/implant/storage) in owner.current.implants
if(!S)
S = new(owner.current)
S = new
S.implant(owner.current)
var/I = pick(possible_useful_items)
if(ispath(I)) // in case some admin decides to fuck the list up for fun
@@ -377,14 +377,15 @@
/obj/item/ectoplasm/revenant/proc/reform()
if(QDELETED(src) || QDELETED(revenant) || inert)
return
var/key_of_revenant
var/key_of_revenant = FALSE
message_admins("Revenant ectoplasm was left undestroyed for 1 minute and is reforming into a new revenant.")
forceMove(drop_location()) //In case it's in a backpack or someone's hand
revenant.forceMove(loc)
if(old_key)
for(var/mob/M in GLOB.dead_mob_list)
if(M.client && M.client.key == old_key) //Only recreates the mob if the mob the client is in is dead
key_of_revenant = old_key
M.transfer_ckey(revenant.key, FALSE)
key_of_revenant = TRUE
break
if(!key_of_revenant)
message_admins("The new revenant's old client either could not be found or is in a new, living mob - grabbing a random candidate instead...")
@@ -396,22 +397,21 @@
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
return
var/mob/dead/observer/C = pick(candidates)
key_of_revenant = C.key
if(!key_of_revenant)
C.transfer_ckey(revenant.key, FALSE)
if(!revenant.key)
qdel(revenant)
message_admins("No ckey was found for the new revenant. Oh well!")
inert = TRUE
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
return
message_admins("[key_of_revenant] has been [old_key == key_of_revenant ? "re":""]made into a revenant by reforming ectoplasm.")
log_game("[key_of_revenant] was [old_key == key_of_revenant ? "re":""]made as a revenant by reforming ectoplasm.")
message_admins("[key_of_revenant] has been [old_key == revenant.key ? "re":""]made into a revenant by reforming ectoplasm.")
log_game("[key_of_revenant] was [old_key == revenant.key ? "re":""]made as a revenant by reforming ectoplasm.")
visible_message("<span class='revenboldnotice'>[src] suddenly rises into the air before fading away.</span>")
revenant.essence = essence
revenant.essence_regen_cap = essence
revenant.death_reset()
revenant.key = key_of_revenant
revenant = null
qdel(src)
@@ -52,7 +52,7 @@
return MAP_ERROR
var/mob/living/simple_animal/revenant/revvie = new(pick(spawn_locs))
revvie.key = selected.key
selected.transfer_ckey(revvie, FALSE)
message_admins("[ADMIN_LOOKUPFLW(revvie)] has been made into a revenant by an event.")
log_game("[key_name(revvie)] was spawned as a revenant by an event.")
spawned_mobs += revvie
@@ -218,7 +218,7 @@
newstruct.master = stoner
var/datum/action/innate/seek_master/SM = new()
SM.Grant(newstruct)
newstruct.key = target.key
target.transfer_ckey(newstruct)
var/obj/screen/alert/bloodsense/BS
if(newstruct.mind && ((stoner && iscultist(stoner)) || cultoverride) && SSticker && SSticker.mode)
SSticker.mode.add_cultist(newstruct.mind, 0)
@@ -243,7 +243,7 @@
S.canmove = FALSE//Can't move out of the soul stone
S.name = "Shade of [T.real_name]"
S.real_name = "Shade of [T.real_name]"
S.key = T.key
T.transfer_ckey(S)
S.language_holder = U.language_holder.copy(S)
if(U)
S.faction |= "[REF(U)]" //Add the master as a faction, allowing inter-mob cooperation
+1 -1
View File
@@ -245,7 +245,7 @@
if(!istype(M))
return
var/obj/item/implant/exile/Implant = new/obj/item/implant/exile(M)
var/obj/item/implant/exile/Implant = new
Implant.implant(M)
/datum/antagonist/wizard/academy/create_objectives()
@@ -133,7 +133,7 @@
var/mob/dead/observer/C = pick(candidates)
message_admins("[ADMIN_LOOKUPFLW(C)] was spawned as Wizard Academy Defender")
current_wizard.ghostize() // on the off chance braindead defender gets back in
current_wizard.key = C.key
C.transfer_ckey(current_wizard, FALSE)
/obj/structure/academy_wizard_spawner/proc/summon_wizard()
var/turf/T = src.loc
@@ -210,8 +210,6 @@
if(4)
//Destroy Equipment
for (var/obj/item/I in user)
if (istype(I, /obj/item/implant))
continue
qdel(I)
if(5)
//Monkeying
@@ -274,7 +272,7 @@
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
message_admins("[ADMIN_LOOKUPFLW(C)] was spawned as Dice Servant")
H.key = C.key
C.transfer_ckey(H, FALSE)
var/obj/effect/proc_holder/spell/targeted/summonmob/S = new
S.target_mob = H
+7
View File
@@ -2246,6 +2246,13 @@
contains = list(/mob/living/simple_animal/hostile/retaliate/goat)
crate_name = "goat crate"
/datum/supply_pack/critter/goose
name = "Goose Crate"
desc = "Angry and violent birds. Evil, evil creatures."
cost = 2500
contains = list(/mob/living/simple_animal/hostile/retaliate/goose)
crate_name = "goose crate"
/datum/supply_pack/critter/monkey
name = "Monkey Cube Crate"
desc = "Stop monkeying around! Contains seven monkey cubes. Just add water!"
+42
View File
@@ -41,6 +41,13 @@
var/dynamic_hair_suffix = ""//head > mask for head hair
var/dynamic_fhair_suffix = ""//mask > head for facial hair
//basically a restriction list.
var/list/species_restricted = null
//Basically syntax is species_restricted = list("Species Name","Species Name")
//Add a "exclude" string to do the opposite, making it only only species listed that can't wear it.
//You append this to clothing objects.
/obj/item/clothing/Initialize()
. = ..()
if(CHECK_BITFIELD(clothing_flags, VOICEBOX_TOGGLABLE))
@@ -338,3 +345,38 @@ BLIND // can't see anything
deconstruct(FALSE)
else
..()
//Species-restricted clothing check. - Thanks Oraclestation, BS13, /vg/station etc.
/obj/item/clothing/mob_can_equip(mob/M, slot, disable_warning = TRUE)
//if we can't equip the item anyway, don't bother with species_restricted (also cuts down on spam)
if(!..())
return FALSE
// Skip species restriction checks on non-equipment slots
if(slot in list(SLOT_IN_BACKPACK, SLOT_L_STORE, SLOT_R_STORE))
return TRUE
if(species_restricted && ishuman(M))
var/wearable = null
var/exclusive = null
var/mob/living/carbon/human/H = M
if("exclude" in species_restricted) //TURNS IT INTO A BLACKLIST - AKA ALL MINUS SPECIES LISTED.
exclusive = TRUE
if(H.dna.species)
if(exclusive)
if(!(H.dna.species.name in species_restricted))
wearable = TRUE
else
if(H.dna.species.name in species_restricted)
wearable = TRUE
if(!wearable)
to_chat(M, "<span class='warning'>Your species cannot wear [src].</span>")
return FALSE
return TRUE
+27
View File
@@ -281,6 +281,33 @@
..()
user.cure_blind("blindfold_[REF(src)]")
/obj/item/clothing/glasses/sunglasses/blindfold/white
name = "blind personnel blindfold"
desc = "Indicates that the wearer suffers from blindness."
icon_state = "blindfoldwhite"
item_state = "blindfoldwhite"
var/colored_before = FALSE
/obj/item/clothing/glasses/sunglasses/blindfold/white/equipped(mob/living/carbon/human/user, slot)
if(ishuman(user) && slot == SLOT_GLASSES)
update_icon(user)
user.update_inv_glasses() //Color might have been changed by update_icon.
..()
/obj/item/clothing/glasses/sunglasses/blindfold/white/update_icon(mob/living/carbon/human/user)
if(ishuman(user) && !colored_before)
add_atom_colour("#[user.eye_color]", FIXED_COLOUR_PRIORITY)
colored_before = TRUE
/obj/item/clothing/glasses/sunglasses/blindfold/white/worn_overlays(isinhands = FALSE, file2use)
. = list()
if(!isinhands && ishuman(loc) && !colored_before)
var/mob/living/carbon/human/H = loc
var/mutable_appearance/M = mutable_appearance('icons/mob/eyes.dmi', "blindfoldwhite")
M.appearance_flags |= RESET_COLOR
M.color = "#[H.eye_color]"
. += M
/obj/item/clothing/glasses/sunglasses/big
desc = "Strangely ancient technology used to help provide rudimentary eye cover. Larger than average enhanced shielding blocks flashes."
icon_state = "bigsunglasses"
+1 -1
View File
@@ -10,7 +10,7 @@
if(visualsOnly)
return
var/obj/item/implant/mindshield/L = new/obj/item/implant/mindshield(H)
var/obj/item/implant/mindshield/L = new
L.implant(H, null, 1)
var/obj/item/radio/R = H.ears
+2 -2
View File
@@ -399,7 +399,7 @@
R.set_frequency(FREQ_CENTCOM)
R.freqlock = TRUE
var/obj/item/implant/mindshield/L = new/obj/item/implant/mindshield(H)//Here you go Deuryn
var/obj/item/implant/mindshield/L = new //Here you go Deuryn
L.implant(H, null, 1)
@@ -426,7 +426,7 @@
/datum/outfit/debug //Debug objs plus hardsuit
name = "Debug outfit"
uniform = /obj/item/clothing/under/patriotsuit
uniform = /obj/item/clothing/under/patriotsuit
suit = /obj/item/clothing/suit/space/hardsuit/syndi/elite
shoes = /obj/item/clothing/shoes/magboots/advance
suit_store = /obj/item/tank/internals/oxygen
+2 -2
View File
@@ -29,9 +29,9 @@
. = ..()
var/obj/item/uplink/U = new /obj/item/uplink/nuclear_restricted(H, H.key, 80)
H.equip_to_slot_or_del(U, SLOT_IN_BACKPACK)
var/obj/item/implant/weapons_auth/W = new/obj/item/implant/weapons_auth(H)
var/obj/item/implant/weapons_auth/W = new
W.implant(H)
var/obj/item/implant/explosive/E = new/obj/item/implant/explosive(H)
var/obj/item/implant/explosive/E = new
E.implant(H)
H.faction |= ROLE_SYNDICATE
H.update_icons()
@@ -599,6 +599,7 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95)
slowdown = 1
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
mutantrace_variation = NO_MUTANTRACE_VARIATION
can_adjust = FALSE
strip_delay = 80
var/next_extinguish = 0
+1 -1
View File
@@ -77,7 +77,7 @@
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
santa = new /mob/living/carbon/human(pick(GLOB.blobstart))
santa.key = C.key
C.transfer_ckey(santa, FALSE)
santa.equipOutfit(/datum/outfit/santa)
santa.update_icons()
+1 -1
View File
@@ -48,7 +48,7 @@
spawned_animals++
SA.key = SG.key
SG.transfer_ckey(SA, FALSE)
SA.grant_all_languages(TRUE)
+1 -1
View File
@@ -23,7 +23,7 @@
I.name = I.dna.real_name
I.updateappearance(mutcolor_update=1)
I.domutcheck()
I.key = C.key
C.transfer_ckey(I, FALSE)
var/datum/antagonist/wizard/master = M.has_antag_datum(/datum/antagonist/wizard)
if(!master.wiz_team)
master.create_wiz_team()
+1 -1
View File
@@ -162,7 +162,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
var/list/row = src.connectionHistory[i]
if (!row || row.len < 3 || (!row["ckey"] || !row["compid"] || !row["ip"])) //Passed malformed history object
return
if (world.IsBanned(row["ckey"], row["compid"], row["ip"], real_bans_only=TRUE))
if (world.IsBanned(row["ckey"], row["ip"], row["compid"], real_bans_only=TRUE))
found = row
break
@@ -1,50 +1,51 @@
/*********************Mining Hammer****************/
/obj/item/twohanded/required/kinetic_crusher
/obj/item/twohanded/kinetic_crusher
icon = 'icons/obj/mining.dmi'
icon_state = "mining_hammer1"
item_state = "mining_hammer1"
icon_state = "crusher"
item_state = "crusher0"
lefthand_file = 'icons/mob/inhands/weapons/hammers_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/hammers_righthand.dmi'
name = "proto-kinetic crusher"
desc = "An early design of the proto-kinetic accelerator, it is little more than an combination of various mining tools cobbled together, forming a high-tech club. \
While it is an effective mining tool, it did little to aid any but the most skilled and/or suicidal miners against local fauna."
force = 20 //As much as a bone spear, but this is significantly more annoying to carry around due to requiring the use of both hands at all times
force = 0 //You can't hit stuff unless wielded
w_class = WEIGHT_CLASS_BULKY
slot_flags = ITEM_SLOT_BACK
force_unwielded = 20 //It's never not wielded so these are the same
force_unwielded = 0
force_wielded = 20
throwforce = 5
throw_speed = 4
light_range = 7
light_power = 2
armour_penetration = 10
materials = list(MAT_METAL=1150, MAT_GLASS=2075)
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("smashed", "crushed", "cleaved", "chopped", "pulped")
sharpness = IS_SHARP
actions_types = list(/datum/action/item_action/toggle_light)
var/list/trophies = list()
var/charged = TRUE
var/charge_time = 15
var/detonation_damage = 50
var/backstab_bonus = 30
var/light_on = FALSE
var/brightness_on = 7
/obj/item/twohanded/required/kinetic_crusher/Initialize()
/obj/item/twohanded/kinetic_crusher/Initialize()
. = ..()
AddComponent(/datum/component/butchering, 60, 110) //technically it's huge and bulky, but this provides an incentive to use it
/obj/item/twohanded/required/kinetic_crusher/Destroy()
/obj/item/twohanded/kinetic_crusher/Destroy()
QDEL_LIST(trophies)
return ..()
/obj/item/twohanded/required/kinetic_crusher/examine(mob/living/user)
/obj/item/twohanded/kinetic_crusher/examine(mob/living/user)
..()
to_chat(user, "<span class='notice'>Mark a large creature with the destabilizing force, then hit them in melee to do <b>[force + detonation_damage]</b> damage.</span>")
to_chat(user, "<span class='notice'>Does <b>[force + detonation_damage + backstab_bonus]</b> damage if the target is backstabbed, instead of <b>[force + detonation_damage]</b>.</span>")
to_chat(user, "<span class='notice'>Mark a large creature with the destabilizing force, then hit them in melee to do <b>[force_wielded + detonation_damage]</b> damage.</span>")
to_chat(user, "<span class='notice'>Does <b>[force_wielded + detonation_damage + backstab_bonus]</b> damage if the target is backstabbed, instead of <b>[force_wielded + detonation_damage]</b>.</span>")
for(var/t in trophies)
var/obj/item/crusher_trophy/T = t
to_chat(user, "<span class='notice'>It has \a [T] attached, which causes [T.effect_desc()].</span>")
/obj/item/twohanded/required/kinetic_crusher/attackby(obj/item/I, mob/living/user)
/obj/item/twohanded/kinetic_crusher/attackby(obj/item/I, mob/living/user)
if(istype(I, /obj/item/crowbar))
if(LAZYLEN(trophies))
to_chat(user, "<span class='notice'>You remove [src]'s trophies.</span>")
@@ -60,7 +61,11 @@
else
return ..()
/obj/item/twohanded/required/kinetic_crusher/attack(mob/living/target, mob/living/carbon/user)
/obj/item/twohanded/kinetic_crusher/attack(mob/living/target, mob/living/carbon/user)
if(!wielded)
to_chat(user, "<span class='warning'>[src] is too heavy to use with one hand. You fumble and drop everything.")
user.drop_all_held_items()
return
var/datum/status_effect/crusher_damage/C = target.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
var/target_health = target.health
..()
@@ -71,11 +76,13 @@
if(!QDELETED(C) && !QDELETED(target))
C.total_damage += target_health - target.health //we did some damage, but let's not assume how much we did
/obj/item/twohanded/required/kinetic_crusher/afterattack(atom/target, mob/living/user, proximity_flag, clickparams)
/obj/item/twohanded/kinetic_crusher/afterattack(atom/target, mob/living/user, proximity_flag, clickparams)
. = ..()
if(istype(target, /obj/item/crusher_trophy))
var/obj/item/crusher_trophy/T = target
T.add_to(src, user)
if(!wielded)
return
if(!proximity_flag && charged)//Mark a target, or mine a tile.
var/turf/proj_turf = user.loc
if(!isturf(proj_turf))
@@ -90,7 +97,7 @@
playsound(user, 'sound/weapons/plasma_cutter.ogg', 100, 1)
D.fire()
charged = FALSE
icon_state = "mining_hammer1_uncharged"
update_icon()
addtimer(CALLBACK(src, .proc/Recharge), charge_time)
return
if(proximity_flag && isliving(target))
@@ -122,12 +129,37 @@
if(user && lavaland_equipment_pressure_check(get_turf(user))) //CIT CHANGE - makes sure below only happens in low pressure environments
user.adjustStaminaLoss(-30)//CIT CHANGE - makes crushers heal stamina
/obj/item/twohanded/required/kinetic_crusher/proc/Recharge()
/obj/item/twohanded/kinetic_crusher/proc/Recharge()
if(!charged)
charged = TRUE
icon_state = "mining_hammer1"
update_icon()
playsound(src.loc, 'sound/weapons/kenetic_reload.ogg', 60, 1)
/obj/item/twohanded/kinetic_crusher/ui_action_click(mob/user, actiontype)
light_on = !light_on
playsound(user, 'sound/weapons/empty.ogg', 100, TRUE)
update_brightness(user)
update_icon()
/obj/item/twohanded/kinetic_crusher/proc/update_brightness(mob/user = null)
if(light_on)
set_light(brightness_on)
else
set_light(0)
/obj/item/twohanded/kinetic_crusher/update_icon()
..()
cut_overlays()
if(!charged)
add_overlay("[icon_state]_uncharged")
if(light_on)
add_overlay("[icon_state]_lit")
spawn(1)
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
item_state = "crusher[wielded]"
//destablizing force
/obj/item/projectile/destabilizer
name = "destabilizing force"
@@ -138,7 +170,7 @@
flag = "bomb"
range = 6
log_override = TRUE
var/obj/item/twohanded/required/kinetic_crusher/hammer_synced
var/obj/item/twohanded/kinetic_crusher/hammer_synced
/obj/item/projectile/destabilizer/Destroy()
hammer_synced = null
@@ -177,12 +209,12 @@
return "errors"
/obj/item/crusher_trophy/attackby(obj/item/A, mob/living/user)
if(istype(A, /obj/item/twohanded/required/kinetic_crusher))
if(istype(A, /obj/item/twohanded/kinetic_crusher))
add_to(A, user)
else
..()
/obj/item/crusher_trophy/proc/add_to(obj/item/twohanded/required/kinetic_crusher/H, mob/living/user)
/obj/item/crusher_trophy/proc/add_to(obj/item/twohanded/kinetic_crusher/H, mob/living/user)
for(var/t in H.trophies)
var/obj/item/crusher_trophy/T = t
if(istype(T, denied_type) || istype(src, T.denied_type))
@@ -194,7 +226,7 @@
to_chat(user, "<span class='notice'>You attach [src] to [H].</span>")
return TRUE
/obj/item/crusher_trophy/proc/remove_from(obj/item/twohanded/required/kinetic_crusher/H, mob/living/user)
/obj/item/crusher_trophy/proc/remove_from(obj/item/twohanded/kinetic_crusher/H, mob/living/user)
forceMove(get_turf(H))
H.trophies -= src
return TRUE
@@ -281,12 +313,12 @@
/obj/item/crusher_trophy/legion_skull/effect_desc()
return "a kinetic crusher to recharge <b>[bonus_value*0.1]</b> second\s faster"
/obj/item/crusher_trophy/legion_skull/add_to(obj/item/twohanded/required/kinetic_crusher/H, mob/living/user)
/obj/item/crusher_trophy/legion_skull/add_to(obj/item/twohanded/kinetic_crusher/H, mob/living/user)
. = ..()
if(.)
H.charge_time -= bonus_value
/obj/item/crusher_trophy/legion_skull/remove_from(obj/item/twohanded/required/kinetic_crusher/H, mob/living/user)
/obj/item/crusher_trophy/legion_skull/remove_from(obj/item/twohanded/kinetic_crusher/H, mob/living/user)
. = ..()
if(.)
H.charge_time += bonus_value
@@ -339,7 +371,7 @@
/obj/item/crusher_trophy/demon_claws/effect_desc()
return "melee hits to do <b>[bonus_value * 0.2]</b> more damage and heal you for <b>[bonus_value * 0.1]</b>, with <b>5X</b> effect on mark detonation"
/obj/item/crusher_trophy/demon_claws/add_to(obj/item/twohanded/required/kinetic_crusher/H, mob/living/user)
/obj/item/crusher_trophy/demon_claws/add_to(obj/item/twohanded/kinetic_crusher/H, mob/living/user)
. = ..()
if(.)
H.force += bonus_value * 0.2
@@ -347,7 +379,7 @@
H.force_wielded += bonus_value * 0.2
H.detonation_damage += bonus_value * 0.8
/obj/item/crusher_trophy/demon_claws/remove_from(obj/item/twohanded/required/kinetic_crusher/H, mob/living/user)
/obj/item/crusher_trophy/demon_claws/remove_from(obj/item/twohanded/kinetic_crusher/H, mob/living/user)
. = ..()
if(.)
H.force -= bonus_value * 0.2
+2 -2
View File
@@ -30,7 +30,7 @@
new /datum/data/mining_equipment("500 Point Transfer Card", /obj/item/card/mining_point_card/mp500, 500),
new /datum/data/mining_equipment("Tracking Implant Kit", /obj/item/storage/box/minertracker, 600),
new /datum/data/mining_equipment("Jaunter", /obj/item/wormhole_jaunter, 750),
new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/twohanded/required/kinetic_crusher, 750),
new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/twohanded/kinetic_crusher, 750),
new /datum/data/mining_equipment("Kinetic Accelerator", /obj/item/gun/energy/kinetic_accelerator, 750),
new /datum/data/mining_equipment("Survival Medipen", /obj/item/reagent_containers/hypospray/medipen/survival, 750),
new /datum/data/mining_equipment("Brute First-Aid Kit", /obj/item/storage/firstaid/brute, 800),
@@ -172,7 +172,7 @@
new /obj/item/stack/marker_beacon/thirty(drop_location)
if("Crusher Kit")
new /obj/item/extinguisher/mini(drop_location)
new /obj/item/twohanded/required/kinetic_crusher(drop_location)
new /obj/item/twohanded/kinetic_crusher(drop_location)
if("Mining Conscription Kit")
new /obj/item/storage/backpack/duffelbag/mining_conscript(drop_location)
+1 -1
View File
@@ -49,7 +49,7 @@
toggle_mode_action.Grant(src)
var/datum/action/innate/minedrone/dump_ore/dump_ore_action = new()
dump_ore_action.Grant(src)
var/obj/item/implant/radio/mining/imp = new(src)
var/obj/item/implant/radio/mining/imp = new
imp.implant(src)
access_card = new /obj/item/card/id(src)
File diff suppressed because it is too large Load Diff
@@ -558,7 +558,7 @@
/datum/sprite_accessory/mam_tails_animated/horse
name = "Horse"
icon_state = "Horse"
icon_state = "horse"
color_src = HAIR
/datum/sprite_accessory/mam_tails/husky
+18 -12
View File
@@ -260,16 +260,16 @@ Transfer_mind is there to check if mob is being deleted/not going to have a body
Works together with spawning an observer, noted above.
*/
/mob/proc/ghostize(can_reenter_corpse = 1)
if(key)
if(!cmptext(copytext(key,1,2),"@")) // Skip aghosts.
stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now
var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc.
SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
ghost.can_reenter_corpse = can_reenter_corpse
ghost.can_reenter_round = (can_reenter_corpse && !suiciding)
ghost.key = key
return ghost
/mob/proc/ghostize(can_reenter_corpse = TRUE, special = FALSE)
if(!key || cmptext(copytext(key,1,2),"@") || (!special && SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special) & COMPONENT_BLOCK_GHOSTING))
return //mob has no key, is an aghost or some component hijacked.
stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now
var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc.
SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
ghost.can_reenter_corpse = can_reenter_corpse
ghost.can_reenter_round = (can_reenter_corpse && !suiciding)
transfer_ckey(ghost, FALSE)
return ghost
/*
This is the proc mobs get to turn into a ghost. Forked from ghostize due to compatibility issues.
@@ -280,6 +280,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "Ghost"
set desc = "Relinquish your life and enter the land of the dead."
if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, (stat == DEAD) ? TRUE : FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING)
return
// CITADEL EDIT
if(istype(loc, /obj/machinery/cryopod))
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
@@ -306,6 +309,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "Ghost"
set desc = "Relinquish your life and enter the land of the dead."
if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING)
return
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost")
return
@@ -348,7 +354,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
client.change_view(CONFIG_GET(string/default_view))
SStgui.on_transfer(src, mind.current) // Transfer NanoUIs.
mind.current.key = key
transfer_ckey(mind.current, FALSE)
return 1
/mob/dead/observer/proc/notify_cloning(var/message, var/sound, var/atom/source, flashwindow = TRUE)
@@ -628,7 +634,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
to_chat(src, "<span class='warning'>Someone has taken this body while you were choosing!</span>")
return 0
target.key = key
transfer_ckey(target, FALSE)
target.faction = list("neutral")
return 1
+1 -1
View File
@@ -158,7 +158,7 @@
//Returns if a certain item can be equipped to a certain slot.
// Currently invalid for two-handed items - call obj/item/mob_can_equip() instead.
/mob/proc/can_equip(obj/item/I, slot, disable_warning = 0)
/mob/proc/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
return FALSE
/mob/proc/can_put_in_hand(I, hand_index)
+1 -1
View File
@@ -42,7 +42,7 @@
if(brainmob.mind)
brainmob.mind.transfer_to(C)
else
C.key = brainmob.key
brainmob.transfer_ckey(C)
QDEL_NULL(brainmob)
@@ -87,7 +87,7 @@
var/atom/xeno_loc = get_turf(owner)
var/mob/living/carbon/alien/larva/new_xeno = new(xeno_loc)
new_xeno.key = ghost.key
ghost.transfer_ckey(new_xeno, FALSE)
SEND_SOUND(new_xeno, sound('sound/voice/hiss5.ogg',0,0,0,100)) //To get the player's attention
new_xeno.canmove = 0 //so we don't move during the bursting animation
new_xeno.notransform = 1
@@ -865,7 +865,7 @@
piggyback(target)
return
//If you dragged them to you and you're aggressively grabbing try to fireman carry them
else if(user != target && can_be_firemanned(target))
else if(user != target)
fireman_carry(target)
return
. = ..()
+62 -13
View File
@@ -9,9 +9,29 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/name // this is the fluff name. these will be left generic (such as 'Lizardperson' for the lizard race) so servers can change them to whatever
var/default_color = "#FFF" // if alien colors are disabled, this is the color that will be used by that race
var/sexes = 1 // whether or not the race has sexual characteristics. at the moment this is only 0 for skeletons and shadows
var/sexes = 1 // whether or not the race has sexual characteristics. at the moment this is only 0 for skeletons and shadows
var/list/offset_features = list(OFFSET_UNIFORM = list(0,0), OFFSET_ID = list(0,0), OFFSET_GLOVES = list(0,0), OFFSET_GLASSES = list(0,0), OFFSET_EARS = list(0,0), OFFSET_SHOES = list(0,0), OFFSET_S_STORE = list(0,0), OFFSET_FACEMASK = list(0,0), OFFSET_HEAD = list(0,0), OFFSET_FACE = list(0,0), OFFSET_BELT = list(0,0), OFFSET_BACK = list(0,0), OFFSET_SUIT = list(0,0), OFFSET_NECK = list(0,0))
//Species Icon Drawing Offsets - Pixel X, Pixel Y, Aka X = Horizontal and Y = Vertical, from bottom left corner
var/list/offset_features = list(
OFFSET_UNIFORM = list(0,0),
OFFSET_ID = list(0,0),
OFFSET_GLOVES = list(0,0),
OFFSET_GLASSES = list(0,0),
OFFSET_EARS = list(0,0),
OFFSET_SHOES = list(0,0),
OFFSET_S_STORE = list(0,0),
OFFSET_FACEMASK = list(0,0),
OFFSET_HEAD = list(0,0),
OFFSET_EYES = list(0,0),
OFFSET_LIPS = list(0,0),
OFFSET_BELT = list(0,0),
OFFSET_BACK = list(0,0),
OFFSET_HAIR = list(0,0),
OFFSET_FHAIR = list(0,0),
OFFSET_SUIT = list(0,0),
OFFSET_NECK = list(0,0),
OFFSET_MUTPARTS = list(0,0)
)
var/hair_color // this allows races to have specific hair colors... if null, it uses the H's hair/facial hair colors. if "mutcolor", it uses the H's mutant_color
var/hair_alpha = 255 // the alpha used by the hair. 255 is completely solid, 0 is transparent.
@@ -401,6 +421,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
facial_overlay.alpha = hair_alpha
if(OFFSET_FHAIR in H.dna.species.offset_features)
facial_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FHAIR][1]
facial_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FHAIR][2]
standing += facial_overlay
if(H.head)
@@ -458,9 +482,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
else
hair_overlay.color = forced_colour
hair_overlay.alpha = hair_alpha
if(OFFSET_FACE in H.dna.species.offset_features)
hair_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FACE][1]
hair_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FACE][2]
if(OFFSET_HAIR in H.dna.species.offset_features)
hair_overlay.pixel_x += H.dna.species.offset_features[OFFSET_HAIR][1]
hair_overlay.pixel_y += H.dna.species.offset_features[OFFSET_HAIR][2]
if(hair_overlay.icon)
standing += hair_overlay
@@ -481,9 +507,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(H.lip_style && (LIPS in species_traits))
var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/human_face.dmi', "lips_[H.lip_style]", -BODY_LAYER)
lip_overlay.color = H.lip_color
if(OFFSET_FACE in H.dna.species.offset_features)
lip_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FACE][1]
lip_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FACE][2]
if(OFFSET_LIPS in H.dna.species.offset_features)
lip_overlay.pixel_x += H.dna.species.offset_features[OFFSET_LIPS][1]
lip_overlay.pixel_y += H.dna.species.offset_features[OFFSET_LIPS][2]
standing += lip_overlay
// eyes
@@ -496,9 +524,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
eye_overlay = mutable_appearance('icons/mob/human_face.dmi', "eyes", -BODY_LAYER)
if((EYECOLOR in species_traits) && has_eyes)
eye_overlay.color = "#" + H.eye_color
if(OFFSET_FACE in H.dna.species.offset_features)
eye_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FACE][1]
eye_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FACE][2]
if(OFFSET_EYES in H.dna.species.offset_features)
eye_overlay.pixel_x += H.dna.species.offset_features[OFFSET_EYES][1]
eye_overlay.pixel_y += H.dna.species.offset_features[OFFSET_EYES][2]
standing += eye_overlay
//Underwear, Undershirts & Socks
@@ -851,6 +881,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
for(var/index=1, index<=husklist.len, index++)
husklist[index] = husklist[index]/255
accessory_overlay.color = husklist
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
accessory_overlay.pixel_y += H.dna.species.offset_features[OFFSET_MUTPARTS][2]
standing += accessory_overlay
if(S.hasinner)
@@ -863,6 +898,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(S.center)
inner_accessory_overlay = center_image(inner_accessory_overlay, S.dimension_x, S.dimension_y)
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
inner_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
inner_accessory_overlay.pixel_y += H.dna.species.offset_features[OFFSET_MUTPARTS][2]
standing += inner_accessory_overlay
if(S.extra) //apply the extra overlay, if there is one
@@ -903,6 +942,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(HORNCOLOR)
extra_accessory_overlay.color = "#[H.horn_color]"
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
extra_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
extra_accessory_overlay.pixel_y += H.dna.species.offset_features[OFFSET_MUTPARTS][2]
standing += extra_accessory_overlay
if(S.extra2) //apply the extra overlay, if there is one
@@ -937,6 +981,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
extra2_accessory_overlay.color = "#[H.hair_color]"
if(HORNCOLOR)
extra2_accessory_overlay.color = "#[H.horn_color]"
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
extra2_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
extra2_accessory_overlay.pixel_y += H.dna.species.offset_features[OFFSET_MUTPARTS][2]
standing += extra2_accessory_overlay
@@ -1343,9 +1392,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/obj/item/organ/cyberimp/chest/thrusters/T = H.getorganslot(ORGAN_SLOT_THRUSTERS)
if(!istype(J) && istype(C))
J = C.jetpack
if(istype(J) && J.full_speed && J.allow_thrust(0.005, H)) //Prevents stacking
if(istype(J) && J.full_speed && J.allow_thrust(0.01, H)) //Prevents stacking
. -= 0.4
else if(istype(T) && T.allow_thrust(0.005, H))
else if(istype(T) && T.allow_thrust(0.01, H))
. -= 0.4
if(!ignoreslow && gravity)
@@ -709,9 +709,9 @@ generate/load female uniform sprites matching all previously decided variables
if(lip_style && (LIPS in dna.species.species_traits))
var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/human_face.dmi', "lips_[lip_style]", -BODY_LAYER)
lip_overlay.color = lip_color
if(OFFSET_FACE in dna.species.offset_features)
lip_overlay.pixel_x += dna.species.offset_features[OFFSET_FACE][1]
lip_overlay.pixel_y += dna.species.offset_features[OFFSET_FACE][2]
if(OFFSET_LIPS in dna.species.offset_features)
lip_overlay.pixel_x += dna.species.offset_features[OFFSET_LIPS][1]
lip_overlay.pixel_y += dna.species.offset_features[OFFSET_LIPS][2]
add_overlay(lip_overlay)
// eyes
@@ -724,9 +724,9 @@ generate/load female uniform sprites matching all previously decided variables
eye_overlay = mutable_appearance('icons/mob/human_face.dmi', "eyes", -BODY_LAYER)
if((EYECOLOR in dna.species.species_traits) && has_eyes)
eye_overlay.color = "#" + eye_color
if(OFFSET_FACE in dna.species.offset_features)
eye_overlay.pixel_x += dna.species.offset_features[OFFSET_FACE][1]
eye_overlay.pixel_y += dna.species.offset_features[OFFSET_FACE][2]
if(OFFSET_EYES in dna.species.offset_features)
eye_overlay.pixel_x += dna.species.offset_features[OFFSET_EYES][1]
eye_overlay.pixel_y += dna.species.offset_features[OFFSET_EYES][2]
add_overlay(eye_overlay)
dna.species.handle_hair(src)
@@ -1,4 +1,4 @@
/mob/living/carbon/monkey/can_equip(obj/item/I, slot, disable_warning = 0)
/mob/living/carbon/monkey/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
switch(slot)
if(SLOT_HANDS)
if(get_empty_held_indexes())
+4
View File
@@ -13,6 +13,10 @@
if(!no_bodyparts)
spread_bodyparts(no_brain, no_organs)
for(var/X in implants)
var/obj/item/implant/I = X
qdel(I)
spawn_gibs(no_bodyparts)
qdel(src)
+1 -1
View File
@@ -912,7 +912,7 @@
if(mind)
mind.transfer_to(new_mob)
else
new_mob.key = key
transfer_ckey(new_mob)
for(var/para in hasparasites())
var/mob/living/simple_animal/hostile/guardian/G = para
+2 -2
View File
@@ -357,8 +357,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
return message
/mob/living/proc/radio(message, message_mode, list/spans, language)
var/obj/item/implant/radio/imp = locate() in src
if(imp && imp.radio.on)
var/obj/item/implant/radio/imp = locate() in implants
if(imp?.radio.on)
if(message_mode == MODE_HEADSET)
imp.radio.talk_into(src, message, , spans, language)
return ITALICS | REDUCE_RANGE
+1 -1
View File
@@ -192,7 +192,7 @@
/mob/proc/makePAI(delold)
var/obj/item/paicard/card = new /obj/item/paicard(get_turf(src))
var/mob/living/silicon/pai/pai = new /mob/living/silicon/pai(card)
pai.key = key
transfer_ckey(pai)
pai.name = name
card.setPersonality(pai)
if(delold)
@@ -290,7 +290,7 @@
to_chat(user, "<span class='warning'>Access denied.</span>")
else if(istype(W, /obj/item/paicard))
insertpai(user, W)
else if(istype(W, /obj/item/hemostat) && paicard)
else if(W.tool_behaviour == TOOL_HEMOSTAT && paicard)
if(open)
to_chat(user, "<span class='warning'>Close the access panel before manipulating the personality slot!</span>")
else
@@ -915,7 +915,7 @@ Pass a positive integer as an argument to override a bot's default speed.
if(mind && paicard.pai)
mind.transfer_to(paicard.pai)
else if(paicard.pai)
paicard.pai.key = key
transfer_ckey(paicard.pai)
else
ghostize(0) // The pAI card that just got ejected was dead.
key = null
@@ -160,7 +160,7 @@
if(mind)
mind.transfer_to(R, 1)
else
R.key = key
transfer_ckey(R)
qdel(src)
@@ -61,5 +61,5 @@
var/obj/item/new_hat = new hat_type(D)
D.equip_to_slot_or_del(new_hat, SLOT_HEAD)
D.flags_1 |= (flags_1 & ADMIN_SPAWNED_1)
D.key = user.key
user.transfer_ckey(D, FALSE)
qdel(src)
@@ -49,7 +49,7 @@
. = ..()
GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, internal_storage)
hidden_uplink.telecrystals = 30
var/obj/item/implant/weapons_auth/W = new/obj/item/implant/weapons_auth(src)
var/obj/item/implant/weapons_auth/W = new
W.implant(src)
/mob/living/simple_animal/drone/snowflake
@@ -19,7 +19,7 @@
return 0
/mob/living/simple_animal/drone/can_equip(obj/item/I, slot)
/mob/living/simple_animal/drone/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
switch(slot)
if(SLOT_HEAD)
if(head)
@@ -429,9 +429,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
to_chat(G, "<span class='holoparasite'>Your user reset you, and your body was taken over by a ghost. Looks like they weren't happy with your performance.</span>")
to_chat(src, "<span class='holoparasite bold'>Your <font color=\"[G.namedatum.colour]\">[G.real_name]</font> has been successfully reset.</span>")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(G)])")
G.ghostize(0)
G.ghostize(FALSE)
G.setthemename(G.namedatum.theme) //give it a new color, to show it's a new person
G.key = C.key
C.transfer_ckey(G)
G.reset = 1
switch(G.namedatum.theme)
if("tech")
@@ -52,7 +52,7 @@
return 1
return 0
/mob/living/simple_animal/hostile/guardian/dextrous/can_equip(obj/item/I, slot)
/mob/living/simple_animal/hostile/guardian/dextrous/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
switch(slot)
if(SLOT_GENERC_DEXTROUS_STORAGE)
if(internal_storage)
@@ -90,7 +90,7 @@
if(key)
to_chat(user, "<span class='notice'>Someone else already took this spider.</span>")
return 1
key = user.key
user.transfer_ckey(src, FALSE)
return 1
//nursemaids - these create webs and eggs
@@ -0,0 +1,35 @@
#define GOOSE_SATIATED 50
/mob/living/simple_animal/hostile/retaliate/goose
name = "goose"
desc = "It's loose"
icon_state = "goose" // sprites by cogwerks from goonstation, used with permission
icon_living = "goose"
icon_dead = "goose_dead"
mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
speak_chance = 0
turns_per_move = 5
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat = 2)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
emote_taunt = list("hisses")
taunt_chance = 30
speed = 0
maxHealth = 25
health = 25
harm_intent_damage = 5
melee_damage_lower = 5
melee_damage_upper = 5
attacktext = "pecks"
attack_sound = "goose"
speak_emote = list("honks")
faction = list("neutral")
attack_same = TRUE
gold_core_spawnable = HOSTILE_SPAWN
var/random_retaliate = TRUE
/mob/living/simple_animal/hostile/retaliate/goose/handle_automated_movement()
. = ..()
if(prob(5) && random_retaliate == TRUE)
Retaliate()
@@ -585,7 +585,7 @@ Difficulty: Very Hard
var/be_helper = alert("Become a Lightgeist? (Warning, You can no longer be cloned!)",,"Yes","No")
if(be_helper == "Yes" && !QDELETED(src) && isobserver(user))
var/mob/living/simple_animal/hostile/lightgeist/W = new /mob/living/simple_animal/hostile/lightgeist(get_turf(loc))
W.key = user.key
user.transfer_ckey(W, FALSE)
/obj/machinery/anomalous_crystal/helpers/Topic(href, href_list)
@@ -649,7 +649,7 @@ Difficulty: Very Hard
L.heal_overall_damage(heal_power, heal_power)
new /obj/effect/temp_visual/heal(get_turf(target), "#80F5FF")
/mob/living/simple_animal/hostile/lightgeist/ghostize()
/mob/living/simple_animal/hostile/lightgeist/ghostize(can_reenter_corpse = TRUE, send_the_signal = TRUE)
. = ..()
if(.)
death()
@@ -127,7 +127,7 @@
var/client/C = L.client
SSmedals.UnlockMedal("Boss [BOSS_KILL_MEDAL]", C)
SSmedals.UnlockMedal("[medaltype] [BOSS_KILL_MEDAL]", C)
if(crusher_kill && istype(L.get_active_held_item(), /obj/item/twohanded/required/kinetic_crusher))
if(crusher_kill && istype(L.get_active_held_item(), /obj/item/twohanded/kinetic_crusher))
SSmedals.UnlockMedal("[medaltype] [BOSS_KILL_MEDAL_CRUSHER]", C)
SSmedals.SetScore(BOSS_SCORE, C, 1)
SSmedals.SetScore(score_type, C, 1)
@@ -46,7 +46,8 @@
fireball.human_req = 0
fireball.player_lock = 0
AddSpell(fireball)
implants += new /obj/item/implant/exile(src)
var/obj/item/implant/exile/I = new
I.implant(src, null, TRUE)
mm = new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile
mm.clothes_req = 0
@@ -916,7 +916,7 @@
if(mind)
mind.transfer_to(G)
else
G.key = key
transfer_ckey(G)
..(gibbed)
/mob/living/simple_animal/parrot/Poly/proc/Read_Memory()
@@ -198,7 +198,7 @@
if(src.mind)
src.mind.transfer_to(new_slime)
else
new_slime.key = src.key
transfer_ckey(new_slime)
qdel(src)
else
to_chat(src, "<i>I am not ready to reproduce yet...</i>")
+7 -1
View File
@@ -444,7 +444,13 @@
// M.Login() //wat
return
/mob/proc/transfer_ckey(mob/new_mob, send_signal = TRUE)
if(!ckey)
return FALSE
if(send_signal)
SEND_SIGNAL(src, COMSIG_MOB_KEY_CHANGE, new_mob, src)
new_mob.ckey = ckey
return TRUE
/mob/verb/cancel_camera()
set name = "Cancel Camera View"
+2 -2
View File
@@ -429,8 +429,8 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
var/mob/dead/observer/C = pick(candidates)
to_chat(M, "Your mob has been taken over by a ghost!")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(M)])")
M.ghostize(0)
M.key = C.key
M.ghostize(FALSE, TRUE)
C.transfer_ckey(M, FALSE)
return TRUE
else
to_chat(M, "There were no ghosts willing to take control.")
@@ -53,7 +53,7 @@
if(mind && isliving(M))
mind.transfer_to(M, 1) // second argument to force key move to new mob
else
M.key = key
transfer_ckey(M)
if(delete_old_mob)
QDEL_IN(src, 1)
+44 -66
View File
@@ -382,7 +382,7 @@
mind.active = FALSE
mind.transfer_to(R)
else if(transfer_after)
R.key = key
transfer_ckey(R)
R.apply_pref_name("cyborg")
@@ -401,7 +401,7 @@
qdel(src)
//human -> alien
/mob/living/carbon/human/proc/Alienize()
/mob/living/carbon/human/proc/Alienize(mind_transfer = TRUE)
if (notransform)
return
for(var/obj/item/W in src)
@@ -425,13 +425,16 @@
new_xeno = new /mob/living/carbon/alien/humanoid/drone(loc)
new_xeno.a_intent = INTENT_HARM
new_xeno.key = key
if(mind && mind_transfer)
mind.transfer_to(new_xeno)
else
transfer_ckey(new_xeno)
to_chat(new_xeno, "<B>You are now an alien.</B>")
. = new_xeno
qdel(src)
/mob/living/carbon/human/proc/slimeize(reproduce as num)
/mob/living/carbon/human/proc/slimeize(reproduce, mind_transfer = TRUE)
if (notransform)
return
for(var/obj/item/W in src)
@@ -457,20 +460,26 @@
else
new_slime = new /mob/living/simple_animal/slime(loc)
new_slime.a_intent = INTENT_HARM
new_slime.key = key
if(mind && mind_transfer)
mind.transfer_to(new_slime)
else
transfer_ckey(new_slime)
to_chat(new_slime, "<B>You are now a slime. Skreee!</B>")
. = new_slime
qdel(src)
/mob/proc/become_overmind(starting_points = 60)
/mob/proc/become_overmind(starting_points = 60, mind_transfer = FALSE)
var/mob/camera/blob/B = new /mob/camera/blob(get_turf(src), starting_points)
B.key = key
if(mind && mind_transfer)
mind.transfer_to(B)
else
transfer_ckey(B)
. = B
qdel(src)
/mob/living/carbon/human/proc/corgize()
/mob/living/carbon/human/proc/corgize(mind_transfer = TRUE)
if (notransform)
return
for(var/obj/item/W in src)
@@ -485,13 +494,16 @@
var/mob/living/simple_animal/pet/dog/corgi/new_corgi = new /mob/living/simple_animal/pet/dog/corgi (loc)
new_corgi.a_intent = INTENT_HARM
new_corgi.key = key
if(mind && mind_transfer)
mind.transfer_to(new_corgi)
else
transfer_ckey(new_corgi)
to_chat(new_corgi, "<B>You are now a Corgi. Yap Yap!</B>")
. = new_corgi
qdel(src)
/mob/living/carbon/proc/gorillize()
/mob/living/carbon/proc/gorillize(mind_transfer = TRUE)
if(notransform)
return
@@ -509,22 +521,22 @@
invisibility = INVISIBILITY_MAXIMUM
var/mob/living/simple_animal/hostile/gorilla/new_gorilla = new (get_turf(src))
new_gorilla.a_intent = INTENT_HARM
if(mind)
if(mind && mind_transfer)
mind.transfer_to(new_gorilla)
else
new_gorilla.key = key
transfer_ckey(new_gorilla)
to_chat(new_gorilla, "<B>You are now a gorilla. Ooga ooga!</B>")
. = new_gorilla
qdel(src)
/mob/living/carbon/human/Animalize()
/mob/living/carbon/human/Animalize(mind_transfer = TRUE)
var/list/mobtypes = typesof(/mob/living/simple_animal)
var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") in mobtypes
if(!safe_animal(mobpath))
to_chat(usr, "<span class='danger'>Sorry but this mob type is currently unavailable.</span>")
var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") as null|anything in mobtypes
if(!mobpath)
return
if(mind)
mind_transfer = alert("Want to transfer their mind into the new mob", "Mind Transfer", "Yes", "No") == "Yes" ? TRUE : FALSE
if(notransform)
return
@@ -532,8 +544,8 @@
dropItemToGround(W)
regenerate_icons()
notransform = 1
canmove = 0
notransform = TRUE
canmove = FALSE
icon = null
invisibility = INVISIBILITY_MAXIMUM
@@ -541,8 +553,10 @@
qdel(t)
var/mob/new_mob = new mobpath(src.loc)
new_mob.key = key
if(mind && mind_transfer)
mind.transfer_to(new_mob)
else
transfer_ckey(new_mob)
new_mob.a_intent = INTENT_HARM
@@ -550,59 +564,23 @@
. = new_mob
qdel(src)
/mob/proc/Animalize()
/mob/proc/Animalize(mind_transfer = TRUE)
var/list/mobtypes = typesof(/mob/living/simple_animal)
var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") in mobtypes
if(!safe_animal(mobpath))
to_chat(usr, "<span class='danger'>Sorry but this mob type is currently unavailable.</span>")
var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") as null|anything in mobtypes
if(!mobpath)
return
if(mind)
mind_transfer = alert("Want to transfer their mind into the new mob", "Mind Transfer", "Yes", "No") == "Yes" ? TRUE : FALSE
var/mob/new_mob = new mobpath(src.loc)
new_mob.key = key
if(mind && mind_transfer)
mind.transfer_to(new_mob)
else
transfer_ckey(new_mob)
new_mob.a_intent = INTENT_HARM
to_chat(new_mob, "You feel more... animalistic")
. = new_mob
qdel(src)
/* Certain mob types have problems and should not be allowed to be controlled by players.
*
* This proc is here to force coders to manually place their mob in this list, hopefully tested.
* This also gives a place to explain -why- players shouldnt be turn into certain mobs and hopefully someone can fix them.
*/
/mob/proc/safe_animal(MP)
//Bad mobs! - Remember to add a comment explaining what's wrong with the mob
if(!MP)
return 0 //Sanity, this should never happen.
if(ispath(MP, /mob/living/simple_animal/hostile/construct))
return 0 //Verbs do not appear for players.
//Good mobs!
if(ispath(MP, /mob/living/simple_animal/pet/cat))
return 1
if(ispath(MP, /mob/living/simple_animal/pet/dog/corgi))
return 1
if(ispath(MP, /mob/living/simple_animal/crab))
return 1
if(ispath(MP, /mob/living/simple_animal/hostile/carp))
return 1
if(ispath(MP, /mob/living/simple_animal/hostile/mushroom))
return 1
if(ispath(MP, /mob/living/simple_animal/shade))
return 1
if(ispath(MP, /mob/living/simple_animal/hostile/killertomato))
return 1
if(ispath(MP, /mob/living/simple_animal/mouse))
return 1 //It is impossible to pull up the player panel for mice (Fixed! - Nodrak)
if(ispath(MP, /mob/living/simple_animal/hostile/bear))
return 1 //Bears will auto-attack mobs, even if they're player controlled (Fixed! - Nodrak)
if(ispath(MP, /mob/living/simple_animal/parrot))
return 1 //Parrots are no longer unfinished! -Nodrak
//Not in here? Must be untested!
return 0
+1 -1
View File
@@ -191,7 +191,7 @@
/obj/item/stock_parts/cell/secborg
name = "security borg rechargeable D battery"
maxcharge = 1750 //35/17/8 disabler/laser/taser shots.
maxcharge = 1250 //25/12/6 disabler/laser/taser shots.
materials = list(MAT_GLASS=40)
/obj/item/stock_parts/cell/secborg/empty/Initialize()
@@ -329,6 +329,12 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
if(power)
soundloop.volume = min(40, (round(power/100)/50)+1) // 5 +1 volume per 20 power. 2500 power is max
if(isclosedturf(T))
var/turf/did_it_melt = T.Melt()
if(!isclosedturf(did_it_melt)) //In case some joker finds way to place these on indestructible walls
visible_message("<span class='warning'>[src] melts through [T]!</span>")
return
//Ok, get the air from the turf
var/datum/gas_mixture/env = T.return_air()
@@ -25,3 +25,6 @@
fire_sound = 'sound/weapons/taser2.ogg'
harmful = FALSE
click_cooldown_override = 3.5
/obj/item/ammo_casing/energy/disabler/secborg
e_cost = 50
@@ -277,12 +277,12 @@
..()
if(istype(A, /obj/item/ammo_box) || istype(A, /obj/item/ammo_casing))
chamber_round()
if(A.tool_behaviour == TOOL_SAW || istype(A, /obj/item/gun/energy/plasmacutter))
sawoff(user)
if(istype(A, /obj/item/melee/transforming/energy))
var/obj/item/melee/transforming/energy/W = A
if(W.active)
sawoff(user)
if(istype(A, /obj/item/circular_saw) || istype(A, /obj/item/gun/energy/plasmacutter))
sawoff(user)
/obj/item/gun/ballistic/revolver/doublebarrel/attack_self(mob/living/user)
var/num_unloaded = 0
@@ -95,7 +95,7 @@
/obj/item/gun/ballistic/shotgun/riot/attackby(obj/item/A, mob/user, params)
..()
if(istype(A, /obj/item/circular_saw) || istype(A, /obj/item/gun/energy/plasmacutter))
if(A.tool_behaviour == TOOL_SAW || istype(A, /obj/item/gun/energy/plasmacutter))
sawoff(user)
if(istype(A, /obj/item/melee/transforming/energy))
var/obj/item/melee/transforming/energy/W = A
@@ -49,6 +49,7 @@
name = "cyborg disabler"
desc = "An integrated disabler that draws from a cyborg's power cell. This one contains a limiter to prevent the cyborg's power cell from overheating."
can_charge = FALSE
ammo_type = list(/obj/item/ammo_casing/energy/disabler/secborg)
selfcharge = EGUN_SELFCHARGE_BORG
cell_type = /obj/item/stock_parts/cell/secborg
charge_delay = 5
+55 -22
View File
@@ -1,14 +1,46 @@
//Generates a markdown txt file for use with the wiki
/proc/find_reagent(input)
. = FALSE
if(GLOB.chemical_reagents_list[input]) //prefer IDs!
var/datum/reagent/R = GLOB.chemical_reagents_list[input]
return R
else
for(var/X in GLOB.chemical_reagents_list)
var/datum/reagent/R = GLOB.chemical_reagents_list[X]
if(input == replacetext(lowertext(R.name), " ", ""))
return R
if(input == replacetext(lowertext(R.id), " ", ""))
return R
/client/proc/generate_wikichem_list()
set name = "Generate Wikichems"
set category = "Debug"
set desc = "Generate a huge loglist of all the chems. Do not click unless you want lag."
message_admins("Someone pressed the lag button. (Generate Wikichems)")
to_chat(usr, "Generating list")
var/prefix = "|Name | Reagents | Reaction vars | Description | Chem properties |\n|---|---|---|-----------|---|\n"
var/prefix = "|Name | Reagents | Reaction vars | Description | Chem properties |\n|---|---|---|-----------|---|\n"
var/input_reagent = replacetext(lowertext(input("Input the name/id of a reagent to get it's description on it's own, or leave blank to parse every chem.", "Input") as text), " ", "") //95% of the time, the reagent id is a lowercase/no spaces version of the name
if(input_reagent)
var/input_reagent2 = find_reagent(input_reagent)
if(!input_reagent2)
to_chat(usr, "Unable to find reagent, stopping proc.")
var/single_parse = generate_chemwiki_line(input_reagent2, input_reagent, FALSE)
text2file(single_parse, "[GLOB.log_directory]/chem_parse.md")
to_chat(usr, "[single_parse].")
single_parse = generate_chemwiki_line(input_reagent2, input_reagent, FALSE)
text2file(single_parse, "[GLOB.log_directory]/chem_parse.md")
to_chat(usr, "[single_parse].")
to_chat(usr, "Saved line to (wherever your root folder is, i.e. where the DME is)/[GLOB.log_directory]/chem_parse.md OR use the Get Current Logs verb under the Admin tab. (if you click Open, and it does nothing, that's because you've not set a .md default program! Try downloading it instead, and use that file to set a default program! Also have a cute day.)")
//Do things here
return
to_chat(usr, "Generating big list")
message_admins("Someone pressed the lag button. (Generate Wikichems)")
///datum/reagent/medicine, /datum/reagent/toxin, /datum/reagent/consumable, /datum/reagent/plantnutriment, /datum/reagent/uranium,
///datum/reagent/colorful_reagent, /datum/reagent/mutationtoxin, /datum/reagent/fermi, /datum/reagent/drug, /datum/reagent/impure
@@ -33,7 +65,7 @@
var/alco = ""
var/grinded = ""
var/blob = ""
//var/impure
var/impure = ""
//Chem_dispencer
var/list/dispensable_reagents = list(
@@ -129,36 +161,46 @@
"applejack"
)
var/breakout = FALSE
for(var/i = 1, i <= 2, i+=1)
for(var/X in GLOB.chemical_reagents_list)
R = GLOB.chemical_reagents_list[X]
if(!R.description) //No description? It's not worth my time.
continue
for(var/Y in dispensable_reagents) //Why do you have to do this
if(R.id == Y)
basic += generate_chemwiki_line(R, X, processCR)
breakout = TRUE
continue
for(var/Y in components)
if(R.id == Y)
upgraded += generate_chemwiki_line(R, X, processCR)
breakout = TRUE
continue
for(var/Y in dispence_drinks)
if(R.id == Y)
drinks += generate_chemwiki_line(R, X, processCR)
breakout = TRUE
continue
for(var/Y in dispence_alco)
if(R.id == Y)
alco += generate_chemwiki_line(R, X, processCR)
breakout = TRUE
continue
for(var/Y in grind)
if(R.id == Y)
grinded += generate_chemwiki_line(R, X, processCR)
breakout = TRUE
continue
if(breakout)
breakout = FALSE
continue
if(istype(R, /datum/reagent/medicine))
medicine += generate_chemwiki_line(R, X, processCR)
@@ -190,10 +232,8 @@
else if(istype(R, /datum/reagent/blob))
blob += generate_chemwiki_line(R, X, processCR)
/* when merged
else if(istype(R, /datum/reagent/impure))
impure += generate_chemwiki_line(R, X, processCR)
*/
else
remainder += generate_chemwiki_line(R, X, processCR)
@@ -206,8 +246,8 @@
to_chat(usr, "finished chems")
var/wholeString = ("\n# DISPENCEABLE REAGENTS\n\n[prefix][basic]\n\n# COMPONENT REAGENTS\n\n[prefix][upgraded]\n\n# GRINDABLE REAGENTS\n\n[prefix][grinded]\n")
wholeString += ("\n# MEDICINE:\n\n[prefix][medicine]\n\n# TOXIN:\n\n[prefix][toxin]\n\n# DRUGS\n\n[prefix][drug]\n\n# FERMI\n\nThese chems lie on the cutting edge of chemical technology, and as such are not recommended for beginners!\n\n[prefix][fermi]\n\n# GENERAL REAGENTS\n\n[prefix][remainder]\n\n# DISPENCEABLE SOFT DRINKS\n\n[prefix][drinks]\n\n# DISPENCEABLE HARD DRINKS\n\n[prefix][alco]\n\n# CONSUMABLE\n\n[prefix][consumable]\n\n# PLANTS\n\n[prefix][plant]\n\n# URANIUM\n\n[prefix][uranium]\n\n# COLOURS\n\n[prefix][colours]\n\n# RACE MUTATIONS\n\n[prefix][muta]\n\n\n# BLOB REAGENTS\n\n[prefix][blob]\n")
var/wholeString = ("\n# DISPENCEABLE REAGENTS\n\n[prefix][basic]\n\n# COMPONENT REAGENTS\n\n[prefix][upgraded]\n\n# GROUND REAGENTS\n\n[prefix][grinded]\n")
wholeString += ("\n# MEDICINE:\n\n[prefix][medicine]\n\n# TOXIN:\n\n[prefix][toxin]\n\n# DRUGS\n\n[prefix][drug]\n\n# FERMI\n\nThese chems lie on the cutting edge of chemical technology, and as such are not recommended for beginners!\n\n[prefix][fermi]\n\n# IMPURE REAGENTS\n\n[prefix][impure]\n\n# GENERAL REAGENTS\n\n[prefix][remainder]\n\n# DISPENCEABLE SOFT DRINKS\n\n[prefix][drinks]\n\n# DISPENCEABLE HARD DRINKS\n\n[prefix][alco]\n\n# CONSUMABLE\n\n[prefix][consumable]\n\n# PLANTS\n\n[prefix][plant]\n\n# URANIUM\n\n[prefix][uranium]\n\n# COLOURS\n\n[prefix][colours]\n\n# RACE MUTATIONS\n\n[prefix][muta]\n\n\n# BLOB REAGENTS\n\n[prefix][blob]\n")
prefix = "|Name | Reagents | Reaction vars | Description |\n|---|---|---|----------|\n"
var/CRparse = ""
@@ -257,6 +297,8 @@
//Temp, Explosions and pH
if(CR)
outstring += "<ul>[(CR.FermiChem?"<li>Min react temp: [CR.OptimalTempMin]K</li>":"[(CR.required_temp?"<li>Min react temp: [CR.required_temp]K</li>":"")]")] [(CR.FermiChem?"<li>Explosion_temp: [CR.ExplodeTemp]K</li>":"")] [(CR.FermiChem?"<li>pH range: [max((CR.OptimalpHMin - CR.ReactpHLim), 0)] to [min((CR.OptimalpHMax + CR.ReactpHLim), 14)]</li>":"")] "
if(CR.FermiChem)
outstring += "[(CR.PurityMin?"<li>Min explosive purity: [CR.PurityMin]</li>":"")] [(CR.FermiExplode?"<li>Special explosion: Yes</li>":"")]"
else
outstring += ""
@@ -288,17 +330,15 @@
outstring += " | "
//Description, OD, Addict, Meta
outstring += "[R.description] | <ul><li>Metabolism_rate: [R.metabolization_rate/2]u/s</li> [(R.overdose_threshold?"<li>Overdose: [R.overdose_threshold]u</li>":"")] [(R.addiction_threshold?"<li>Addiction: [R.addiction_threshold]u</li>":"")] "
outstring += "[R.description] | <ul><li>Metabolism rate: [R.metabolization_rate/2]u/s</li> [(R.overdose_threshold?"<li>Overdose: [R.overdose_threshold]u</li>":"")] [(R.addiction_threshold?"<li>Addiction: [R.addiction_threshold]u</li>":"")] "
if(R.impure_chem != "fermiTox" && R.impure_chem)
if(R.impure_chem && R.impure_chem != "fermiTox")
R3 = GLOB.chemical_reagents_list[R.impure_chem]
outstring += "<li>Impure chem:<a href=\"#[R3.name]\">[R3.name]</a></li>"
if(R.inverse_chem != "fermiTox" && R.inverse_chem)
if(R.inverse_chem && R.impure_chem != "fermiTox")
R3 = GLOB.chemical_reagents_list[R.inverse_chem]
outstring += "<li>Inverse chem:<a href=\"#[R3.name]\">[R3.name]</a></li> "
outstring += "<li>Inverse chem:<a href=\"#[R3.name]\">[R3.name]</a></li> [(R3.inverse_chem_val?"<li>Inverse purity: [R3.inverse_chem_val]</li>":"")] "
if(CR)
if(CR.required_container)
@@ -307,16 +347,9 @@
outstring += "<li>Required container: [I.name]</li>"*/
outstring += "<li>Required container: [CR.required_container]</li>"
if(CR.FermiChem)
outstring += "<li>Minimum purity: [CR.PurityMin]</li> [(CR.FermiExplode?"<li>Special explosion: Yes</li>":"")]"
outstring += "</ul>|\n"
return outstring
//Generate the big list of reaction based reactions.
//|Name | Reagents | Reaction vars | Description | Chem properties
/proc/generate_chemreactwiki_line(datum/chemical_reaction/CR)
+58 -53
View File
@@ -63,7 +63,7 @@
var/targetVol = 0 //the target volume, i.e. the total amount that can be created during a fermichem reaction.
var/reactedVol = 0 //how much of the reagent is reacted during a fermireaction
var/fermiIsReacting = FALSE //that prevents multiple reactions from occurring (i.e. add_reagent calls to process_reactions(), this stops any extra reactions.)
var/fermiReactID = null //ID of the chem being made during a fermireaction, kept here so it's cache isn't lost between loops/procs.
var/fermiReactID //ID of the chem being made during a fermireaction, kept here so it's cache isn't lost between loops/procs.
/datum/reagents/New(maximum=100, new_flags)
maximum_volume = maximum
@@ -365,7 +365,7 @@
/datum/reagents/proc/handle_reactions()//HERE EDIT HERE THE MAIN REACTION
if(fermiIsReacting == TRUE)
if(fermiIsReacting) //This ARRESTS other reactions. If you don't want this, then remove it.
return
if(reagents_holder_flags & NO_REACT)
@@ -404,7 +404,7 @@
for(var/B in cached_required_reagents)
if(!has_reagent(B, cached_required_reagents[B]))
if(!has_reagent(B, cached_required_reagents[B]*CHEMICAL_QUANTISATION_LEVEL))//Allows vols at less than 1 to react.
break
total_matching_reagents++
for(var/B in cached_required_catalysts)
@@ -464,7 +464,7 @@
//Temperature plays into a larger role too.
var/datum/chemical_reaction/C = selected_reaction
if (C.FermiChem == TRUE && !continue_reacting)
if (C.FermiChem && !continue_reacting)
if (chem_temp > C.ExplodeTemp) //This is first to ensure explosions.
var/datum/chemical_reaction/Ferm = selected_reaction
fermiIsReacting = FALSE
@@ -472,31 +472,28 @@
Ferm.FermiExplode(src, my_atom, volume = total_volume, temp = chem_temp, pH = pH)
return 0
//This is just to calc the on_reaction multiplier, and is a candidate for removal.
for(var/B in cached_required_reagents)
multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), CHEMICAL_QUANTISATION_LEVEL))
multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), 0.0001))
for(var/P in selected_reaction.results)
targetVol = cached_results[P]*multiplier
if( (chem_temp <= C.ExplodeTemp) && (chem_temp >= C.OptimalTempMin))
if( (pH >= (C.OptimalpHMin - C.ReactpHLim)) && (pH <= (C.OptimalpHMax + C.ReactpHLim)) )//To prevent pointless reactions
if (fermiIsReacting == TRUE)
return 0
else
START_PROCESSING(SSprocessing, src)
selected_reaction.on_reaction(src, my_atom, multiplier)
fermiIsReacting = TRUE
fermiReactID = selected_reaction
reaction_occurred = 1
else //It's a little bit of a confusing nest, but esstentially we check if it's a fermireaction, then temperature, then pH. If this is true, the remainer of this handler is run.
return 0 //If pH is out of range
if(!((chem_temp <= C.ExplodeTemp) && (chem_temp >= C.OptimalTempMin)))
return 0 //Not hot enough
if(! ((pH >= (C.OptimalpHMin - C.ReactpHLim)) && (pH <= (C.OptimalpHMax + C.ReactpHLim)) ))//To prevent pointless reactions
return 0
if (fermiIsReacting)
return 0
else
return 0 //If not hot enough
START_PROCESSING(SSprocessing, src)
selected_reaction.on_reaction(src, my_atom, multiplier)
fermiIsReacting = TRUE
fermiReactID = selected_reaction
reaction_occurred = 1
//Standard reaction mechanics:
else
if (C.FermiChem == TRUE)//Just to make sure, should only proc when grenades are combining.
if (C.FermiChem)//Just to make sure, should only proc when grenades are combining.
if (chem_temp > C.ExplodeTemp) //To allow fermigrenades
var/datum/chemical_reaction/fermi/Ferm = selected_reaction
fermiIsReacting = FALSE
@@ -551,38 +548,43 @@
var/multiplier = INFINITY
for(var/B in cached_required_reagents) //
multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), 0.001))
if (multiplier == 0)
multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), 0.0001))
if (multiplier == 0)//clarity
fermiEnd()
return
for(var/P in C.required_catalysts)
if(!has_reagent(P))
fermiEnd()
return
for(var/P in cached_results)
targetVol = cached_results[P]*multiplier
if (fermiIsReacting == FALSE)
if (!fermiIsReacting)
CRASH("Fermi has refused to stop reacting even though we asked her nicely.")
if (chem_temp > C.OptimalTempMin && fermiIsReacting == TRUE)//To prevent pointless reactions
if( (pH >= (C.OptimalpHMin - C.ReactpHLim)) && (pH <= (C.OptimalpHMax + C.ReactpHLim)) )
if (reactedVol < targetVol)
reactedVol = fermiReact(fermiReactID, chem_temp, pH, reactedVol, targetVol, cached_required_reagents, cached_results, multiplier)
else//Volume is used up
fermiEnd()
return
else//pH is out of range
fermiEnd()
return
else//Temperature is too low, or reaction has stopped.
if (!(chem_temp >= C.OptimalTempMin))//To prevent pointless reactions
fermiEnd()
return
if (!( (pH >= (C.OptimalpHMin - C.ReactpHLim)) && (pH <= (C.OptimalpHMax + C.ReactpHLim)) )) //if pH is too far out, (could possibly allow reactions at this point, after the reaction has started, but make purity = 0)
fermiEnd()
return
reactedVol = fermiReact(fermiReactID, chem_temp, pH, reactedVol, targetVol, cached_required_reagents, cached_results, multiplier)
if(round(reactedVol, CHEMICAL_QUANTISATION_LEVEL) == round(targetVol, CHEMICAL_QUANTISATION_LEVEL))
fermiEnd()
if(!reactedVol)//Maybe unnessicary.
fermiEnd()
return
/datum/reagents/proc/fermiEnd()
var/datum/chemical_reaction/C = fermiReactID
STOP_PROCESSING(SSprocessing, src)
fermiIsReacting = FALSE
reactedVol = 0
targetVol = 0
//Cap off values
for(var/datum/reagent/R in reagent_list)
R.volume = round(R.volume, CHEMICAL_QUANTISATION_LEVEL)//To prevent runaways.
//pH check, handled at the end to reduce calls.
if(istype(my_atom, /obj/item/reagent_containers))
var/obj/item/reagent_containers/RC = my_atom
@@ -593,7 +595,6 @@
handle_reactions()
update_total()
//Reaction sounds and words
playsound(get_turf(my_atom), C.mix_sound, 80, 1)
var/list/seen = viewers(5, get_turf(my_atom))
var/iconhtml = icon2html(my_atom, seen)
for(var/mob/M in seen)
@@ -650,16 +651,18 @@
//ONLY WORKS FOR ONE PRODUCT AT THE MOMENT
//Calculate how much product to make and how much reactant to remove factors..
for(var/P in cached_results)
//stepChemAmmount = CLAMP(((deltaT * multiplier), 0, ((targetVol - reactedVol)/cached_results[P])) //used to have multipler, now it does
stepChemAmmount = (multiplier*cached_results[P])
if (stepChemAmmount >= C.RateUpLim)
stepChemAmmount = (C.RateUpLim)
if (stepChemAmmount > C.RateUpLim)
stepChemAmmount = C.RateUpLim
addChemAmmount = deltaT * stepChemAmmount
if (addChemAmmount >= (targetVol - reactedVol))
addChemAmmount = (targetVol - reactedVol)
if (addChemAmmount < CHEMICAL_QUANTISATION_LEVEL)
addChemAmmount = CHEMICAL_QUANTISATION_LEVEL
removeChemAmmount = (addChemAmmount/cached_results[P])
//keep limited.
addChemAmmount = round(addChemAmmount, CHEMICAL_QUANTISATION_LEVEL)
removeChemAmmount = round(removeChemAmmount, CHEMICAL_QUANTISATION_LEVEL)
//This is kept for future bugtesters.
//message_admins("Reaction vars: PreReacted: [reactedVol] of [targetVol]. deltaT [deltaT], multiplier [multiplier], Step [stepChemAmmount], uncapped Step [deltaT*(multiplier*cached_results[P])], addChemAmmount [addChemAmmount], removeFactor [removeChemAmmount] Pfactor [cached_results[P]], adding [addChemAmmount]")
@@ -672,7 +675,7 @@
for(var/P in cached_results)
SSblackbox.record_feedback("tally", "chemical_reaction", addChemAmmount, P)//log
SSblackbox.record_feedback("tally", "fermi_chem", addChemAmmount, P)
add_reagent(P, (addChemAmmount), null, cached_temp, purity)//add reagent function!! I THINK I can do this:
add_reagent(P, (addChemAmmount), null, cached_temp, purity)
TotalStep += addChemAmmount//for multiple products
//Above should reduce yeild based on holder purity.
//Purity Check
@@ -681,9 +684,9 @@
if (R.purity < C.PurityMin)//If purity is below the min, blow it up.
fermiIsReacting = FALSE
SSblackbox.record_feedback("tally", "fermi_chem", 1, ("[P] explosion"))
C.FermiExplode(src, my_atom, (reactedVol+targetVol), cached_temp, pH)
C.FermiExplode(src, my_atom, (total_volume), cached_temp, pH)
STOP_PROCESSING(SSprocessing, src)
return 0
return
C.FermiCreate(src, addChemAmmount, purity)//proc that calls when step is done
@@ -698,11 +701,11 @@
//go to explode proc
fermiIsReacting = FALSE
SSblackbox.record_feedback("tally", "fermi_chem", 1, ("[C] explosions"))
C.FermiExplode(src, my_atom, (reactedVol+targetVol), chem_temp, pH)
C.FermiExplode(src, my_atom, (total_volume), chem_temp, pH)
STOP_PROCESSING(SSprocessing, src)
return
//Make sure things are limited.
//Make sure things are limited, but superacids/bases can push forward the reaction
pH = CLAMP(pH, 0, 14)
//return said amount to compare for next step.
@@ -717,6 +720,8 @@
if (R in cached_reagents)
cachedPurity += R.purity
i++
if(!i)//I've never seen it get here with 0, but in case
CRASH("No reactants found mid reaction for [fermiReactID]/[C], how it got here is beyond me. Beaker: [holder]")
return cachedPurity/i
/datum/reagents/proc/uncache_purity(id)
@@ -758,14 +763,14 @@
total_volume = 0
for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
if(R.volume == 0)
if(R.volume <= 0)//For clarity
del_reagent(R.id)
if((R.volume < 0.01) && !fermiIsReacting)
del_reagent(R.id)
else
total_volume += R.volume
if(!reagent_list)
pH = 7
if(!reagent_list || !total_volume)
pH = REAGENT_NORMAL_PH
return 0
/datum/reagents/proc/clear_reagents()
@@ -830,7 +835,7 @@
if(!isnum(amount) || !amount)
return FALSE
if(amount <= CHEMICAL_QUANTISATION_LEVEL)//To prevent small ammount problems.
if(amount < CHEMICAL_QUANTISATION_LEVEL)//To prevent small ammount problems.
return FALSE
var/datum/reagent/D = GLOB.chemical_reagents_list[reagent]
@@ -838,7 +843,7 @@
WARNING("[my_atom] attempted to add a reagent called '[reagent]' which doesn't exist. ([usr])")
return FALSE
if (D.id == "water" && no_react == FALSE && !istype(my_atom, /obj/item/reagent_containers/food)) //Do like an otter, add acid to water, but also don't blow up botany.
if (D.id == "water" && !no_react && !istype(my_atom, /obj/item/reagent_containers/food)) //Do like an otter, add acid to water, but also don't blow up botany.
if (pH <= 2)
SSblackbox.record_feedback("tally", "fermi_chem", 1, "water-acid explosions")
var/datum/effect_system/smoke_spread/chem/s = new
@@ -881,7 +886,7 @@
chem_temp = thermal_energy / (specific_heat * new_total)
//cacluate reagent based pH shift.
if(ignore_pH == TRUE)
if(ignore_pH)
pH = ((cached_pH * cached_total)+(other_pH * amount))/(cached_total + amount)//should be right
else
pH = ((cached_pH * cached_total)+(D.pH * amount))/(cached_total + amount)//should be right
@@ -960,7 +965,7 @@
if((total_volume - amount) <= 0)//Because this can result in 0, I don't want it to crash.
pH = 7
//In practice this is really confusing and players feel like it randomly melts their beakers, but I'm not sure how else to handle it. We'll see how it goes and I can remove this if it confuses people.
else if (ignore_pH == FALSE)
else if (!ignore_pH)
//if (((pH > R.pH) && (pH <= 7)) || ((pH < R.pH) && (pH >= 7)))
pH = (((pH - R.pH) / total_volume) * amount) + pH
if(istype(my_atom, /obj/item/reagent_containers/))
@@ -125,12 +125,6 @@
else
cut_overlays()
/obj/machinery/computer/pandemic/proc/eject_beaker()
if(beaker)
beaker.forceMove(drop_location())
beaker = null
update_icon()
/obj/machinery/computer/pandemic/ui_interact(mob/user, ui_key = "main", datum/tgui/ui, force_open = FALSE, datum/tgui/master_ui, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
@@ -165,7 +159,7 @@
return
switch(action)
if("eject_beaker")
eject_beaker()
replace_beaker(usr)
. = TRUE
if("empty_beaker")
if(beaker)
@@ -174,7 +168,7 @@
if("empty_eject_beaker")
if(beaker)
beaker.reagents.clear_reagents()
eject_beaker()
replace_beaker(usr)
. = TRUE
if("rename_disease")
var/id = get_virus_id_by_index(text2num(params["index"]))
@@ -234,18 +228,32 @@
. = TRUE //no afterattack
if(stat & (NOPOWER|BROKEN))
return
if(beaker)
to_chat(user, "<span class='warning'>A container is already loaded into [src]!</span>")
var/obj/item/reagent_containers/B = I
if(!user.transferItemToLoc(B, src))
return
if(!user.transferItemToLoc(I, src))
return
beaker = I
replace_beaker(user, B)
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
update_icon()
else
return ..()
/obj/machinery/computer/pandemic/AltClick(mob/living/user)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
replace_beaker(user)
return
/obj/machinery/computer/pandemic/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(beaker)
beaker.forceMove(drop_location())
if(user && Adjacent(user) && !issiliconoradminghost(user))
user.put_in_hands(beaker)
if(new_beaker)
beaker = new_beaker
else
beaker = null
update_icon()
return TRUE
/obj/machinery/computer/pandemic/on_deconstruction()
eject_beaker()
replace_beaker(usr)
. = ..()
@@ -9,7 +9,7 @@
/datum/reagent/impure/fermiTox
name = "Chemical Isomers"
id = "fermiTox"
description = "Toxic chemical isomers made from impure reactions. At low volumes will cause light toxin damage, but as the volume increases, it deals larger amounts, damages the liver, then eventually the heart."
description = "Toxic chemical isomers made from impure reactions. At low volumes will cause light toxin damage, but as the volume increases, it deals larger amounts, damages the liver, then eventually the heart. This is default impure chem for all chems, and changes only if stated."
data = "merge"
color = "FFFFFF"
can_synth = FALSE
@@ -3,6 +3,7 @@
name = "Blood"
id = "blood"
color = "#C80000" // rgb: 200, 0, 0
description = "Blood from a human, or otherwise."
metabolization_rate = 5 //fast rate so it disappears fast.
taste_description = "iron"
taste_mult = 1.3
@@ -71,8 +71,8 @@
/datum/chemical_reaction/synthtissue
name = "Synthtissue"
id = "synthtissue"
results = list("synthtissue" = 0.05)
required_reagents = list("synthflesh" = 0.01)
results = list("synthtissue" = 5)
required_reagents = list("synthflesh" = 1)
required_catalysts = list("nutriment" = 0.1)
//FermiChem vars:
OptimalTempMin = 305 // Lower area of bell curve for determining heat based rate reactions
@@ -601,63 +601,34 @@
/datum/design/retractor_adv
name = "Advanced Retractor"
desc = "A high-class, premium retractor, featuring precision crafted, silver-plated hook-ends and an electrum handle."
desc = "An almagation of rods and gears, able to function as both a surgical clamp and retractor. "
id = "retractor_adv"
build_type = PROTOLATHE
materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 1500, MAT_GOLD = 1000)
build_path = /obj/item/retractor/adv
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/hemostat_adv
name = "Advanced Hemostat"
desc = "An exceptionally fine pair of arterial forceps. These appear to be plated in electrum and feel soft to the touch."
id = "hemostat_adv"
build_type = PROTOLATHE
materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 1000, MAT_GOLD = 1500)
build_path = /obj/item/hemostat/adv
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/cautery_adv
name = "Electrocautery" //This is based on real-life science.
desc = "A high-tech unipolar Electrocauter. This tiny device contains an extremely powerful microbattery that uses arcs of electricity to painlessly sear wounds shut. It seems to recharge with the user's body-heat. Wow!"
id = "cautery_adv"
build_type = PROTOLATHE
materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 1000, MAT_GOLD = 1500)
build_path = /obj/item/cautery/adv
build_path = /obj/item/retractor/advanced
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/surgicaldrill_adv
name = "Surgical Autodrill"
desc = "With a diamond tip and built-in depth and safety sensors, this drill alerts the user before overpenetrating a patient's skull or tooth. There also appears to be a disable switch."
name = "Surgical Laser Drill"
desc = "It projects a high power laser used for medical applications."
id = "surgicaldrill_adv"
build_type = PROTOLATHE
materials = list(MAT_METAL = 2500, MAT_GLASS = 2500, MAT_SILVER = 6000, MAT_GOLD = 5500, MAT_DIAMOND = 3500)
build_path = /obj/item/surgicaldrill/adv
build_path = /obj/item/surgicaldrill/advanced
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/scalpel_adv
name = "Precision Scalpel"
desc = "A perfectly balanced electrum scalpel with a silicon-coated edge to eliminate wear and tear."
name = "Laser Scalpel"
desc = "An advanced scalpel which uses laser technology to cut."
id = "scalpel_adv"
build_type = PROTOLATHE
materials = list(MAT_METAL = 1500, MAT_GLASS = 1500, MAT_SILVER = 4000, MAT_GOLD = 2500)
build_path = /obj/item/scalpel/adv
build_path = /obj/item/scalpel/advanced
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/circular_saw_adv
name = "Diamond-Grit Circular Saw"
desc = "For those Assistants with REALLY thick skulls."
id = "circular_saw_adv"
build_type = PROTOLATHE
materials = list(MAT_METAL = 7500, MAT_GLASS = 6000, MAT_SILVER = 6500, MAT_GOLD = 7500, MAT_DIAMOND = 4500)
build_path = /obj/item/circular_saw/adv
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
/////////////////////////////////////////
//////////Alien Surgery Tools////////////
@@ -756,7 +727,7 @@
research_icon = 'icons/obj/surgery.dmi'
research_icon_state = "surgery_any"
var/surgery
/datum/design/surgery/experimental_dissection
name = "Experimental Dissection"
desc = "A surgical procedure which deeply analyzes the biology of a corpse, and automatically adds new findings to the research database."
+1 -1
View File
@@ -96,7 +96,7 @@
display_name = "Advanced Surgery Tools"
description = "Refined and improved redesigns for the run-of-the-mill medical utensils."
prereq_ids = list("adv_biotech", "adv_surgery")
design_ids = list("drapes", "retractor_adv", "hemostat_adv", "cautery_adv", "surgicaldrill_adv", "scalpel_adv", "circular_saw_adv")
design_ids = list("drapes", "retractor_adv", "surgicaldrill_adv", "scalpel_adv")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -325,7 +325,7 @@
if(SLIME_ACTIVATE_MAJOR)
var/turf/open/T = get_turf(user)
if(istype(T))
T.atmos_spawn_air("nitrogen=40;TEMP=2.7")
T.atmos_spawn_air("n2=40;TEMP=2.7")
to_chat(user, "<span class='warning'>You activate [src], and icy air bursts out of your skin!</span>")
return 900
@@ -681,7 +681,7 @@
var/list/candidates = pollCandidatesForMob("Do you want to play as [SM.name]?", ROLE_SENTIENCE, null, ROLE_SENTIENCE, 50, SM, POLL_IGNORE_SENTIENCE_POTION) // see poll_ignore.dm
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
SM.key = C.key
C.transfer_ckey(SM, FALSE)
SM.mind.enslave_mind_to_creator(user)
SM.sentience_act()
to_chat(SM, "<span class='warning'>All at once it makes sense: you know what you are and who you are! Self awareness is yours!</span>")
@@ -705,7 +705,7 @@
desc = "A miraculous chemical mix that grants human like intelligence to living beings. It has been modified with Syndicate technology to also grant an internal radio implant to the target and authenticate with identification systems."
/obj/item/slimepotion/slime/sentience/nuclear/after_success(mob/living/user, mob/living/simple_animal/SM)
var/obj/item/implant/radio/syndicate/imp = new(src)
var/obj/item/implant/radio/syndicate/imp = new
imp.implant(SM, user)
SM.access_card = new /obj/item/card/id/syndicate(SM)
@@ -969,7 +969,7 @@
to_chat(user, "<span class='notice'>You feed the potion to [M].</span>")
to_chat(M, "<span class='notice'>Your mind tingles as you are fed the potion. You can hear radio waves now!</span>")
var/obj/item/implant/radio/slime/imp = new(src)
var/obj/item/implant/radio/slime/imp = new
imp.implant(M, user)
qdel(src)
@@ -70,12 +70,12 @@ Also, you never added distance checking after target is selected. I've went ahea
var/mob/living/caster = user//The wizard/whomever doing the body transferring.
//MIND TRANSFER BEGIN
var/mob/dead/observer/ghost = victim.ghostize(0)
var/mob/dead/observer/ghost = victim.ghostize(FALSE, TRUE)
caster.mind.transfer_to(victim)
ghost.mind.transfer_to(caster)
if(ghost.key)
caster.key = ghost.key //have to transfer the key since the mind was not active
ghost.transfer_ckey(caster) //have to transfer the key since the mind was not active
qdel(ghost)
//MIND TRANSFER END
@@ -20,7 +20,7 @@
/datum/surgery_step/dissection
name = "dissection"
implements = list(/obj/item/scalpel = 60, /obj/item/kitchen/knife = 30, /obj/item/shard = 15)
implements = list(TOOL_SCALPEL = 60, /obj/item/kitchen/knife = 30, /obj/item/shard = 15)
time = 125
/datum/surgery_step/dissection/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -12,7 +12,7 @@
/datum/surgery_step/clamp_bleeders,
/datum/surgery_step/brainwash,
/datum/surgery_step/close)
species = list(/mob/living/carbon/human)
possible_locs = list(BODY_ZONE_HEAD)
/datum/surgery/advanced/brainwashing/can_start(mob/user, mob/living/carbon/target)
@@ -24,7 +24,7 @@
return TRUE
/datum/surgery_step/brainwash
name = "brainwash"
implements = list(/obj/item/hemostat = 85, TOOL_WIRECUTTER = 50, /obj/item/stack/packageWrap = 35, /obj/item/stack/cable_coil = 15)
implements = list(TOOL_HEMOSTAT = 85, TOOL_WIRECUTTER = 50, /obj/item/stack/packageWrap = 35, /obj/item/stack/cable_coil = 15)
time = 200
var/objective
/datum/surgery_step/brainwash/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+1 -1
View File
@@ -21,7 +21,7 @@
return TRUE
/datum/surgery_step/lobotomize
name = "perform lobotomy"
implements = list(/obj/item/scalpel = 85, /obj/item/melee/transforming/energy/sword = 55, /obj/item/kitchen/knife = 35,
implements = list(TOOL_SCALPEL = 85, /obj/item/melee/transforming/energy/sword = 55, /obj/item/kitchen/knife = 35,
/obj/item/shard = 25, /obj/item = 20)
time = 100
/datum/surgery_step/lobotomize/tool_check(mob/user, obj/item/tool)
@@ -16,7 +16,7 @@
/datum/surgery_step/bionecrosis
name = "start bionecrosis"
implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
implements = list(/obj/item/reagent_containers/syringe = 100, /obj/item/pen = 30)
time = 50
chems_needed = list("zombiepowder", "rezadone")
@@ -17,7 +17,7 @@
return FALSE
/datum/surgery_step/pacify
name = "rewire brain"
implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
time = 40
/datum/surgery_step/pacify/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -37,4 +37,4 @@
"<span class='warning'>[user] screws up, causing brain damage!</span>",
"[user] completes the surgery on [target]'s brain.")
target.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_LOBOTOMY)
return FALSE
return FALSE
@@ -17,7 +17,7 @@
/datum/surgery_step/reconstruct
name = "repair body"
implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
repeatable = TRUE
time = 25
@@ -1,6 +1,6 @@
/datum/surgery/advanced/toxichealing
name = "Body Rejuvenation"
desc = "A surgical procedure that helps deal with oxygen deprecation, and treat toxic damaged. Works on corpses and alive alike without chemicals."
desc = "A surgical procedure that helps deal with oxygen deprivation, and treats parts damaged due to toxic compounds. Works on corpses and alive alike without chemicals."
steps = list(/datum/surgery_step/incise,
/datum/surgery_step/incise,
/datum/surgery_step/retract_skin,
@@ -17,7 +17,7 @@
/datum/surgery_step/toxichealing
name = "rejuvenate body"
implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
repeatable = TRUE
time = 25
@@ -17,7 +17,7 @@
return TRUE
/datum/surgery_step/viral_bond
name = "viral bond"
implements = list(/obj/item/cautery = 100, TOOL_WELDER = 50, /obj/item = 30) // 30% success with any hot item.
implements = list(TOOL_CAUTERY = 100, TOOL_WELDER = 50, /obj/item = 30) // 30% success with any hot item.
time = 100
chems_needed = list("spaceacillin","virusfood","formaldehyde")
+1 -1
View File
@@ -6,7 +6,7 @@
requires_bodypart_type = 0
/datum/surgery_step/sever_limb
name = "sever limb"
implements = list(/obj/item/scalpel = 100, /obj/item/circular_saw = 100, /obj/item/melee/transforming/energy/sword/cyborg/saw = 100, /obj/item/melee/arm_blade = 80, /obj/item/twohanded/required/chainsaw = 80, /obj/item/mounted_chainsaw = 80, /obj/item/twohanded/fireaxe = 50, /obj/item/hatchet = 40, /obj/item/kitchen/knife/butcher = 25)
implements = list(TOOL_SCALPEL = 100, TOOL_SAW = 100, /obj/item/melee/transforming/energy/sword/cyborg/saw = 100, /obj/item/melee/arm_blade = 80, /obj/item/twohanded/required/chainsaw = 80, /obj/item/mounted_chainsaw = 80, /obj/item/twohanded/fireaxe = 50, /obj/item/hatchet = 40, /obj/item/kitchen/knife/butcher = 25)
time = 64
/datum/surgery_step/sever_limb/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+1 -1
View File
@@ -12,7 +12,7 @@
requires_bodypart_type = 0
/datum/surgery_step/fix_brain
name = "fix brain"
implements = list(/obj/item/hemostat = 85, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15) //don't worry, pouring some alcohol on their open brain will get that chance to 100
implements = list(TOOL_HEMOSTAT = 85, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15) //don't worry, pouring some alcohol on their open brain will get that chance to 100
time = 120 //long and complicated
/datum/surgery/brain_surgery/can_start(mob/user, mob/living/carbon/target)
var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN)
+1 -1
View File
@@ -11,7 +11,7 @@
//extract brain
/datum/surgery_step/extract_core
name = "extract core"
implements = list(/obj/item/hemostat = 100, TOOL_CROWBAR = 100)
implements = list(TOOL_HEMOSTAT = 100, TOOL_CROWBAR = 100)
time = 16
/datum/surgery_step/extract_core/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+2 -2
View File
@@ -1,6 +1,6 @@
/datum/surgery/embalming //Fast and easy way to husk bodys
name = "Embalming"
desc = "A surgical procedure that prevents a corps from producing."
desc = "A surgical procedure that prevents a corpse from producing miasma."
steps = list(/datum/surgery_step/incise,
/datum/surgery_step/embalming,
/datum/surgery_step/close)
@@ -11,7 +11,7 @@
/datum/surgery_step/embalming
name = "embalming body"
implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
implements = list(/obj/item/reagent_containers/syringe = 100, /obj/item/pen = 30)
time = 10
chems_needed = list("drying_agent", "sterilizine")

Some files were not shown because too many files have changed in this diff Show More