Merge branch 'master' into access-clarifications
This commit is contained in:
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -35,8 +35,9 @@
|
||||
H.dna.features["spines"] = pick(GLOB.spines_list)
|
||||
H.dna.features["body_markings"] = pick(GLOB.body_markings_list)
|
||||
H.dna.features["insect_wings"] = pick(GLOB.insect_wings_list)
|
||||
H.dna.features["deco_wings"] = pick(GLOB.deco_wings_list)
|
||||
H.dna.features["insect_fluff"] = pick(GLOB.insect_fluffs_list)
|
||||
|
||||
H.update_body()
|
||||
H.update_hair()
|
||||
H.update_body_parts()
|
||||
H.update_body_parts()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -413,9 +413,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
dat += "CLOSED"
|
||||
else
|
||||
dat += "UNKNOWN"
|
||||
dat += "</b>[GLOB.TAB][TicketHref("Refresh", ref_src)][GLOB.TAB][TicketHref("Re-Title", ref_src, "retitle")]"
|
||||
dat += "</b>[FOURSPACES][TicketHref("Refresh", ref_src)][FOURSPACES][TicketHref("Re-Title", ref_src, "retitle")]"
|
||||
if(state != AHELP_ACTIVE)
|
||||
dat += "[GLOB.TAB][TicketHref("Reopen", ref_src, "reopen")]"
|
||||
dat += "[FOURSPACES][TicketHref("Reopen", ref_src, "reopen")]"
|
||||
dat += "<br><br>Opened at: [GAMETIMESTAMP("hh:mm:ss", closed_at)] (Approx [DisplayTimeText(world.time - opened_at)] ago)"
|
||||
if(closed_at)
|
||||
dat += "<br>Closed at: [GAMETIMESTAMP("hh:mm:ss", closed_at)] (Approx [DisplayTimeText(world.time - closed_at)] ago)"
|
||||
@@ -423,7 +423,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
if(initiator)
|
||||
dat += "<b>Actions:</b> [FullMonty(ref_src)]<br>"
|
||||
else
|
||||
dat += "<b>DISCONNECTED</b>[GLOB.TAB][ClosureLinks(ref_src)]<br>"
|
||||
dat += "<b>DISCONNECTED</b>[FOURSPACES][ClosureLinks(ref_src)]<br>"
|
||||
dat += "<br><b>Log:</b><br><br>"
|
||||
for(var/I in _interactions)
|
||||
dat += "[I]<br>"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
@@ -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>")
|
||||
|
||||
|
||||
@@ -539,10 +539,10 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
|
||||
var/list/parts = list()
|
||||
parts += "The devil's true name is: [truename]"
|
||||
parts += "The devil's bans were:"
|
||||
parts += "[GLOB.TAB][GLOB.lawlorify[LORE][ban]]"
|
||||
parts += "[GLOB.TAB][GLOB.lawlorify[LORE][bane]]"
|
||||
parts += "[GLOB.TAB][GLOB.lawlorify[LORE][obligation]]"
|
||||
parts += "[GLOB.TAB][GLOB.lawlorify[LORE][banish]]"
|
||||
parts += "[FOURSPACES][GLOB.lawlorify[LORE][ban]]"
|
||||
parts += "[FOURSPACES][GLOB.lawlorify[LORE][bane]]"
|
||||
parts += "[FOURSPACES][GLOB.lawlorify[LORE][obligation]]"
|
||||
parts += "[FOURSPACES][GLOB.lawlorify[LORE][banish]]"
|
||||
return parts.Join("<br>")
|
||||
|
||||
/datum/antagonist/devil/roundend_report()
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
disease_flags = CURABLE
|
||||
permeability_mod = 1
|
||||
severity = DISEASE_SEVERITY_HARMFUL
|
||||
var/stagedamage = 0 //Highest stage reached.
|
||||
severity = DISEASE_SEVERITY_DANGEROUS
|
||||
var/finalstage = 0 //Because we're spawning off the cure in the final stage, we need to check if we've done the final stage's effects.
|
||||
var/datum/mood_event/revenant_blight/depression
|
||||
|
||||
/datum/disease/revblight/cure()
|
||||
if(affected_mob)
|
||||
@@ -21,12 +21,13 @@
|
||||
if(affected_mob.dna && affected_mob.dna.species)
|
||||
affected_mob.dna.species.handle_mutant_bodyparts(affected_mob)
|
||||
affected_mob.dna.species.handle_hair(affected_mob)
|
||||
to_chat(affected_mob, "<span class='notice'>You feel better.</span>")
|
||||
SEND_SIGNAL(affected_mob, COMSIG_CLEAR_MOOD_EVENT, "rev_blight")
|
||||
..()
|
||||
|
||||
/datum/disease/revblight/stage_act()
|
||||
if(!finalstage)
|
||||
if(affected_mob.lying && prob(stage*6))
|
||||
if(affected_mob.lying && prob(stage*4))
|
||||
to_chat(affected_mob, "<span class='notice'>You feel better.</span>")
|
||||
cure()
|
||||
return
|
||||
if(prob(stage*3))
|
||||
@@ -34,10 +35,6 @@
|
||||
affected_mob.confused += 8
|
||||
affected_mob.adjustStaminaLoss(8)
|
||||
new /obj/effect/temp_visual/revenant(affected_mob.loc)
|
||||
if(stagedamage < stage)
|
||||
stagedamage++
|
||||
affected_mob.adjustToxLoss(stage*2) //should, normally, do about 30 toxin damage.
|
||||
new /obj/effect/temp_visual/revenant(affected_mob.loc)
|
||||
if(prob(45))
|
||||
affected_mob.adjustStaminaLoss(stage)
|
||||
..() //So we don't increase a stage before applying the stage damage.
|
||||
@@ -46,9 +43,13 @@
|
||||
if(prob(5))
|
||||
affected_mob.emote("pale")
|
||||
if(3)
|
||||
if(!depression)
|
||||
depression = SEND_SIGNAL(affected_mob, COMSIG_ADD_MOOD_EVENT, "rev_blight", /datum/mood_event/revenant_blight)
|
||||
SEND_SIGNAL(affected_mob, COMSIG_DECREASE_SANITY, 0.12, SANITY_CRAZY)
|
||||
if(prob(10))
|
||||
affected_mob.emote(pick("pale","shiver"))
|
||||
if(4)
|
||||
SEND_SIGNAL(affected_mob, COMSIG_DECREASE_SANITY, 0.18, SANITY_CRAZY)
|
||||
if(prob(15))
|
||||
affected_mob.emote(pick("pale","shiver","cries"))
|
||||
if(5)
|
||||
@@ -56,12 +57,18 @@
|
||||
finalstage = TRUE
|
||||
to_chat(affected_mob, "<span class='revenbignotice'>You feel like [pick("nothing's worth it anymore", "nobody ever needed your help", "nothing you did mattered", "everything you tried to do was worthless")].</span>")
|
||||
affected_mob.adjustStaminaLoss(45)
|
||||
new /obj/effect/temp_visual/revenant(affected_mob.loc)
|
||||
if(affected_mob.dna && affected_mob.dna.species)
|
||||
if(affected_mob.dna?.species)
|
||||
affected_mob.dna.species.handle_mutant_bodyparts(affected_mob,"#1d2953")
|
||||
affected_mob.dna.species.handle_hair(affected_mob,"#1d2953")
|
||||
affected_mob.visible_message("<span class='warning'>[affected_mob] looks terrifyingly gaunt...</span>", "<span class='revennotice'>You suddenly feel like your skin is <i>wrong</i>...</span>")
|
||||
affected_mob.add_atom_colour("#1d2953", TEMPORARY_COLOUR_PRIORITY)
|
||||
addtimer(CALLBACK(src, .proc/cure), 100)
|
||||
else
|
||||
return
|
||||
new /obj/effect/temp_visual/revenant(affected_mob.loc)
|
||||
addtimer(CALLBACK(src, .proc/curses), 150)
|
||||
|
||||
/datum/disease/revblight/proc/curses()
|
||||
if(QDELETED(affected_mob))
|
||||
return
|
||||
affected_mob.playsound_local(affected_mob, 'sound/effects/curse5.ogg', 40, 1, -1)
|
||||
to_chat(affected_mob, "<span class='revendanger'>You sense the terrific curse of a vengeful ghost befall upon you...</span>")
|
||||
affected_mob.apply_necropolis_curse(null, 7 MINUTES) //Once the blight has done its course without being cured beforehand, it will cast a necrocurse to compensate how underpowered it's.
|
||||
cure()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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!"
|
||||
|
||||
@@ -95,6 +95,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
"ears" = "None",
|
||||
"wings" = "None",
|
||||
"frills" = "None",
|
||||
"deco_wings" = "None",
|
||||
"spines" = "None",
|
||||
"body_markings" = "None",
|
||||
"legs" = "Plantigrade",
|
||||
@@ -583,6 +584,13 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(mutant_category >= MAX_MUTANT_ROWS)
|
||||
dat += "</td>"
|
||||
mutant_category = 0
|
||||
if("deco_wings" in pref_species.default_features)
|
||||
if(!mutant_category)
|
||||
dat += APPEARANCE_CATEGORY_COLUMN
|
||||
|
||||
dat += "<h3>Decorative wings</h3>"
|
||||
|
||||
dat += "<a style='display:block;width:100px' href='?_src_=prefs;preference=deco_wings;task=input'>[features["deco_wings"]]</a>"
|
||||
if("insect_wings" in pref_species.default_features)
|
||||
if(!mutant_category)
|
||||
dat += APPEARANCE_CATEGORY_COLUMN
|
||||
@@ -1722,7 +1730,13 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
new_insect_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.insect_wings_list
|
||||
if(new_insect_wings)
|
||||
features["insect_wings"] = new_insect_wings
|
||||
|
||||
|
||||
if("deco_wings")
|
||||
var/new_deco_wings
|
||||
new_deco_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.deco_wings_list
|
||||
if(new_deco_wings)
|
||||
features["deco_wings"] = new_deco_wings
|
||||
|
||||
if("insect_fluffs")
|
||||
var/new_insect_fluff
|
||||
new_insect_fluff = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.insect_fluffs_list
|
||||
|
||||
@@ -352,6 +352,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["feature_human_tail"] >> features["tail_human"]
|
||||
S["feature_human_ears"] >> features["ears"]
|
||||
S["feature_insect_wings"] >> features["insect_wings"]
|
||||
S["feature_deco_wings"] >> features["deco_wings"]
|
||||
S["feature_insect_fluff"] >> features["insect_fluff"]
|
||||
|
||||
//Custom names
|
||||
@@ -484,6 +485,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
features["body_markings"] = sanitize_inlist(features["body_markings"], GLOB.body_markings_list)
|
||||
features["feature_lizard_legs"] = sanitize_inlist(features["legs"], GLOB.legs_list)
|
||||
features["insect_wings"] = sanitize_inlist(features["insect_wings"], GLOB.insect_wings_list)
|
||||
features["deco_wings"] = sanitize_inlist(features["deco_wings"], GLOB.deco_wings_list)
|
||||
features["insect_fluff"] = sanitize_inlist(features["insect_fluff"], GLOB.insect_fluffs_list)
|
||||
|
||||
joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole))
|
||||
@@ -553,6 +555,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["feature_lizard_body_markings"] , features["body_markings"])
|
||||
WRITE_FILE(S["feature_lizard_legs"] , features["legs"])
|
||||
WRITE_FILE(S["feature_insect_wings"] , features["insect_wings"])
|
||||
WRITE_FILE(S["feature_deco_wings"] , features["deco_wings"])
|
||||
WRITE_FILE(S["feature_insect_fluff"] , features["insect_fluff"])
|
||||
WRITE_FILE(S["feature_meat"] , features["meat_type"])
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -324,6 +324,23 @@
|
||||
item_state = "officertanjacket"
|
||||
body_parts_covered = CHEST|ARMS
|
||||
|
||||
/obj/item/clothing/suit/ran
|
||||
name = "Shikigami costume"
|
||||
desc = "A costume that looks like a certain shikigami, is super fluffy."
|
||||
icon_state = "ran_suit"
|
||||
item_state = "ran_suit"
|
||||
body_parts_covered = CHEST|GROIN|LEGS
|
||||
flags_inv = HIDEJUMPSUIT|HIDETAUR
|
||||
heat_protection = CHEST|GROIN|LEGS //fluffy tails!
|
||||
//2061
|
||||
|
||||
/obj/item/clothing/head/ran
|
||||
name = "Shikigami hat"
|
||||
desc = "A hat that looks like it keeps any fluffy ears contained super warm, has little charms over it."
|
||||
icon_state = "ran_hat"
|
||||
item_state = "ran_hat"
|
||||
flags_inv = HIDEEARS
|
||||
|
||||
/*
|
||||
* Misc
|
||||
*/
|
||||
|
||||
@@ -355,6 +355,14 @@
|
||||
above_suit = TRUE
|
||||
armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 20, "bio" = 20, "rad" = 5, "fire" = 0, "acid" = 25)
|
||||
|
||||
/obj/item/clothing/accessory/skullcodpiece/fake
|
||||
name = "false codpiece"
|
||||
desc = "A plastic ornament, intended to protect the important things in life. It's not very good at it."
|
||||
icon_state = "skull"
|
||||
item_color = "skull"
|
||||
above_suit = TRUE
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
|
||||
/////////////////////
|
||||
//Synda Accessories//
|
||||
/////////////////////
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
new /mob/living/simple_animal/parrot/Poly/ghost(Poly.loc)
|
||||
qdel(Poly)
|
||||
|
||||
|
||||
/datum/round_event/spooky/announce(fake)
|
||||
priority_announce(pick("RATTLE ME BONES!","THE RIDE NEVER ENDS!", "A SKELETON POPS OUT!", "SPOOKY SCARY SKELETONS!", "CREWMEMBERS BEWARE, YOU'RE IN FOR A SCARE!") , "THE CALL IS COMING FROM INSIDE THE HOUSE")
|
||||
|
||||
|
||||
@@ -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,5 +1,8 @@
|
||||
// Normal strength
|
||||
|
||||
#define SINGULO_BEACON_DISTURBANCE 0.2 //singularity beacon also improve the odds of meteor waves and speed them up a little.
|
||||
#define SINGULO_BEACON_MAX_DISTURBANCE 0.6 //maximum cap due to how meteor waves can be potentially round ending.
|
||||
|
||||
/datum/round_event_control/meteor_wave
|
||||
name = "Meteor Wave: Normal"
|
||||
typepath = /datum/round_event/meteor_wave
|
||||
@@ -18,6 +21,8 @@
|
||||
/datum/round_event/meteor_wave/setup()
|
||||
announceWhen = 1
|
||||
startWhen = rand(300, 600) //Yeah for SOME REASON this is measured in seconds and not deciseconds???
|
||||
if(GLOB.singularity_counter)
|
||||
startWhen *= 1 - min(GLOB.singularity_counter * SINGULO_BEACON_DISTURBANCE, SINGULO_BEACON_MAX_DISTURBANCE)
|
||||
endWhen = startWhen + 60
|
||||
|
||||
|
||||
@@ -52,7 +57,7 @@
|
||||
kill()
|
||||
|
||||
/datum/round_event/meteor_wave/announce(fake)
|
||||
priority_announce("Meteors have been detected on collision course with the station. Estimated time until impact: [round(startWhen/60)] minutes.", "Meteor Alert", 'sound/ai/meteors.ogg')
|
||||
priority_announce("Meteors have been detected on collision course with the station. Estimated time until impact: [round(startWhen/60)] minutes.[GLOB.singularity_counter ? " Warning: Anomalous gravity pulse detected, Syndicate technology interference likely." : ""]", "Meteor Alert", 'sound/ai/meteors.ogg')
|
||||
|
||||
/datum/round_event/meteor_wave/tick()
|
||||
if(ISMULTIPLE(activeFor, 3))
|
||||
@@ -79,3 +84,6 @@
|
||||
|
||||
/datum/round_event/meteor_wave/catastrophic
|
||||
wave_name = "catastrophic"
|
||||
|
||||
#undef SINGULO_BEACON_DISTURBANCE
|
||||
#undef SINGULO_BEACON_MAX_DISTURBANCE
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
spawned_animals++
|
||||
|
||||
SA.key = SG.key
|
||||
SG.transfer_ckey(SA, FALSE)
|
||||
|
||||
SA.grant_all_languages(TRUE)
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -183,8 +183,8 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
|
||||
log_world("\[[time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")]\] Client: [(src.owner.key ? src.owner.key : src.owner)] triggered JS error: [error]")
|
||||
|
||||
//Global chat procs
|
||||
/proc/to_chat(target, message, handle_whitespace=TRUE)
|
||||
if(!target)
|
||||
/proc/to_chat_immediate(target, message, handle_whitespace=TRUE)
|
||||
if(!target || !message)
|
||||
return
|
||||
|
||||
//Ok so I did my best but I accept that some calls to this will be for shit like sound and images
|
||||
@@ -206,7 +206,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
|
||||
message = replacetext(message, "\proper", "")
|
||||
if(handle_whitespace)
|
||||
message = replacetext(message, "\n", "<br>")
|
||||
message = replacetext(message, "\t", "[GLOB.TAB][GLOB.TAB]")
|
||||
message = replacetext(message, "\t", "[FOURSPACES][FOURSPACES]")
|
||||
|
||||
if(islist(target))
|
||||
// Do the double-encoding outside the loop to save nanoseconds
|
||||
@@ -248,3 +248,15 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
|
||||
|
||||
// url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript.
|
||||
C << output(url_encode(url_encode(message)), "browseroutput:output")
|
||||
|
||||
/proc/to_chat(target, message, handle_whitespace = TRUE)
|
||||
if(Master.current_runlevel == RUNLEVEL_INIT || !SSchat?.initialized)
|
||||
to_chat_immediate(target, message, handle_whitespace)
|
||||
return
|
||||
SSchat.queue(target, message, handle_whitespace)
|
||||
|
||||
/datum/chatOutput/proc/swaptolightmode() //Dark mode light mode stuff. Yell at KMC if this breaks! (See darkmode.dm for documentation)
|
||||
owner.force_white_theme()
|
||||
|
||||
/datum/chatOutput/proc/swaptodarkmode()
|
||||
owner.force_dark_theme()
|
||||
|
||||
@@ -401,6 +401,7 @@ h1.alert, h2.alert {color: #000000;}
|
||||
.redtext {color: #FF0000; font-size: 24px;}
|
||||
.clown {color: #FF69Bf; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;}
|
||||
.his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;}
|
||||
.spooky {color: #FF6100;}
|
||||
.velvet {color: #660015; font-weight: bold; animation: velvet 5000ms infinite;}
|
||||
@keyframes velvet {
|
||||
0% { color: #400020; }
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
/obj/effect/landmark/barthpot
|
||||
name = "barthpot"
|
||||
|
||||
/obj/item/barthpot
|
||||
name = "Bartholomew"
|
||||
icon = 'icons/obj/halloween_items.dmi'
|
||||
icon_state = "barthpot"
|
||||
anchored = TRUE
|
||||
var/items_list = list()
|
||||
speech_span = "spooky"
|
||||
var/active = TRUE
|
||||
|
||||
/obj/item/barthpot/Destroy()
|
||||
var/obj/item/barthpot/n = new src(loc)
|
||||
n.items_list = items_list
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/barthpot/attackby(obj/item/I, mob/user, params)
|
||||
if(!active)
|
||||
say("Meow!")
|
||||
return
|
||||
for(var/I2 in items_list)
|
||||
if(istype(I, I2))
|
||||
qdel(I)
|
||||
new /obj/item/reagent_containers/food/snacks/special_candy(loc)
|
||||
to_chat(user, "<span class='notice'>You add the [I.name] to the pot and watch as it melts into the mixture, a candy crystalising in it's wake.</span>")
|
||||
say("Hooray! Thank you!")
|
||||
items_list -= I2
|
||||
return
|
||||
say("It doesn't seem like that's magical enough!")
|
||||
|
||||
/obj/item/barthpot/attack_hand(mob/user)
|
||||
if(!active)
|
||||
say("Meow!")
|
||||
return
|
||||
say("Hello there, I'm Bartholomew, Jacqueline's Familiar.")
|
||||
sleep(20)
|
||||
say("I'm currently seeking items to put into my pot, if we get the right items, it should crystalise into a magic candy!")
|
||||
if(!iscarbon(user))
|
||||
say("Though... I'm not sure you can help me.")
|
||||
|
||||
var/message = "From what I can tell, "
|
||||
if(LAZYLEN(items_list) < 5)
|
||||
generate_items()
|
||||
for(var/I2 in items_list)
|
||||
if(!I2)
|
||||
items_list -= I2
|
||||
continue
|
||||
var/obj/item/I3 = new I2
|
||||
message += "a [I3.name], "
|
||||
message += "currently seem to have the most magic potential."
|
||||
sleep(15)
|
||||
say("[message]")
|
||||
|
||||
/obj/item/barthpot/proc/generate_items()
|
||||
var/length = LAZYLEN(items_list)
|
||||
var/rand_items = list(/obj/item/bodybag = 1,
|
||||
/obj/item/clothing/glasses/meson = 2,
|
||||
/obj/item/clothing/glasses/sunglasses = 1,
|
||||
/obj/item/clothing/gloves/color/fyellow = 1,
|
||||
/obj/item/clothing/head/hardhat = 1,
|
||||
/obj/item/clothing/head/hardhat/red = 1,
|
||||
/obj/item/clothing/head/that = 1,
|
||||
/obj/item/clothing/head/ushanka = 1,
|
||||
/obj/item/clothing/head/welding = 1,
|
||||
/obj/item/clothing/mask/gas = 15,
|
||||
/obj/item/clothing/suit/hazardvest = 1,
|
||||
/obj/item/clothing/under/rank/vice = 1,
|
||||
/obj/item/clothing/suit/hooded/flashsuit = 2,
|
||||
/obj/item/clothing/accessory/medal/greytide = 1,
|
||||
/obj/item/assembly/prox_sensor = 4,
|
||||
/obj/item/assembly/timer = 3,
|
||||
/obj/item/flashlight = 4,
|
||||
/obj/item/flashlight/pen = 1,
|
||||
/obj/effect/spawner/lootdrop/glowstick = 4,
|
||||
/obj/effect/spawner/lootdrop/mre = 3,
|
||||
/obj/item/multitool = 2,
|
||||
/obj/item/radio/off = 2,
|
||||
/obj/item/t_scanner = 5,
|
||||
/obj/item/airlock_painter = 1,
|
||||
/obj/item/stack/cable_coil/ = 4,
|
||||
/obj/item/stack/medical/bruise_pack = 1,
|
||||
/obj/item/stack/rods = 3,
|
||||
/obj/item/stack/sheet/cardboard = 2,
|
||||
/obj/item/stack/sheet/metal = 1,
|
||||
/obj/item/stack/sheet/mineral/plasma = 1,
|
||||
/obj/item/stack/sheet/rglass = 1,
|
||||
/obj/item/book/manual/wiki/engineering_construction = 1,
|
||||
/obj/item/book/manual/wiki/engineering_hacking = 1,
|
||||
/obj/item/clothing/head/cone = 1,
|
||||
/obj/item/coin/silver = 1,
|
||||
/obj/item/coin/twoheaded = 1,
|
||||
/obj/item/poster/random_contraband = 1,
|
||||
/obj/item/poster/random_official = 1,
|
||||
/obj/item/crowbar = 1,
|
||||
/obj/item/crowbar/red = 1,
|
||||
/obj/item/extinguisher = 11,
|
||||
/obj/item/hand_labeler = 1,
|
||||
/obj/item/paper/crumpled = 1,
|
||||
/obj/item/pen = 1,
|
||||
/obj/item/reagent_containers/spray/pestspray = 1,
|
||||
/obj/item/reagent_containers/rag = 3,
|
||||
/obj/item/stock_parts/cell = 3,
|
||||
/obj/item/storage/belt/utility = 2,
|
||||
/obj/item/storage/box = 2,
|
||||
/obj/item/storage/box/cups = 1,
|
||||
/obj/item/storage/box/donkpockets = 1,
|
||||
/obj/item/storage/box/lights/mixed = 3,
|
||||
/obj/item/storage/box/hug/medical = 1,
|
||||
/obj/item/storage/fancy/cigarettes/dromedaryco = 1,
|
||||
/obj/item/storage/toolbox/mechanical = 1,
|
||||
/obj/item/screwdriver = 3,
|
||||
/obj/item/tank/internals/emergency_oxygen = 2,
|
||||
/obj/item/vending_refill/cola = 1,
|
||||
/obj/item/weldingtool = 3,
|
||||
/obj/item/wirecutters = 1,
|
||||
/obj/item/wrench = 4,
|
||||
/obj/item/relic = 3,
|
||||
/obj/item/weaponcrafting/receiver = 2,
|
||||
/obj/item/clothing/head/cone = 2,
|
||||
/obj/item/grenade/smokebomb = 2,
|
||||
/obj/item/geiger_counter = 3,
|
||||
/obj/item/reagent_containers/food/snacks/grown/citrus/orange = 1,
|
||||
/obj/item/radio/headset = 1,
|
||||
/obj/item/assembly/infra = 1,
|
||||
/obj/item/assembly/igniter = 2,
|
||||
/obj/item/assembly/signaler = 2,
|
||||
/obj/item/assembly/mousetrap = 2,
|
||||
/obj/item/reagent_containers/syringe = 2,
|
||||
/obj/item/clothing/gloves = 8,
|
||||
/obj/item/clothing/shoes/laceup = 1,
|
||||
/obj/item/storage/secure/briefcase = 3,
|
||||
/obj/item/storage/toolbox/artistic = 2,
|
||||
/obj/item/toy/eightball = 1,
|
||||
/obj/item/reagent_containers/pill/floorpill = 1,
|
||||
/obj/item/reagent_containers/food/snacks/cannedpeaches/maint = 2,
|
||||
/obj/item/clothing/shoes = 2)
|
||||
if(length == 5)
|
||||
return TRUE
|
||||
//var/metalist = pickweight(GLOB.maintenance_loot)
|
||||
for(var/i = length, i <= 5, i+=1)
|
||||
var/obj/item = pickweight(rand_items)
|
||||
if(!item)
|
||||
i-=1
|
||||
continue
|
||||
items_list += item
|
||||
return TRUE
|
||||
@@ -5,19 +5,27 @@
|
||||
|
||||
//spooky recipes
|
||||
|
||||
/datum/recipe/sugarcookie/spookyskull
|
||||
reagents = list("flour" = 5, "sugar" = 5, "milk" = 5)
|
||||
items = list(
|
||||
/obj/item/reagent_containers/food/snacks/egg,
|
||||
/datum/crafting_recipe/food/sugarcookie/spookyskull
|
||||
time = 15
|
||||
name = "Sugar cookie"
|
||||
reqs = list(
|
||||
/datum/reagent/consumable/sugar = 5,
|
||||
/obj/item/reagent_containers/food/snacks/pastrybase = 1
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/sugarcookie/spookyskull
|
||||
subcategory = CAT_PASTRY
|
||||
|
||||
/datum/recipe/sugarcookie/spookycoffin
|
||||
reagents = list("flour" = 5, "sugar" = 5, "coffee" = 5)
|
||||
items = list(
|
||||
/obj/item/reagent_containers/food/snacks/egg,
|
||||
/datum/crafting_recipe/food/sugarcookie/spookycoffin
|
||||
time = 15
|
||||
name = "Sugar cookie"
|
||||
reqs = list(
|
||||
/datum/reagent/consumable/sugar = 5,
|
||||
/datum/reagent/consumable/coffee = 5,
|
||||
/obj/item/reagent_containers/food/snacks/pastrybase = 1
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/sugarcookie/spookycoffin
|
||||
subcategory = CAT_PASTRY
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
//Spookoween trapped closets//
|
||||
@@ -34,12 +42,12 @@
|
||||
var/trapped = 0
|
||||
var/mob/trapped_mob
|
||||
|
||||
/obj/structure/closet/initialize()
|
||||
/obj/structure/closet/Initialize()
|
||||
..()
|
||||
if(prob(30))
|
||||
set_spooky_trap()
|
||||
|
||||
/obj/structure/closet/dump_contents()
|
||||
/obj/structure/closet/dump_contents(var/override = TRUE)
|
||||
..()
|
||||
trigger_spooky_trap()
|
||||
|
||||
@@ -256,6 +264,7 @@
|
||||
desc = "A standard miniature energy crossbow that uses a hard-light projector to transform bolts into candy corn. Happy Halloween!"
|
||||
category = "Holiday"
|
||||
item = /obj/item/gun/energy/kinetic_accelerator/crossbow/halloween
|
||||
cost = 12
|
||||
surplus = 0
|
||||
|
||||
/datum/uplink_item/device_tools/emag/hack_o_lantern
|
||||
@@ -0,0 +1,442 @@
|
||||
//Conversation
|
||||
#define JACQ_HELLO (1<<0)
|
||||
#define JACQ_CANDIES (1<<1)
|
||||
#define JACQ_HEAD (1<<2)
|
||||
#define JACQ_FAR (1<<3)
|
||||
#define JACQ_WITCH (1<<4)
|
||||
#define JACQ_EXPELL (1<<5)
|
||||
#define JACQ_DATE (1<<6)
|
||||
|
||||
/////// EVENT
|
||||
/datum/round_event_control/jacqueen
|
||||
name = "Jacqueline's visit"
|
||||
holidayID = "jacqueen"
|
||||
typepath = /datum/round_event/jacqueen
|
||||
weight = -1 //forces it to be called, regardless of weight
|
||||
max_occurrences = 1
|
||||
earliest_start = 0 MINUTES
|
||||
|
||||
/datum/round_event/jacqueen/start()
|
||||
..()
|
||||
|
||||
for(var/mob/living/carbon/human/H in GLOB.carbon_list)
|
||||
playsound(H, 'sound/spookoween/ahaha.ogg', 100, 0.25)
|
||||
|
||||
for(var/obj/effect/landmark/barthpot/bp in GLOB.landmarks_list)
|
||||
new /obj/item/barthpot(bp.loc)
|
||||
new /mob/living/simple_animal/jacq(bp.loc)
|
||||
|
||||
/////// MOBS
|
||||
|
||||
//Whacha doing in here like? Yae wan tae ruin ta magicks?
|
||||
/mob/living/simple_animal/jacq
|
||||
name = "Jacqueline the Pumpqueen"
|
||||
real_name = "Jacqueline"
|
||||
icon = 'icons/obj/halloween_items.dmi'
|
||||
icon_state = "jacqueline"
|
||||
maxHealth = 25
|
||||
health = 25
|
||||
density = FALSE
|
||||
speech_span = "spooky"
|
||||
friendly = "pets"
|
||||
response_help = "chats with"
|
||||
var/last_poof
|
||||
var/progression = list() //Keep track of where people are in the story.
|
||||
var/active = TRUE //Turn this to false to keep normal mob behavour
|
||||
|
||||
/mob/living/simple_animal/jacq/Initialize()
|
||||
..()
|
||||
poof()
|
||||
|
||||
/mob/living/simple_animal/jacq/Life()
|
||||
..()
|
||||
if(!ckey)
|
||||
if((last_poof+4 MINUTES) < world.realtime)
|
||||
poof()
|
||||
|
||||
/mob/living/simple_animal/jacq/Destroy() //I.e invincible
|
||||
visible_message("<b>[src]</b> cackles, <span class='spooky'>\"You'll nae get rid a me that easily!\"</span>")
|
||||
playsound(loc, 'sound/spookoween/ahaha.ogg', 100, 0.25)
|
||||
var/mob/living/simple_animal/jacq/Jacq = new src.type(loc)
|
||||
Jacq.progression = progression
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/jacq/death() //What is alive may never die
|
||||
visible_message("<b>[src]</b> cackles, <span class='spooky'>\"You'll nae get rid a me that easily!\"</span>")
|
||||
playsound(loc, 'sound/spookoween/ahaha.ogg', 100, 0.25)
|
||||
health = 20
|
||||
poof()
|
||||
|
||||
/mob/living/simple_animal/jacq/attack_hand(mob/living/carbon/human/M)
|
||||
if(!active)
|
||||
say("Hello there [gender_check(M)]!")
|
||||
return ..()
|
||||
if(!ckey)
|
||||
canmove = FALSE
|
||||
chit_chat(M)
|
||||
canmove = TRUE
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/jacq/attack_paw(mob/living/carbon/monkey/M)
|
||||
if(!active)
|
||||
say("Hello there [gender_check(M)]!")
|
||||
return ..()
|
||||
if(!ckey)
|
||||
canmove = FALSE
|
||||
chit_chat(M)
|
||||
canmove = TRUE
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/jacq/proc/poof()
|
||||
last_poof = world.realtime
|
||||
var/datum/reagents/R = new/datum/reagents(100)//Hey, just in case.
|
||||
var/datum/effect_system/smoke_spread/chem/s = new()
|
||||
R.add_reagent("secretcatchem", (10))
|
||||
s.set_up(R, 0, loc)
|
||||
s.start()
|
||||
visible_message("<b>[src]</b> disappears in a puff of smoke!")
|
||||
canmove = TRUE
|
||||
|
||||
var/hp_list = list()
|
||||
for(var/obj/machinery/holopad/hp in world)
|
||||
hp_list += hp
|
||||
|
||||
var/obj/machinery/holopad/hp = pick(hp_list)
|
||||
if(forceMove(pick(hp.loc)))
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/jacq/proc/gender_check(mob/living/carbon/C)
|
||||
var/gender = "lamb"
|
||||
if(C)
|
||||
if(C.gender == MALE)
|
||||
gender = "laddie"
|
||||
if(C.gender == FEMALE)
|
||||
gender = "lassie"
|
||||
return gender
|
||||
|
||||
//Ye wee bugger, gerrout of it. Ye've nae tae enjoy reading the code fer mae secrets like.
|
||||
/mob/living/simple_animal/jacq/proc/chit_chat(mob/living/carbon/C)
|
||||
//Very important
|
||||
var/gender = gender_check(C)
|
||||
if(C)
|
||||
if(C.gender == MALE)
|
||||
gender = "laddie"
|
||||
if(C.gender == FEMALE)
|
||||
gender = "lassie"
|
||||
|
||||
if(!progression["[C.real_name]"] || !(progression["[C.real_name]"] & JACQ_HELLO))
|
||||
visible_message("<b>[src]</b> smiles ominously at [C], <span class='spooky'>\"Well halo there [gender]! Ah'm Jacqueline, tae great Pumpqueen, great tae meet ye.\"</span>")
|
||||
sleep(20)
|
||||
visible_message("<b>[src]</b> continues, says, <span class='spooky'>\"Ah'm sure yae well stunned, but ah've got nae taem fer that. Ah'm after the candies around this station. If yae get mae enoof o the wee buggers, Ah'll give ye a treat, or if yae feeling bold, Ah ken trick ye instead.</span>\" giving [C] a wide grin.")
|
||||
if(!progression["[C.real_name]"])
|
||||
progression["[C.real_name]"] = NONE //TO MAKE SURE THAT THE LIST ENTRY EXISTS.
|
||||
|
||||
progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_HELLO
|
||||
|
||||
var/choices = list("Trick", "Treat", "How do I get candies?")
|
||||
var/choice = input(C, "Trick or Treat?", "Trick or Treat?") in choices
|
||||
switch(choice)
|
||||
if("Trick")
|
||||
trick(C)
|
||||
return
|
||||
if("Treat")
|
||||
if(check_candies(C))
|
||||
treat(C, gender)
|
||||
else
|
||||
visible_message("<b>[src]</b> raises an eyebrow, <span class='spooky'>\"You've nae got any candies Ah want! They're the orange round ones, now bugger off an go get em first.\"</span>")
|
||||
return
|
||||
if("How do I get candies?")
|
||||
visible_message("<b>[src]</b> says, <span class='spooky'>\"Gae find my familiar; Bartholomew. Ee's tendin the cauldron which ken bring oot t' magic energy in items scattered aroond. Knowing him, ee's probably gone tae somewhere with books.\"</span>")
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/jacq/proc/treat(mob/living/carbon/C, gender)
|
||||
visible_message("<b>[src]</b> gives off a glowing smile, <span class='spooky'>\"What ken Ah offer ye? I can magic up an object, a potion or a plushie fer ye.\"</span>")
|
||||
var/choices_reward = list("Object - 3 candies", "Potion - 2 candies", "Plushie - 1 candy", "Can I ask you a question instead?")
|
||||
var/choice_reward = input(usr, "Trick or Treat?", "Trick or Treat?") in choices_reward
|
||||
|
||||
//rewards
|
||||
switch(choice_reward)
|
||||
if("Object - 3 candies")
|
||||
if(!take_candies(C, 3))
|
||||
visible_message("<b>[src]</b> raises an eyebrown, <span class='spooky'>\"It's 3 candies per trinket [gender]! Thems the rules!\"</span>")
|
||||
return
|
||||
|
||||
var/new_obj = pick(subtypesof(/obj))
|
||||
//for(var/item in blacklist)
|
||||
// if(new_obj == item)
|
||||
// panic()
|
||||
var/reward = new new_obj(C.loc)
|
||||
C.put_in_hands(reward)
|
||||
visible_message("<b>[src]</b> waves her hands, magicing up a [reward] from thin air, <span class='spooky'>\"There ye are [gender], enjoy! \"</span>")
|
||||
sleep(20)
|
||||
poof()
|
||||
return
|
||||
if("Potion - 2 candies")
|
||||
if(!take_candies(C, 2))
|
||||
visible_message("<b>[src]</b> raises an eyebrow, <span class='spooky'>\"It's 2 candies per potion [gender]! Thems the rules!\"</span>")
|
||||
return
|
||||
|
||||
var/reward = new /obj/item/reagent_containers/potion_container(C.loc)
|
||||
C.put_in_hands(reward)
|
||||
visible_message("<b>[src]</b> waves her hands, magicing up a [reward] from thin air, <span class='spooky'>\"There ye are [gender], enjoy! \"</span>")
|
||||
sleep(20)
|
||||
poof()
|
||||
return
|
||||
if("Plushie - 1 candy")
|
||||
if(!take_candies(C, 1))
|
||||
visible_message("<b>[src]</b> raises an eyebrow, <span class='spooky'>\"It's 1 candy per plushie [gender]! Thems the rules!\"</span>")
|
||||
return
|
||||
|
||||
new /obj/item/toy/plush/random(C.loc)
|
||||
visible_message("<b>[src]</b> waves her hands, magicing up a plushie from thin air, <span class='spooky'>\"There ye are [gender], enjoy! \"</span>")
|
||||
sleep(20)
|
||||
poof()
|
||||
return
|
||||
|
||||
//chitchats!
|
||||
if("Can I ask you a question instead?")
|
||||
var/choices = list()
|
||||
//Figure out where the C is in the story
|
||||
if(!progression["[C.real_name]"]) //I really don't want to get here withoot a hello, but just to be safe
|
||||
progression["[C.real_name]"] = NONE
|
||||
if(!(progression["[C.real_name]"] & JACQ_FAR))
|
||||
if(progression["[C.real_name]"] & JACQ_CANDIES)
|
||||
choices += "You really came all this way for candy?"
|
||||
else
|
||||
choices += "Why do you want the candies?"
|
||||
if(!(progression["[C.real_name]"] & JACQ_HEAD))
|
||||
choices += "What is that on your head?"
|
||||
if(!(progression["[C.real_name]"] & JACQ_EXPELL))
|
||||
if(progression["[C.real_name]"] & JACQ_WITCH)
|
||||
choices += "So you got ex-spell-ed?"
|
||||
else
|
||||
choices += "Are you a witch?"
|
||||
|
||||
//for Kepler, delete this, or just delete the whole story aspect if you want.
|
||||
//If fully completed
|
||||
/*
|
||||
if(progression["[C.real_name]"] & JACQ_FAR)//Damnit this is a pain
|
||||
if(progression["[C.real_name]"] & JACQ_EXPELL) //I give up
|
||||
if(progression["[C.real_name]"] & JACQ_HEAD) //This is only an event thing
|
||||
choices += "Can I take you out on a date?"
|
||||
*/
|
||||
if(progression["[C.real_name]"] == 63)//Damnit this is a pain
|
||||
choices += "Can I take you out on a date?"
|
||||
|
||||
//If you've nothing to ask
|
||||
if(!LAZYLEN(choices))
|
||||
visible_message("<b>[src]</b> sighs, <span class='spooky'>\"Ah'm all questioned oot fer noo, [gender].\"</span>")
|
||||
return
|
||||
//Otherwise, lets go!
|
||||
visible_message("<b>[src]</b> says, <span class='spooky'>\"A question? Sure, it'll cost you a candy though!\"</span>")
|
||||
choices += "Nevermind"
|
||||
//Candies for chitchats
|
||||
var/choice = input(C, "What do you want to ask?", "What do you want to ask?") in choices
|
||||
if(!take_candies(C, 1))
|
||||
visible_message("<b>[src]</b> raises an eyebrow, <span class='spooky'>\"It's a candy per question [gender]! Thems the rules!\"</span>")
|
||||
return
|
||||
//Talking
|
||||
switch(choice)
|
||||
if("Why do you want the candies?")
|
||||
visible_message("<b>[src]</b> says, <span class='spooky'>\"Ave ye tried them? They're full of all sorts of reagents. Ah'm after them so ah ken magic em up an hopefully find rare stuff fer me brews. Honestly it's a lot easier magicking up tatt fer ye lot than runnin aroond on me own like. I'd ask me familiars but most a my familiars are funny fellows 'n constantly bugger off on adventures when given simple objectives like; Go grab me a tea cake or watch over me cauldron. Ah mean, ye might run into Bartholomew my cat. Ee's supposed tae be tending my cauldron, but I've nae idea where ee's got tae.\"</span>")
|
||||
progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_CANDIES
|
||||
sleep(30)
|
||||
poof()
|
||||
|
||||
if("You really came all this way for candy?")
|
||||
visible_message("<b>[src]</b> looks tae the side sheepishly, <span class='spooky'>\"Aye, well, tae be honest, Ah'm here tae see me sis, but dunnae let her knew that. She's an alchemist too like, but she dunnae use a caldron like mae, she buggered off like tae her posh ivory tower tae learn bloody chemistry instead!\"</span> <b>[src]</b> scowls, <span class='spooky'>\"She's tae black sheep o' the family too, so we dunnae see eye tae eye sometimes on alchemy. Ah mean, she puts <i> moles </i> in her brews! Ye dunnae put moles in yer brews! Yae threw your brews at tae wee bastards an blew em up!\"</span> <b>[src]</b> sighs, <span class='spooky'>\"But she's a heart o gold so.. Ah wanted tae see her an check up oon her, make sure she's okay.\"</span>")
|
||||
progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_FAR
|
||||
sleep(30)
|
||||
poof()
|
||||
|
||||
if("What is that on your head?")
|
||||
visible_message("<b>[src]</b> pats the pumpkin atop her head, <span class='spooky'>\"This thing? This ain't nae ordinary pumpkin! Me Ma grew this monster ooer a year o love, dedication an hard work. Honestly it felt like she loved this thing more than any of us, which Ah knew ain't true an it's not like she was hartless or anything but.. well, we had a falling oot when Ah got back home with all me stuff in tow. An all she had done is sent me owl after owl over t' last year aboot this bloody pumpkin and ah had enough. So ah took it, an put it on me head. You know, as ye do. Ah am the great Pumpqueen after all, Ah deserve this.\"</span>")
|
||||
progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_HEAD
|
||||
sleep(30)
|
||||
poof()
|
||||
|
||||
if("Are you a witch?")
|
||||
visible_message("<b>[src]</b> grumbles, <span class='spooky'>\"If ye must know, Ah got kicked oot of the witch academy fer being too much of a \"loose cannon\". A bloody loose cannon? Nae they were just pissed off Ah had the brass tae proclaim myself as the Pumpqueen! And also maybe the time Ah went and blew up one of the towers by trying tae make a huge batch of astrogen might've had something tae do with it. Ah mean it would've worked fine if the cauldrons weren't so shite and were actually upgraded by the faculty. So technically no, I'm not a witch.\"</span>")
|
||||
progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_WITCH
|
||||
sleep(30)
|
||||
poof()
|
||||
|
||||
if("So you got ex-spell-ed?")
|
||||
visible_message("<b>[src]</b> Gives you a blank look at the pun, before continuing, <span class='spooky'>\"Not quite, Ah know Ah ken get back into the academy, it's only an explosion, they happen all the time, but, tae be fair it's my fault that things came tae their explosive climax. You don't know what it's like when you're after a witch doctorate, everyone else is doing well, everyone's making new spells and the like, and I'm just good at making explosions really, or fireworks. So, Ah did something Ah knew was dangerous, because Ah had tae do something tae stand oot, but Ah know this life ain't fer me, Ah don't want tae be locked up in dusty towers, grinding reagent after reagent together, trying tae find new reactions, some of the wizards in there haven't left fer years. Ah want tae live, Ah want tae fly around on a broom, turn people into cats fer a day and disappear cackling! That's what got me into witchcraft!\"</span> she throws her arms up in the arm, spinning the pumpkin upon her head slightly. She carefully spins it back to face you, giving oot a soft sigh, <span class='spooky'>\"Ah know my mother's obsession with this dumb thing on my head is just her trying tae fill the void of me and my sis moving oot, and it really shouldn't be on my head. And Ah know that I'm really here tae get help from my sis.. She's the sensible one, and she gives good hugs.\"</span>")
|
||||
sleep(30)
|
||||
visible_message("<b>[src]</b> says, <span class='spooky'>\"Thanks [C], Ah guess Ah didn't realise Ah needed someone tae talk tae but, I'm glad ye spent all your candies talking tae me. Funny how things seem much worse in yer head.\"</span>")
|
||||
progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_EXPELL
|
||||
sleep(30)
|
||||
poof()
|
||||
|
||||
if("Can I take you out on a date?")
|
||||
visible_message("<b>[src]</b> blushes, <span class='spooky'>\"...You want tae ask me oot on a date? Me? After all that nonsense Ah just said? It seems a waste of a candy honestly.\"</span>")
|
||||
progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_DATE
|
||||
visible_message("<b>[src]</b> looks to the side, deep in thought.</span>")
|
||||
dating_start(C, gender)
|
||||
|
||||
if("Nevermind")
|
||||
visible_message("<b>[src]</b> shrugs, <span class='spooky'>\"Suit yerself then, here's your candy back.\"</span>")
|
||||
new /obj/item/reagent_containers/food/snacks/special_candy(loc)
|
||||
|
||||
|
||||
/mob/living/simple_animal/jacq/proc/trick(mob/living/carbon/C, gender)
|
||||
var/option
|
||||
if(ishuman(C))
|
||||
option = rand(1,7)
|
||||
else
|
||||
option = rand(1,6)
|
||||
switch(option)
|
||||
if(1)
|
||||
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"Hocus pocus, making friends is now your focus!\"</span>")
|
||||
var/datum/objective/brainwashing/objective = pick("Make a tasty sandwich for", "Compose a poem for", "Aquire a nice outfit to give to", "Strike up a conversation about pumpkins with", "Write a letter and deliver it to", "Give a nice hat to")
|
||||
var/mob/living/L2 = pick(GLOB.player_list)
|
||||
objective += " [L2.name]."
|
||||
brainwash(C, objective)
|
||||
if(2)
|
||||
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"Off comes your head, a pumpkin taking it's stead!\"</span>")
|
||||
C.reagents.add_reagent("pumpkinmutationtoxin", 5)
|
||||
if(3)
|
||||
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"If only you had a better upbringing, your ears are now full of my singing!\"</span>")
|
||||
var/client/C2 = C.client
|
||||
C2.chatOutput.sendMusic("https://a.uguu.se/rQ8FxxUQ1Xzc_SpOwOkyOwOkyPumpkinSong-PFrPrIxluWk.mp4", 1)//I hope this works!
|
||||
if(4)
|
||||
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"You're cute little bumpkin, On your head is a pumpkin!\"</span>")
|
||||
if(C.head)
|
||||
var/obj/item/W = C.head
|
||||
C.dropItemToGround(W, TRUE)
|
||||
var/jaqc_latern = new /obj/item/clothing/head/hardhat/pumpkinhead/jaqc
|
||||
C.equip_to_slot(jaqc_latern, SLOT_HEAD, 1, 1)
|
||||
if(5)
|
||||
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"In your body there's something amiss, you'll find it's a chem made by my sis!\"</span>")
|
||||
C.reagents.add_reagent("eigenstate", 30)
|
||||
if(6)
|
||||
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"A new familiar for me, and you'll see it's thee!\"</span>")
|
||||
C.reagents.add_reagent("secretcatchem", 30)
|
||||
if(7)
|
||||
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"While you may not be a ghost, for this sheet you'll always be it's host.\"</span>")
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(H.wear_suit)
|
||||
var/obj/item/W = H.wear_suit
|
||||
H.dropItemToGround(W, TRUE)
|
||||
var/ghost = new /obj/item/clothing/suit/ghost_sheet/sticky
|
||||
H.equip_to_slot(ghost, SLOT_WEAR_SUIT, 1, 1)
|
||||
poof()
|
||||
|
||||
//Blame Fel
|
||||
/mob/living/simple_animal/jacq/proc/dating_start(mob/living/carbon/C, gender)
|
||||
var/candies = pollGhostCandidates("Do you want to go on a date with [C] as Jacqueline the great pumpqueen?")
|
||||
//sleep(30) //If the poll doesn't autopause.
|
||||
if(candies)
|
||||
candies = shuffle(candies)//Shake those ghosts up!
|
||||
for(var/mob/dead/observer/C2 in candies)
|
||||
if(C2.key && C2)
|
||||
key = C2.key
|
||||
message_admins("[C2]/[C2.key] has agreed to go on a date with [C] as Jacqueline.")
|
||||
log_game("HALLOWEEN: [C2]/[C2.key] has agreed to go on a date with [C] as Jacqueline")
|
||||
to_chat(src, "<span class='big spooky'>You are Jacqueline the great pumpqueen, witch Extraordinaire! You're a very Scottish lass with a kind heart, but also a little crazy. You also blew up the wizarding school and you're suspended for a while, so you visited the station before heading home. On your head lies the prize pumpkin of your Mother's pumpkin patch. You're currently on a date with [C] and well, I didn't think anyone would get this far. <i> Please be good so I can do events like this in the future. </i> </span>")
|
||||
return
|
||||
else
|
||||
candies =- C2
|
||||
visible_message("<b>[src]</b> looks to the side, <span class='spooky'>\"Look, Ah like ye but, Ah don't think Ah can right now. If ye can't tell, the stations covered in volatile candies, I've a few other laddies and lassies running after me treats, and tae top it all off, I've the gods breathing down me neck, watching every treat Ah make fer the lot of yous.\" she sighs, \"But that's not a no, right? That's.. just a nae right noo.\"</span>")
|
||||
sleep(20)
|
||||
visible_message("<b>[src]</b> takes off the pumpkin on her head, a rich blush on her cheeks. She leans over planting a kiss upon your forehead quickly befere popping the pumpkin back on her head.")
|
||||
sleep(10)
|
||||
visible_message("<b>[src]</b> waves their arms around, <span class='spooky'>\"There, that aught tae be worth a candy.\"</span>")
|
||||
sleep(20)
|
||||
poof()
|
||||
|
||||
/obj/item/clothing/head/hardhat/pumpkinhead/jaqc
|
||||
name = "Jacq o' latern"
|
||||
desc = "A jacqueline o' lantern! You can't seem to get rid of it."
|
||||
icon_state = "hardhat0_pumpkin_j"
|
||||
item_state = "hardhat0_pumpkin_j"
|
||||
item_color = "pumpkin_j"
|
||||
brightness_on = 4
|
||||
|
||||
/obj/item/clothing/head/hardhat/pumpkinhead/jaqc/Initialize()
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_NODROP, GLUED_ITEM_TRAIT)
|
||||
|
||||
/obj/item/clothing/suit/ghost_sheet/sticky
|
||||
|
||||
/obj/item/clothing/suit/ghost_sheet/sticky/Initialize()
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_NODROP, GLUED_ITEM_TRAIT)
|
||||
|
||||
/obj/item/clothing/suit/ghost_sheet/sticky/attack_hand(mob/user)
|
||||
if(iscarbon(user))
|
||||
to_chat(user, "<span class='spooky'><i>Boooooo~!</i></span>")
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/clothing/suit/ghost_sheet/sticky/attack_hand(mob/user)
|
||||
if(iscarbon(user))
|
||||
to_chat(user, "<span class='spooky'><i>Boooooo~!</i></span>")
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
/datum/reagent/mutationtoxin/pumpkinhead
|
||||
name = "Pumpkin head mutation toxin"
|
||||
id = "pumpkinmutationtoxin"
|
||||
race = /datum/species/dullahan/pumpkin
|
||||
mutationtext = "<span class='spooky'>The pain subsides. You feel your head roll off your shoulders... and you smell pumpkin."
|
||||
//I couldn't get the replace head sprite with a pumpkin to work so, it is what it is.
|
||||
|
||||
/mob/living/simple_animal/jacq/proc/check_candies(mob/living/carbon/C)
|
||||
var/invs = C.get_contents()
|
||||
var/candy_count = 0
|
||||
for(var/item in invs)
|
||||
if(istype(item, /obj/item/reagent_containers/food/snacks/special_candy))
|
||||
candy_count++
|
||||
return candy_count
|
||||
|
||||
/mob/living/simple_animal/jacq/proc/take_candies(mob/living/carbon/C, candy_amount = 1)
|
||||
var/inv = C.get_contents()
|
||||
var/candies = list()
|
||||
for(var/item in inv)
|
||||
if(istype(item, /obj/item/reagent_containers/food/snacks/special_candy))
|
||||
candies += item
|
||||
if(LAZYLEN(candies) == candy_amount)
|
||||
break
|
||||
if(LAZYLEN(candies) == candy_amount) //I know it's a double check but eh, to be safe.
|
||||
for(var/candy in candies)
|
||||
qdel(candy)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//Potions
|
||||
/obj/item/reagent_containers/potion_container
|
||||
name = "potion"
|
||||
icon = 'icons/obj/halloween_items.dmi'
|
||||
icon_state = "jacq_potion"
|
||||
desc = "A potion with a strange concoction within. Be careful, as if it's thrown it explodes in a puff of smoke like Jacqueline."
|
||||
|
||||
/obj/item/reagent_containers/potion_container/Initialize()
|
||||
.=..()
|
||||
var/R = get_random_reagent_id()
|
||||
reagents.add_reagent(R, 30)
|
||||
name = "[R] Potion"
|
||||
|
||||
/obj/item/reagent_containers/potion_container/throw_impact(atom/target)
|
||||
..()
|
||||
sleep(20)
|
||||
var/datum/effect_system/smoke_spread/chem/s = new()
|
||||
s.set_up(src.reagents, 3, src.loc)
|
||||
s.start()
|
||||
qdel(src)
|
||||
|
||||
//Candies
|
||||
/obj/item/reagent_containers/food/snacks/special_candy
|
||||
name = "Magic candy"
|
||||
icon = 'icons/obj/halloween_items.dmi'
|
||||
icon_state = "jacq_candy"
|
||||
desc = "A candy with strange magic within. Be careful, as the magic isn't always helpful."
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/special_candy/Initialize()
|
||||
.=..()
|
||||
reagents.add_reagent(get_random_reagent_id(), 5)
|
||||
@@ -333,6 +333,16 @@
|
||||
/datum/holiday/halloween/getStationPrefix()
|
||||
return pick("Bone-Rattling","Mr. Bones' Own","2SPOOKY","Spooky","Scary","Skeletons")
|
||||
|
||||
/datum/holiday/jacqueen //Subset of halloween
|
||||
name = "jacqueen"
|
||||
begin_day = 27
|
||||
begin_month = OCTOBER
|
||||
end_day = 2
|
||||
end_month = NOVEMBER
|
||||
|
||||
/datum/holiday/jacqueen/greet()
|
||||
return "Jacqueline the great Pumpqueen has come to visit!"
|
||||
|
||||
/datum/holiday/vegan
|
||||
name = "Vegan Day"
|
||||
begin_day = 1
|
||||
|
||||
@@ -111,6 +111,11 @@
|
||||
if(A)
|
||||
load_program(A)
|
||||
if("safety")
|
||||
if(!issilicon(usr) && !IsAdminGhost(usr))
|
||||
var/msg = "[key_name(usr)] attempted to emag the holodeck using a href they shouldn't have!"
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
return
|
||||
obj_flags ^= EMAGGED
|
||||
if((obj_flags & EMAGGED) && program && emag_programs[program.name])
|
||||
emergency_shutdown()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -27,6 +27,88 @@
|
||||
dimension_y = 34
|
||||
locked = TRUE
|
||||
|
||||
// Decorative wings
|
||||
/datum/sprite_accessory/deco_wings
|
||||
icon = 'icons/mob/wings.dmi'
|
||||
|
||||
/datum/sprite_accessory/deco_wings/plain
|
||||
name = "Plain"
|
||||
icon_state = "plain"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/monarch
|
||||
name = "Monarch"
|
||||
icon_state = "monarch"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/luna
|
||||
name = "Luna"
|
||||
icon_state = "luna"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/atlas
|
||||
name = "Atlas"
|
||||
icon_state = "atlas"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/reddish
|
||||
name = "Reddish"
|
||||
icon_state = "redish"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/royal
|
||||
name = "Royal"
|
||||
icon_state = "royal"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/gothic
|
||||
name = "Gothic"
|
||||
icon_state = "gothic"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/lovers
|
||||
name = "Lovers"
|
||||
icon_state = "lovers"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/whitefly
|
||||
name = "White Fly"
|
||||
icon_state = "whitefly"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/punished
|
||||
name = "Burnt Off"
|
||||
icon_state = "punished"
|
||||
locked = TRUE
|
||||
|
||||
/datum/sprite_accessory/deco_wings/firewatch
|
||||
name = "Firewatch"
|
||||
icon_state = "firewatch"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/deathhead
|
||||
name = "Deathshead"
|
||||
icon_state = "deathhead"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/poison
|
||||
name = "Poison"
|
||||
icon_state = "poison"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/ragged
|
||||
name = "Ragged"
|
||||
icon_state = "ragged"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/moonfly
|
||||
name = "Moon Fly"
|
||||
icon_state = "moonfly"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/snow
|
||||
name = "Snow"
|
||||
icon_state = "snow"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/angel
|
||||
name = "Angel"
|
||||
icon_state = "angel"
|
||||
color_src = 0
|
||||
dimension_x = 46
|
||||
center = TRUE
|
||||
dimension_y = 34
|
||||
|
||||
/datum/sprite_accessory/deco_wings/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
|
||||
|
||||
//INSECT WINGS
|
||||
|
||||
/datum/sprite_accessory/insect_wings
|
||||
@@ -76,7 +158,6 @@
|
||||
/datum/sprite_accessory/insect_wings/punished
|
||||
name = "Burnt Off"
|
||||
icon_state = "punished"
|
||||
locked = TRUE
|
||||
|
||||
/datum/sprite_accessory/insect_wings/firewatch
|
||||
name = "Firewatch"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
attack_verb = list("attacked", "slapped", "whacked")
|
||||
///The brain's organ variables are significantly more different than the other organs, with half the decay rate for balance reasons, and twice the maxHealth
|
||||
decay_factor = STANDARD_ORGAN_DECAY / 4 //30 minutes of decaying to result in a fully damaged brain, since a fast decay rate would be unfun gameplay-wise
|
||||
healing_factor = STANDARD_ORGAN_HEALING / 2
|
||||
|
||||
maxHealth = BRAIN_DAMAGE_DEATH
|
||||
low_threshold = 45
|
||||
@@ -42,7 +43,7 @@
|
||||
if(brainmob.mind)
|
||||
brainmob.mind.transfer_to(C)
|
||||
else
|
||||
C.key = brainmob.key
|
||||
brainmob.transfer_ckey(C)
|
||||
|
||||
QDEL_NULL(brainmob)
|
||||
|
||||
@@ -247,11 +248,13 @@
|
||||
to_chat(owner, "<span class='userdanger'>The last spark of life in your brain fizzles out...</span>")
|
||||
owner.death()
|
||||
brain_death = TRUE
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/organ/brain/on_death()
|
||||
if(damage <= BRAIN_DAMAGE_DEATH) //rip
|
||||
brain_death = FALSE
|
||||
applyOrganDamage(maxHealth * decay_factor)
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/organ/brain/applyOrganDamage(var/d, var/maximum = maxHealth)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/obj/item/organ/alien
|
||||
icon_state = "xgibmid2"
|
||||
var/list/alien_powers = list()
|
||||
organ_flags = ORGAN_NO_SPOIL
|
||||
|
||||
/obj/item/organ/alien/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -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
|
||||
. = ..()
|
||||
|
||||
@@ -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
|
||||
@@ -731,6 +761,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
S = GLOB.wings_list[H.dna.features["wings"]]
|
||||
if("wingsopen")
|
||||
S = GLOB.wings_open_list[H.dna.features["wings"]]
|
||||
if("deco_wings")
|
||||
S = GLOB.deco_wings_list[H.dna.features["deco_wings"]]
|
||||
if("legs")
|
||||
S = GLOB.legs_list[H.dna.features["legs"]]
|
||||
if("insect_wings")
|
||||
@@ -782,6 +814,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
bodypart = "snout"
|
||||
if(bodypart == "xenohead")
|
||||
bodypart = "xhead"
|
||||
if(bodypart == "insect_wings" || bodypart == "deco_wings")
|
||||
bodypart = "insect_wings"
|
||||
|
||||
if(S.gender_specific)
|
||||
accessory_overlay.icon_state = "[g]_[bodypart]_[S.icon_state]_[layertext]"
|
||||
@@ -851,6 +885,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 +902,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 +946,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 +985,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 +1396,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)
|
||||
|
||||
@@ -13,9 +13,12 @@
|
||||
blacklisted = TRUE
|
||||
limbs_id = "human"
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/human
|
||||
var/pumpkin = FALSE
|
||||
|
||||
var/obj/item/dullahan_relay/myhead
|
||||
|
||||
/datum/species/dullahan/pumpkin
|
||||
pumpkin = TRUE
|
||||
|
||||
/datum/species/dullahan/check_roundstart_eligible()
|
||||
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
|
||||
@@ -27,11 +30,19 @@
|
||||
H.flags_1 &= ~HEAR_1
|
||||
var/obj/item/bodypart/head/head = H.get_bodypart(BODY_ZONE_HEAD)
|
||||
if(head)
|
||||
if(pumpkin)//Pumpkinhead!
|
||||
head.animal_origin = 100
|
||||
head.icon = 'icons/obj/clothing/hats.dmi'
|
||||
head.icon_state = "hardhat1_pumpkin_j"
|
||||
head.custom_head = TRUE
|
||||
head.drop_limb()
|
||||
head.flags_1 = HEAR_1
|
||||
head.throwforce = 25
|
||||
myhead = new /obj/item/dullahan_relay (head, H)
|
||||
H.put_in_hands(head)
|
||||
var/obj/item/organ/eyes/E = H.getorganslot(ORGAN_SLOT_EYES)
|
||||
for(var/datum/action/item_action/organ_action/OA in E.actions)
|
||||
OA.Trigger()
|
||||
|
||||
/datum/species/dullahan/on_species_loss(mob/living/carbon/human/H)
|
||||
H.flags_1 |= ~HEAR_1
|
||||
@@ -64,7 +75,7 @@
|
||||
|
||||
/obj/item/organ/brain/dullahan
|
||||
decoy_override = TRUE
|
||||
organ_flags = 0
|
||||
organ_flags = ORGAN_NO_SPOIL//Do not decay
|
||||
|
||||
/obj/item/organ/tongue/dullahan
|
||||
zone = "abstract"
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
should_draw_citadel = TRUE
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR)
|
||||
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
|
||||
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "taur", "horns", "legs")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky",
|
||||
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "deco_wings", "taur", "horns", "legs")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "deco_wings" = "None",
|
||||
"mam_body_markings" = "Husky", "taur" = "None", "horns" = "None", "legs" = "Plantigrade", "meat_type" = "Mammalian")
|
||||
attack_verb = "claw"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
|
||||
@@ -581,7 +581,7 @@
|
||||
limbs_id = "cultgolem"
|
||||
sexes = FALSE
|
||||
info_text = "As a <span class='danger'>Runic Golem</span>, you possess eldritch powers granted by the Elder Goddess Nar'Sie."
|
||||
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES) //no mutcolors
|
||||
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES,NOGENITALS,NOAROUSAL) //no mutcolors
|
||||
prefix = "Runic"
|
||||
special_names = null
|
||||
|
||||
@@ -635,7 +635,7 @@
|
||||
say_mod = "clicks"
|
||||
limbs_id = "clockgolem"
|
||||
info_text = "<span class='bold alloy'>As a </span><span class='bold brass'>Clockwork Golem</span><span class='bold alloy'>, you are faster than other types of golems. On death, you will break down into scrap.</span>"
|
||||
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES)
|
||||
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES,NOGENITALS,NOAROUSAL)
|
||||
inherent_biotypes = list(MOB_ROBOTIC, MOB_HUMANOID)
|
||||
armor = 20 //Reinforced, but much less so to allow for fast movement
|
||||
attack_verb = "smash"
|
||||
@@ -691,7 +691,7 @@
|
||||
sexes = FALSE
|
||||
info_text = "As a <span class='danger'>Cloth Golem</span>, you are able to reform yourself after death, provided your remains aren't burned or destroyed. You are, of course, very flammable. \
|
||||
Being made of cloth, your body is magic resistant and faster than that of other golems, but weaker and less resilient."
|
||||
species_traits = list(NOBLOOD,NO_UNDERWEAR) //no mutcolors, and can burn
|
||||
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOGENITALS,NOAROUSAL) //no mutcolors, and can burn
|
||||
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOGUNS)
|
||||
inherent_biotypes = list(MOB_UNDEAD, MOB_HUMANOID)
|
||||
armor = 15 //feels no pain, but not too resistant
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
var/turf/T = H.loc
|
||||
light_amount = min(1,T.get_lumcount()) - 0.5
|
||||
H.nutrition += light_amount * light_nutrition_gain_factor
|
||||
if(H.nutrition > NUTRITION_LEVEL_FULL)
|
||||
H.nutrition = NUTRITION_LEVEL_FULL
|
||||
if(H.nutrition >= NUTRITION_LEVEL_FULL)
|
||||
H.nutrition = NUTRITION_LEVEL_FULL - 1
|
||||
if(light_amount > 0.2) //if there's enough light, heal
|
||||
H.heal_overall_damage(light_bruteheal, light_burnheal)
|
||||
H.adjustToxLoss(-light_toxheal)
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -808,11 +808,18 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
|
||||
switch(href_list["operation"])
|
||||
if("patrol")
|
||||
if(!issilicon(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
|
||||
return TRUE
|
||||
auto_patrol = !auto_patrol
|
||||
bot_reset()
|
||||
if("remote")
|
||||
remote_disabled = !remote_disabled
|
||||
if("hack")
|
||||
if(!issilicon(usr) && !IsAdminGhost(usr))
|
||||
var/msg = "[key_name(usr)] attempted to hack a bot with a href that shouldn't be available!"
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
return TRUE
|
||||
if(emagged != 2)
|
||||
emagged = 2
|
||||
hacked = TRUE
|
||||
@@ -915,7 +922,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
|
||||
|
||||
@@ -131,7 +131,8 @@ Auto Patrol: []"},
|
||||
/mob/living/simple_animal/bot/secbot/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(!issilicon(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
|
||||
return TRUE
|
||||
switch(href_list["operation"])
|
||||
if("idcheck")
|
||||
idcheck = !idcheck
|
||||
|
||||
@@ -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>")
|
||||
|
||||
@@ -52,13 +52,11 @@
|
||||
switch(from.pH)
|
||||
if(11.5 to INFINITY)
|
||||
to_chat(src, "<span class='warning'>You taste a strong alkaline flavour!</span>")
|
||||
T.applyOrganDamage(1)
|
||||
if(8.5 to 11.5)
|
||||
to_chat(src, "<span class='notice'>You taste a sort of soapy tone in the mixture.</span>")
|
||||
if(2.5 to 5.5)
|
||||
to_chat(src, "<span class='notice'>You taste a sort of acid tone in the mixture.</span>")
|
||||
if(-INFINITY to 2.5)
|
||||
to_chat(src, "<span class='warning'>You taste a strong acidic flavour!</span>")
|
||||
T.applyOrganDamage(1)
|
||||
|
||||
#undef DEFAULT_TASTE_SENSITIVITY
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user