Polaris Sync

This commit is contained in:
killer653
2017-10-16 22:16:24 -04:00
249 changed files with 6618 additions and 2568 deletions
+2 -2
View File
@@ -114,7 +114,7 @@ var/list/admin_verbs_sounds = list(
)
var/list/admin_verbs_fun = list(
/client/proc/object_talk,
/client/proc/cmd_admin_dress,
/datum/admins/proc/cmd_admin_dress,
/client/proc/cmd_admin_gib_self,
/client/proc/drop_bomb,
/client/proc/everyone_random,
@@ -260,7 +260,7 @@ var/list/admin_verbs_hideable = list(
/client/proc/play_sound,
/client/proc/play_server_sound,
/client/proc/object_talk,
/client/proc/cmd_admin_dress,
/datum/admins/proc/cmd_admin_dress,
/client/proc/cmd_admin_gib_self,
/client/proc/drop_bomb,
/client/proc/cinematic,
+20 -502
View File
@@ -385,518 +385,36 @@
for(var/areatype in areas_without_camera)
world << "* [areatype]"
/client/proc/cmd_admin_dress() // Vorestation Edits throughout this proc.
/datum/admins/proc/cmd_admin_dress(input in getmobs())
set category = "Fun"
set name = "Select equipment"
var/mob/living/carbon/human/M = input("Select mob.", "Select equipment.") as null|anything in human_mob_list
if(!M) return
//log_admin("[key_name(src)] has alienized [M.key].")
var/list/dresspacks = list(
"strip",
"job",
"standard space gear",
"tournament standard red",
"tournament standard green",
"tournament gangster",
"tournament chef",
"tournament janitor",
"pirate",
"space pirate",
"soviet admiral",
"tunnel clown",
"masked killer",
"assassin",
"death commando",
"syndicate commando",
"special ops officer",
"blue wizard",
"red wizard",
"marisa wizard",
"emergency response team",
"nanotrasen representative",
"nanotrasen officer",
"nanotrasen captain",
"USDF marine",
"USDF officer",
"SolGov Representative",
"Imperial soldier",
"Imperial officer"
)
var/dresscode = input("Select dress for [M]", "Robust quick dress shop") as null|anything in dresspacks
if (isnull(dresscode))
if(!check_rights(R_FUN))
return
feedback_add_details("admin_verb","SEQ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
for (var/obj/item/I in M)
if (istype(I, /obj/item/weapon/implant))
continue
M.drop_from_inventory(I)
if(I.loc != M)
qdel(I)
switch(dresscode)
if ("strip")
//do nothing
if ("job")
var/selected_job = input("Select job", "Robust quick dress shop") as null|anything in joblist
if (isnull(selected_job))
return
var/datum/job/job = job_master.GetJob(selected_job)
if(!job)
return
var/target = getmobs()[input]
if(!target)
return
job.equip(M)
job.apply_fingerprints(M)
job_master.spawnId(M, selected_job)
if(!ishuman(target))
return
if ("standard space gear")
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
var/mob/living/carbon/human/H = target
M.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/space(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space(M), slot_head)
var /obj/item/weapon/tank/jetpack/J = new /obj/item/weapon/tank/jetpack/oxygen(M)
M.equip_to_slot_or_del(J, slot_back)
J.toggle()
M.equip_to_slot_or_del(new /obj/item/clothing/mask/breath(M), slot_wear_mask)
J.Topic(null, list("stat" = 1))
if ("tournament standard red","tournament standard green") //we think stunning weapon is too overpowered to use it on tournaments. --rastaf0
if (dresscode=="tournament standard red")
M.equip_to_slot_or_del(new /obj/item/clothing/under/color/red(M), slot_w_uniform)
else
M.equip_to_slot_or_del(new /obj/item/clothing/under/color/green(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
var/decl/hierarchy/outfit/outfit = input("Select outfit.", "Select equipment.") as null|anything in outfits()
if(!outfit)
return
M.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/vest(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/thunderdome(M), slot_head)
feedback_add_details("admin_verb","SEQ")
dressup_human(H, outfit, 1)
M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/destroyer(M), slot_r_hand)
M.equip_to_slot_or_del(new /obj/item/weapon/material/knife(M), slot_l_hand)
M.equip_to_slot_or_del(new /obj/item/weapon/grenade/smokebomb(M), slot_r_store)
if ("tournament gangster") //gangster are supposed to fight each other. --rastaf0
M.equip_to_slot_or_del(new /obj/item/clothing/under/det(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/det_trench(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/plain/monocle(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/clothing/head/det(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver(M), slot_r_hand)
M.equip_to_slot_or_del(new /obj/item/ammo_magazine/s357(M), slot_l_store)
if ("tournament chef") //Steven Seagal FTW
M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/chef(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/chef(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/head/chefhat(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/weapon/material/kitchen/rollingpin(M), slot_r_hand)
M.equip_to_slot_or_del(new /obj/item/weapon/material/knife(M), slot_l_hand)
M.equip_to_slot_or_del(new /obj/item/weapon/material/knife(M), slot_r_store)
M.equip_to_slot_or_del(new /obj/item/weapon/material/knife(M), slot_s_store)
if ("tournament janitor")
M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/janitor(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
var/obj/item/weapon/storage/backpack/backpack = new(M)
for(var/obj/item/I in backpack)
qdel(I)
M.equip_to_slot_or_del(backpack, slot_back)
M.equip_to_slot_or_del(new /obj/item/weapon/mop(M), slot_r_hand)
var/obj/item/weapon/reagent_containers/glass/bucket/bucket = new(M)
bucket.reagents.add_reagent("water", 70)
M.equip_to_slot_or_del(bucket, slot_l_hand)
M.equip_to_slot_or_del(new /obj/item/weapon/grenade/chem_grenade/cleaner(M), slot_r_store)
M.equip_to_slot_or_del(new /obj/item/weapon/grenade/chem_grenade/cleaner(M), slot_l_store)
M.equip_to_slot_or_del(new /obj/item/stack/tile/floor(M), slot_in_backpack)
M.equip_to_slot_or_del(new /obj/item/stack/tile/floor(M), slot_in_backpack)
M.equip_to_slot_or_del(new /obj/item/stack/tile/floor(M), slot_in_backpack)
M.equip_to_slot_or_del(new /obj/item/stack/tile/floor(M), slot_in_backpack)
M.equip_to_slot_or_del(new /obj/item/stack/tile/floor(M), slot_in_backpack)
M.equip_to_slot_or_del(new /obj/item/stack/tile/floor(M), slot_in_backpack)
M.equip_to_slot_or_del(new /obj/item/stack/tile/floor(M), slot_in_backpack)
if ("pirate")
M.equip_to_slot_or_del(new /obj/item/clothing/under/pirate(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/head/bandana(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/eyepatch(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword/pirate(M), slot_r_hand)
if ("space pirate")
M.equip_to_slot_or_del(new /obj/item/clothing/under/pirate(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/space/pirate(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/pirate(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/eyepatch(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword/pirate(M), slot_r_hand)
if ("soviet soldier")
M.equip_to_slot_or_del(new /obj/item/clothing/under/soviet(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/head/ushanka(M), slot_head)
if("tunnel clown")//Tunnel clowns rule!
M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/clown(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/clown_shoes(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/black(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(M), slot_wear_mask)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/plain/monocle(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/hooded/chaplain_hoodie(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/weapon/bikehorn(M), slot_r_store)
var/obj/item/weapon/card/id/W = new(M)
W.name = "[M.real_name]'s ID Card"
W.access = get_all_station_access()
W.assignment = "Tunnel Clown!"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
var/obj/item/weapon/material/twohanded/fireaxe/fire_axe = new(M)
M.equip_to_slot_or_del(fire_axe, slot_r_hand)
if("masked killer")
M.equip_to_slot_or_del(new /obj/item/clothing/under/overalls(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/sterile/latex(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/clothing/mask/surgical(M), slot_wear_mask)
M.equip_to_slot_or_del(new /obj/item/clothing/head/welding(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/plain/monocle(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/apron(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/weapon/material/knife(M), slot_l_store)
M.equip_to_slot_or_del(new /obj/item/weapon/surgical/scalpel(M), slot_r_store)
var/obj/item/weapon/material/twohanded/fireaxe/fire_axe = new(M)
M.equip_to_slot_or_del(fire_axe, slot_r_hand)
for(var/obj/item/carried_item in M.contents)
if(!istype(carried_item, /obj/item/weapon/implant))//If it's not an implant.
carried_item.add_blood(M)//Oh yes, there will be blood...
if("assassin")
M.equip_to_slot_or_del(new /obj/item/clothing/under/suit_jacket(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/black(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/clothing/accessory/wcoat(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword(M), slot_l_store)
var/obj/item/weapon/storage/secure/briefcase/sec_briefcase = new(M)
for(var/obj/item/briefcase_item in sec_briefcase)
qdel(briefcase_item)
for(var/i=3, i>0, i--)
sec_briefcase.contents += new /obj/item/weapon/spacecash/c1000
sec_briefcase.contents += new /obj/item/weapon/gun/energy/crossbow
sec_briefcase.contents += new /obj/item/weapon/gun/projectile/revolver/mateba
sec_briefcase.contents += new /obj/item/ammo_magazine/s357
sec_briefcase.contents += new /obj/item/weapon/plastique
M.equip_to_slot_or_del(sec_briefcase, slot_l_hand)
var/obj/item/device/pda/heads/pda = new(M)
pda.owner = M.real_name
pda.ownjob = "Reaper"
pda.name = "PDA-[M.real_name] ([pda.ownjob])"
M.equip_to_slot_or_del(pda, slot_belt)
var/obj/item/weapon/card/id/syndicate/W = new(M)
W.name = "[M.real_name]'s ID Card"
W.access = get_all_station_access()
W.assignment = "Reaper"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
if("death commando")//Was looking to add this for a while.
deathsquad.equip(M)
if("syndicate commando")
commandos.equip(M)
if("nanotrasen representative")
M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/white(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/hop(M), slot_l_ear)
var/obj/item/device/pda/heads/pda = new(M)
pda.owner = M.real_name
pda.ownjob = "NanoTrasen Navy Representative"
pda.name = "PDA-[M.real_name] ([pda.ownjob])"
M.equip_to_slot_or_del(pda, slot_r_store)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store)
M.equip_to_slot_or_del(new /obj/item/weapon/clipboard(M), slot_belt)
var/obj/item/weapon/card/id/W = new(M)
W.name = "[M.real_name]'s ID Card"
W.icon_state = "centcom"
W.item_state = "id_inv"
W.access = get_all_station_access()
W.access += list("VIP Guest","Custodian","Thunderdome Overseer","Intel Officer","Medical Officer","Death Commando","Research Officer")
W.assignment = "NanoTrasen Navy Representative"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
if("nanotrasen officer")
M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/white(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear)
M.equip_to_slot_or_del(new /obj/item/clothing/head/beret/centcom/officer(M), slot_head)
var/obj/item/device/pda/heads/pda = new(M)
pda.owner = M.real_name
pda.ownjob = "NanoTrasen Navy Officer"
pda.name = "PDA-[M.real_name] ([pda.ownjob])"
M.equip_to_slot_or_del(pda, slot_r_store)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store)
M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy(M), slot_belt)
var/obj/item/weapon/card/id/centcom/W = new(M)
W.name = "[M.real_name]'s ID Card"
W.access = get_all_station_access()
W.access += get_all_centcom_access()
W.assignment = "NanoTrasen Navy Officer"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
if("nanotrasen captain")
M.equip_to_slot_or_del(new /obj/item/clothing/under/rank/centcom_captain(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/white(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear)
M.equip_to_slot_or_del(new /obj/item/clothing/head/beret/centcom/captain(M), slot_head)
var/obj/item/device/pda/heads/pda = new(M)
pda.owner = M.real_name
pda.ownjob = "NanoTrasen Navy Captain"
pda.name = "PDA-[M.real_name] ([pda.ownjob])"
M.equip_to_slot_or_del(pda, slot_r_store)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_l_store)
M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy(M), slot_belt)
var/obj/item/weapon/card/id/centcom/W = new(M)
W.name = "[M.real_name]'s ID Card"
W.access = get_all_station_access()
W.access += get_all_centcom_access()
W.assignment = "NanoTrasen Navy Captain"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
if("emergency response team")
M.equip_to_slot_or_del(new /obj/item/clothing/under/ert(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/boots/swat(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/swat(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/ert(M), slot_l_ear)
M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/gun(M), slot_belt)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
var/obj/item/weapon/card/id/W = new(M)
W.name = "[M.real_name]'s ID Card"
W.icon_state = "centcom"
W.access = get_all_station_access()
W.access += get_all_centcom_access()
W.assignment = "Emergency Response Team"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
if("special ops officer")
M.equip_to_slot_or_del(new /obj/item/clothing/under/syndicate/combat(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/swat/officer(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/boots/combat(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/plain/eyepatch(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/clothing/mask/smokable/cigarette/cigar/havana(M), slot_wear_mask)
M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/deathsquad/beret(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle/M1911(M), slot_belt)
M.equip_to_slot_or_del(new /obj/item/weapon/flame/lighter/zippo(M), slot_r_store)
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
var/obj/item/weapon/card/id/W = new(M)
W.name = "[M.real_name]'s ID Card"
W.icon_state = "centcom"
W.access = get_all_station_access()
W.access += get_all_centcom_access()
W.assignment = "Special Operations Officer"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
if("blue wizard")
M.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
M.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll(M), slot_r_store)
M.equip_to_slot_or_del(new /obj/item/weapon/spellbook(M), slot_r_hand)
M.equip_to_slot_or_del(new /obj/item/weapon/staff(M), slot_l_hand)
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(M), slot_back)
M.equip_to_slot_or_del(new /obj/item/weapon/storage/box(M), slot_in_backpack)
if("red wizard")
M.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/red(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
M.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/red(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll(M), slot_r_store)
M.equip_to_slot_or_del(new /obj/item/weapon/spellbook(M), slot_r_hand)
M.equip_to_slot_or_del(new /obj/item/weapon/staff(M), slot_l_hand)
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(M), slot_back)
M.equip_to_slot_or_del(new /obj/item/weapon/storage/box(M), slot_in_backpack)
if("marisa wizard")
M.equip_to_slot_or_del(new /obj/item/clothing/under/color/lightpurple(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe/marisa(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/marisa(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset(M), slot_l_ear)
M.equip_to_slot_or_del(new /obj/item/clothing/head/wizard/marisa(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll(M), slot_r_store)
M.equip_to_slot_or_del(new /obj/item/weapon/spellbook(M), slot_r_hand)
M.equip_to_slot_or_del(new /obj/item/weapon/staff(M), slot_l_hand)
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(M), slot_back)
M.equip_to_slot_or_del(new /obj/item/weapon/storage/box(M), slot_in_backpack)
if("soviet admiral")
M.equip_to_slot_or_del(new /obj/item/clothing/head/hgpiratecap(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/boots/combat(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear)
M.equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/plain/eyepatch(M), slot_glasses)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/hgpirate(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver/mateba(M), slot_belt)
M.equip_to_slot_or_del(new /obj/item/clothing/under/soviet(M), slot_w_uniform)
var/obj/item/weapon/card/id/W = new(M)
W.name = "[M.real_name]'s ID Card"
W.icon_state = "centcom"
W.access = get_all_station_access()
W.access += get_all_centcom_access()
W.assignment = "Admiral"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
if("USDF marine")
M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/combat/USDF(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/boots/jackboots(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/combat(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/centcom(M), slot_l_ear)
M.equip_to_slot_or_del(new /obj/item/clothing/under/utility/marine/green(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/combat/USDF(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/automatic/battlerifle(M), slot_back)
M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/security/tactical(M), slot_belt)
M.equip_to_slot_or_del(new /obj/item/ammo_magazine/m95(M), slot_l_store)
M.equip_to_slot_or_del(new /obj/item/ammo_magazine/m95(M), slot_r_store)
M.equip_to_slot_or_del(new /obj/item/ammo_magazine/m95(M), slot_r_hand)
M.equip_to_slot_or_del(new /obj/item/ammo_magazine/m95(M), slot_l_hand)
var/obj/item/weapon/card/id/W = new(M)
W.name = "[M.real_name]'s military ID Card"
W.icon_state = "lifetime"
W.access = get_all_station_access()
W.access += get_all_centcom_access()
W.assignment = "USDF"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
if("USDF officer")
M.equip_to_slot_or_del(new /obj/item/clothing/head/dress/marine/command/admiral(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/boots/jackboots(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/centcom(M), slot_l_ear)
M.equip_to_slot_or_del(new /obj/item/clothing/under/mildress/marine/command(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
M.equip_to_slot_or_del(new /obj/item/weapon/gun/projectile/revolver/consul(M), slot_belt)
M.equip_to_slot_or_del(new /obj/item/ammo_magazine/s44(M), slot_l_store)
M.equip_to_slot_or_del(new /obj/item/ammo_magazine/s44(M), slot_r_store)
M.equip_to_slot_or_del(new /obj/item/clothing/accessory/holster/hip(M), slot_r_hand)
M.equip_to_slot_or_del(new /obj/item/clothing/accessory/black(M), slot_l_hand)
var/obj/item/weapon/card/id/W = new(M)
W.name = "[M.real_name]'s military ID Card"
W.icon_state = "lifetime"
W.access = get_all_station_access()
W.access += get_all_centcom_access()
W.assignment = "USDF"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
if("SolGov Representative")
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/centcom(M), slot_l_ear)
M.equip_to_slot_or_del(new /obj/item/clothing/under/suit_jacket/navy (M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
M.equip_to_slot_or_del(new /obj/item/weapon/pen/blue(M), slot_l_store)
M.equip_to_slot_or_del(new /obj/item/weapon/pen/red(M), slot_r_store)
M.equip_to_slot_or_del(new /obj/item/device/pda/centcom(M), slot_r_hand)
M.equip_to_slot_or_del(new /obj/item/weapon/clipboard(M), slot_l_hand)
var/obj/item/weapon/card/id/W = new(M)
W.name = "[M.real_name]'s SolGov ID Card"
W.icon_state = "lifetime"
W.access = get_all_station_access()
W.access += get_all_centcom_access()
W.assignment = "SolGov Representative"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
if("Imperial soldier")
M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/combat/imperial(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/leg_guard/combat/imperial(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/arm_guard/combat/imperial(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/syndicate(M), slot_l_ear)
M.equip_to_slot_or_del(new /obj/item/clothing/under/imperial(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/imperial(M), slot_wear_mask)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/combat/imperial(M), slot_wear_suit)
M.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(M), slot_back)
M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/security/tactical/bandolier(M), slot_belt)
M.equip_to_slot_or_del(new /obj/item/weapon/cell/device/weapon(M), slot_l_store)
M.equip_to_slot_or_del(new /obj/item/weapon/cell/device/weapon(M), slot_r_store)
M.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword/imperial(M), slot_r_hand)
M.equip_to_slot_or_del(new /obj/item/weapon/shield/energy/imperial(M), slot_l_hand)
M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/imperial(M), slot_s_store)
/*var/obj/item/weapon/card/id/W = new(M)
W.name = "[M.real_name]'s ID Card" // ToDo
W.icon_state = "lifetime"
W.access = get_all_station_access()
W.access += get_all_centcom_access()
W.assignment = "SolGov Representative"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)*/
if("Imperial officer")
M.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/combat/imperial/centurion(M), slot_head)
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/leg_guard/combat/imperial(M), slot_shoes)
M.equip_to_slot_or_del(new /obj/item/clothing/gloves/arm_guard/combat/imperial(M), slot_gloves)
M.equip_to_slot_or_del(new /obj/item/device/radio/headset/syndicate(M), slot_l_ear)
M.equip_to_slot_or_del(new /obj/item/clothing/under/imperial(M), slot_w_uniform)
M.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/imperial(M), slot_wear_mask)
M.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/combat/imperial/centurion(M), slot_wear_suit)
//M.equip_to_slot_or_del(new (M), slot_back) // Doesn't look right with the cape. No bags.
M.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/security/tactical/bandolier(M), slot_belt)
M.equip_to_slot_or_del(new /obj/item/weapon/cell/device/weapon(M), slot_l_store)
M.equip_to_slot_or_del(new /obj/item/weapon/cell/device/weapon(M), slot_r_store)
M.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword/imperial(M), slot_r_hand)
M.equip_to_slot_or_del(new /obj/item/weapon/shield/energy/imperial(M), slot_l_hand)
M.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/imperial(M), slot_s_store)
/*var/obj/item/weapon/card/id/W = new(M)
W.name = "[M.real_name]'s ID Card" // ToDo
W.icon_state = "lifetime"
W.access = get_all_station_access()
W.access += get_all_centcom_access()
W.assignment = "SolGov Representative"
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)*/
M.regenerate_icons()
log_admin("[key_name(usr)] changed the equipment of [key_name(M)] to [dresscode].")
message_admins("<font color='blue'>[key_name_admin(usr)] changed the equipment of [key_name_admin(M)] to [dresscode]..</font>", 1)
return
/proc/dressup_human(var/mob/living/carbon/human/H, var/decl/hierarchy/outfit/outfit, var/undress = 1)
if(!H || !outfit)
return
if(undress)
H.delete_inventory()
outfit.equip(H)
log_and_message_admins("changed the equipment of [key_name(H)] to [outfit.name].")
/client/proc/startSinglo()
+7 -7
View File
@@ -83,12 +83,12 @@
if (!fqs)
output += "&nbsp;&nbsp;<b>ERROR</b><br>"
continue
for (var/filter in fqs.devices)
var/list/f = fqs.devices[filter]
for (var/radio_filter in fqs.devices)
var/list/f = fqs.devices[radio_filter]
if (!f)
output += "&nbsp;&nbsp;[filter]: ERROR<br>"
output += "&nbsp;&nbsp;[radio_filter]: ERROR<br>"
continue
output += "&nbsp;&nbsp;[filter]: [f.len]<br>"
output += "&nbsp;&nbsp;[radio_filter]: [f.len]<br>"
for (var/device in f)
if (isobj(device))
output += "&nbsp;&nbsp;&nbsp;&nbsp;[device] ([device:x],[device:y],[device:z] in area [get_area(device:loc)])<br>"
@@ -177,11 +177,11 @@
set desc = "This searches all the active jobban entries for the current round and outputs the results to standard output."
set category = "Debug"
var/filter = input("Contains what?","Filter") as text|null
if(!filter)
var/job_filter = input("Contains what?","Job Filter") as text|null
if(!job_filter)
return
usr << "<b>Jobbans active in this round.</b>"
for(var/t in jobban_keylist)
if(findtext(t, filter))
if(findtext(t, job_filter))
usr << "[t]"
+73 -4
View File
@@ -73,11 +73,39 @@
motto = ""
ship_prefixes = list("NSV" = "exploration", "NTV" = "hauling", "NDV" = "patrol", "NRV" = "emergency response")
//Scientist naming scheme
ship_names = list(
"Bardeen",
"Einstein",
"Feynman",
"Sagan",
"Tyson",
"Galilei",
"Jans",
"Fhriede",
"Franklin",
"Tesla",
"Curie",
"Darwin",
"Newton",
"Pasteur",
"Bell",
"Mendel",
"Kepler",
"Edision",
"Cavendish",
"Nye",
"Hawking",
"Aristotle",
"Von Braun",
"Kaku",
"Oppenheimer"
)
// Note that the current station being used will be pruned from this list upon being instantiated
destination_names = list(
"NSS Exodus in Nyx",
"NCS Northern Star in Vir",
"NCS Southern Cross in Vir",
"NLS Southern Cross in Vir",
"NAS Vir Central Command",
"a dockyard orbiting Sif",
"an asteroid orbiting Kara",
@@ -110,6 +138,24 @@
motto = ""
ship_prefixes = list("HTV" = "freight", "HTV" = "munitions resupply")
//War God/Soldier Theme
ship_names = list(
"Ares",
"Athena",
"Grant",
"Custer",
"Puller",
"Nike",
"Bellona",
"Leonides",
"Bast",
"Jackson",
"Lee",
"Annan",
"Chi Yu",
"Shiva",
"Tyr"
)
destination_names = list(
"a SolGov dockyard on Luna",
"a Fleet outpost in the Almach Rim",
@@ -133,6 +179,22 @@
motto = ""
ship_prefixes = list("VTV" = "transportation", "VMV" = "medical resupply")
// Diona names
ship_names = list(
"Wind That Stirs The Waves",
"Sustained Note Of Metal",
"Bright Flash Reflecting Off Glass",
"Veil Of Mist Concealing The Rock",
"Thin Threads Intertwined",
"Clouds Drifting Amid Storm",
"Loud Note And Breaking",
"Endless Vistas Expanding Before The Void",
"Fire Blown Out By Wind",
"Star That Fades From View",
"Eyes Which Turn Inwards",
"Joy Without Which The World Would Come Undone",
"A Thousand Thousand Planets Dangling From Branches"
)
destination_names = list(
"a research facility in Samsara",
"a SDTF near Ue-Orsi",
@@ -289,9 +351,16 @@
"Nothing To Declare",
"Sneaking Suspicion",
"Bass Ackwards",
"Good Things Come to Those Who Freight"
"Good Things Come to Those Who Freight",
"Redundant Morality",
"Synthetic Goodwill",
"Your Ad Here",
"What Are We Plotting?",
"Set Phasers To Stun",
"Preemptive Defensive Strike",
"This Ship Is Spiders",
"Legitimate Trade Vessel",
"Please Don't Explode II"
)
destination_names = list(
"A trade outpost in Shelf"
@@ -29,6 +29,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
S["organ_data"] >> pref.organ_data
S["rlimb_data"] >> pref.rlimb_data
S["body_markings"] >> pref.body_markings
S["synth_color"] >> pref.synth_color
S["synth_red"] >> pref.r_synth
S["synth_green"] >> pref.g_synth
S["synth_blue"] >> pref.b_synth
pref.preview_icon = null
/datum/category_item/player_setup_item/general/body/save_character(var/savefile/S)
@@ -53,6 +57,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
S["organ_data"] << pref.organ_data
S["rlimb_data"] << pref.rlimb_data
S["body_markings"] << pref.body_markings
S["synth_color"] << pref.synth_color
S["synth_red"] << pref.r_synth
S["synth_green"] << pref.g_synth
S["synth_blue"] << pref.b_synth
/datum/category_item/player_setup_item/general/body/sanitize_character(var/savefile/S)
if(!pref.species || !(pref.species in playable_species))
@@ -101,6 +109,10 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
character.h_style = pref.h_style
character.f_style = pref.f_style
character.b_type = pref.b_type
character.synth_color = pref.synth_color
character.r_synth = pref.r_synth
character.g_synth = pref.g_synth
character.b_synth = pref.b_synth
// Destroy/cyborgize organs and limbs.
for(var/name in list(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_GROIN, BP_TORSO))
@@ -284,6 +296,11 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
. += "<font face='fixedsys' size='3' color='[pref.body_markings[M]]'><table style='display:inline;' bgcolor='[pref.body_markings[M]]'><tr><td>__</td></tr></table></font>"
. += "<br>"
. += "<br>"
. += "<b>Allow Synth color:</b> <a href='?src=\ref[src];synth_color=1'><b>[pref.synth_color ? "Yes" : "No"]</b></a><br>"
if(pref.synth_color)
. += "<a href='?src=\ref[src];synth2_color=1'>Change Color</a> <font face='fixedsys' size='3' color='#[num2hex(pref.r_synth, 2)][num2hex(pref.g_synth, 2)][num2hex(pref.b_synth, 2)]'><table style='display:inline;' bgcolor='#[num2hex(pref.r_synth, 2)][num2hex(pref.g_synth, 2)][num2hex(pref.b_synth)]'><tr><td>__</td></tr></table></font> "
. = jointext(.,null)
/datum/category_item/player_setup_item/general/body/proc/has_flag(var/datum/species/mob_species, var/flag)
@@ -672,6 +689,18 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
pref.equip_preview_mob ^= text2num(href_list["toggle_preview_value"])
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["synth_color"])
pref.synth_color = !pref.synth_color
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["synth2_color"])
var/new_color = input(user, "Choose your character's synth colour: ", "Character Preference", rgb(pref.r_synth, pref.g_synth, pref.b_synth)) as color|null
if(new_color && CanUseTopic(user))
pref.r_synth = hex2num(copytext(new_color, 2, 4))
pref.g_synth = hex2num(copytext(new_color, 4, 6))
pref.b_synth = hex2num(copytext(new_color, 6, 8))
return TOPIC_REFRESH_UPDATE_PREVIEW
return ..()
/datum/category_item/player_setup_item/general/body/proc/reset_limbs()
@@ -74,4 +74,28 @@
/datum/gear/gloves/fingerless
display_name = "fingerless gloves"
path = /obj/item/clothing/gloves/fingerless
path = /obj/item/clothing/gloves/fingerless
/datum/gear/gloves/ring
display_name = "ring selection"
description = "Choose from a number of rings."
path = /obj/item/clothing/gloves/ring
cost = 1
/datum/gear/gloves/ring/New()
..()
var/ringtype = list()
ringtype["CTI ring"] = /obj/item/clothing/gloves/ring/cti
ringtype["Mariner University ring"] = /obj/item/clothing/gloves/ring/mariner
ringtype["engagement ring"] = /obj/item/clothing/gloves/ring/engagement
ringtype["signet ring"] = /obj/item/clothing/gloves/ring/seal/signet
ringtype["masonic ring"] = /obj/item/clothing/gloves/ring/seal/mason
ringtype["ring, steel"] = /obj/item/clothing/gloves/ring/material/steel
ringtype["ring, iron"] = /obj/item/clothing/gloves/ring/material/iron
ringtype["ring, silver"] = /obj/item/clothing/gloves/ring/material/silver
ringtype["ring, gold"] = /obj/item/clothing/gloves/ring/material/gold
ringtype["ring, platinum"] = /obj/item/clothing/gloves/ring/material/platinum
ringtype["ring, glass"] = /obj/item/clothing/gloves/ring/material/glass
ringtype["ring, wood"] = /obj/item/clothing/gloves/ring/material/wood
ringtype["ring, plastic"] = /obj/item/clothing/gloves/ring/material/plastic
gear_tweaks += new/datum/gear_tweak/path(ringtype)
@@ -199,6 +199,41 @@
path = /obj/item/clothing/accessory/poncho/roles/cargo
allowed_roles = list("Quartermaster","Cargo Technician")
/datum/gear/suit/roles/poncho/cloak/hos
display_name = "cloak, head of security"
path = /obj/item/clothing/accessory/poncho/roles/cloak/hos
allowed_roles = list("Head of Security")
/datum/gear/suit/roles/poncho/cloak/cmo
display_name = "cloak, chief medical officer"
path = /obj/item/clothing/accessory/poncho/roles/cloak/cmo
allowed_roles = list("Chief Medical Officer")
/datum/gear/suit/roles/poncho/cloak/ce
display_name = "cloak, chief engineer"
path = /obj/item/clothing/accessory/poncho/roles/cloak/ce
allowed_roles = list("Chief Engineer")
/datum/gear/suit/roles/poncho/cloak/rd
display_name = "cloak, research director"
path = /obj/item/clothing/accessory/poncho/roles/cloak/rd
allowed_roles = list("Research Director")
/datum/gear/suit/roles/poncho/cloak/qm
display_name = "cloak, quartermaster"
path = /obj/item/clothing/accessory/poncho/roles/cloak/qm
allowed_roles = list("Quartermaster")
/datum/gear/suit/roles/poncho/cloak/captain
display_name = "cloak, colony director"
path = /obj/item/clothing/accessory/poncho/roles/cloak/captain
allowed_roles = list("Colony Director")
/datum/gear/suit/roles/poncho/cloak/hop
display_name = "cloak, head of personnel"
path = /obj/item/clothing/accessory/poncho/roles/cloak/hop
allowed_roles = list("Head of Personnel")
/datum/gear/suit/unathi_robe
display_name = "roughspun robe"
path = /obj/item/clothing/suit/unathi/robe
@@ -89,12 +89,14 @@
path = /obj/item/weapon/implant/language/eal
cost = 2
slot = "implant"
exploitable = 1
/datum/gear/utility/implant/tracking
display_name = "implant, tracking"
path = /obj/item/weapon/implant/tracking/weak
cost = 10
slot = "implant"
exploitable = 1
/datum/gear/utility/translator
display_name = "universal translator"
@@ -157,7 +157,7 @@
var/datum/job/job = locate(href_list["select_alt_title"])
if (job)
var/choices = list(job.title) + job.alt_titles
var/choice = input("Choose an title for [job.title].", "Choose Title", pref.GetPlayerAltTitle(job)) as anything in choices|null
var/choice = input("Choose a title for [job.title].", "Choose Title", pref.GetPlayerAltTitle(job)) as anything in choices|null
if(choice && CanUseTopic(user))
SetPlayerAltTitle(job, choice)
return (pref.equip_preview_mob ? TOPIC_REFRESH_UPDATE_PREVIEW : TOPIC_REFRESH)
@@ -32,10 +32,15 @@
name = "Loadout"
sort_order = 5
category_item_type = /datum/category_item/player_setup_item/loadout
/* //VOREStation Removal
/datum/category_group/player_setup_category/trait_preferences
name = "Traits"
sort_order = 6
category_item_type = /datum/category_item/player_setup_item/traits
*/ //VOREStation Removal End
/datum/category_group/player_setup_category/global_preferences
name = "Global"
sort_order = 6
sort_order = 6 //VOREStation Edit due to above commented out
category_item_type = /datum/category_item/player_setup_item/player_global
/****************************
@@ -0,0 +1,223 @@
// This contains character setup datums for traits.
// The actual modifiers (if used) for these are stored inside code/modules/mob/_modifiers/traits.dm
/datum/trait/modifier
var/modifier_type = null // Type to add to the mob post spawn.
/datum/trait/modifier/apply_trait_post_spawn(mob/living/L)
L.add_modifier(modifier_type)
/datum/trait/modifier/generate_desc()
var/new_desc = desc
if(!modifier_type)
new_desc = "[new_desc] This trait is not implemented yet."
return new_desc
var/datum/modifier/M = new modifier_type()
if(!desc)
new_desc = M.desc // Use the modifier's description, if the trait doesn't have one defined.
var/modifier_effects = M.describe_modifier_effects()
new_desc = "[new_desc][modifier_effects ? "<br>[modifier_effects]":""]" // Now describe what the trait actually does.
qdel(M)
return new_desc
// Physical traits are what they sound like, and involve the character's physical body, as opposed to their mental state.
/datum/trait/modifier/physical
category = "Physical Quirks" //VOREStation Edit
/datum/trait/modifier/physical/flimsy
name = "Flimsy"
desc = "You're more fragile than most, and have less of an ability to endure harm."
modifier_type = /datum/modifier/trait/flimsy
mutually_exclusive = list(/datum/trait/modifier/physical/frail)
/datum/trait/modifier/physical/frail
name = "Frail"
desc = "Your body is very fragile, and has even less of an ability to endure harm."
modifier_type = /datum/modifier/trait/frail
mutually_exclusive = list(/datum/trait/modifier/physical/flimsy)
/datum/trait/modifier/physical/haemophilia
name = "Haemophilia"
desc = "Some say that when it rains, it pours. Unfortunately, this is also true for yourself if you get cut."
modifier_type = /datum/modifier/trait/haemophilia
/datum/trait/modifier/physical/haemophilia/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
if(setup.is_FBP())
return "Full Body Prosthetics cannot bleed."
// If a species lacking blood is added, it is suggested to add a check for them here.
return ..()
/datum/trait/modifier/physical/weak
name = "Weak"
desc = "A lack of physical strength causes a diminshed capability in close quarters combat."
modifier_type = /datum/modifier/trait/weak
mutually_exclusive = list(/datum/trait/modifier/physical/wimpy)
/datum/trait/modifier/physical/wimpy
name = "Wimpy"
desc = "An extreme lack of physical strength causes a greatly diminished capability in close quarters combat."
modifier_type = /datum/modifier/trait/wimpy
mutually_exclusive = list(/datum/trait/modifier/physical/weak)
/datum/trait/modifier/physical/inaccurate
name = "Inaccurate"
desc = "You're rather inexperienced with guns, you've never used one in your life, or you're just really rusty. \
Regardless, you find it quite difficult to land shots where you wanted them to go."
modifier_type = /datum/modifier/trait/inaccurate
// These two traits might be borderline, feel free to remove if they get abused.
/datum/trait/modifier/physical/high_metabolism
name = "High Metabolism"
modifier_type = /datum/modifier/trait/high_metabolism
mutually_exclusive = list(/datum/trait/modifier/physical/low_metabolism)
/datum/trait/modifier/physical/high_metabolism/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
if(setup.is_FBP())
return "Full Body Prosthetics do not have a metabolism."
return ..()
/datum/trait/modifier/physical/low_metabolism
name = "Low Metabolism"
modifier_type = /datum/modifier/trait/low_metabolism
mutually_exclusive = list(/datum/trait/modifier/physical/high_metabolism)
/datum/trait/modifier/physical/low_metabolism/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
if(setup.is_FBP())
return "Full Body Prosthetics do not have a metabolism."
return ..()
/datum/trait/modifier/physical/cloned
name = "Cloned"
desc = "At some point in your life, you died and were cloned."
modifier_type = /datum/modifier/cloned
/datum/trait/modifier/physical/cloned/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
if(setup.is_FBP())
return "Full Body Prosthetics cannot be cloned."
return ..()
/datum/trait/modifier/physical/no_clone
name = "Cloning Incompatability"
modifier_type = /datum/modifier/no_clone
/datum/trait/modifier/physical/no_clone/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
if(setup.is_FBP())
return "Full Body Prosthetics cannot be cloned anyways."
return ..()
/datum/trait/modifier/physical/no_borg
name = "Cybernetic Incompatability"
modifier_type = /datum/modifier/no_borg
/datum/trait/modifier/physical/no_borg/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
if(setup.is_FBP())
return "Full Body Prosthetics are already partly or fully mechanical."
return ..()
// 'Mental' traits are just those that only sapients can have, for now, and generally involves fears.
// So far, all of them are just for fluff/don't have mechanical effects.
/datum/trait/modifier/mental
category = "Mental"
/datum/trait/modifier/mental/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
if(setup.is_FBP())
if(setup.get_FBP_type() == PREF_FBP_SOFTWARE)
return "Drone Intelligences cannot feel emotions."
return ..()
/datum/trait/modifier/mental/arachnophobe
name = "Arachnophobic"
desc = "Spiders are quite creepy to most people, however for you, those chitters of pure evil inspire pure dread and fear."
modifier_type = /datum/modifier/trait/phobia/arachnophobe
/datum/trait/modifier/mental/nyctophobe
name = "Nyctophobic"
desc = "More commonly known as the fear of darkness. The shadows can hide many dangers, which makes the prospect of going into the depths of Maintenance rather worrisome."
modifier_type = /datum/modifier/trait/phobia/nyctophobe
/datum/trait/modifier/mental/haemophobe
name = "Haemophobia"
desc = "Not to be confused with Haemophilia (which makes you bleed faster), Haemophobia is the fear of blood. Seeing a bunch of blood isn't really \
pleasant for most people, but for you, it is very distressing."
modifier_type = /datum/modifier/trait/phobia/haemophobia
/datum/trait/modifier/mental/claustrophobe
name = "Claustrophobic"
desc = "Small spaces and tight quarters makes you feel distressed. Unfortunately both are rather common when living in space."
modifier_type = /datum/modifier/trait/phobia/claustrophobe
/*
// Uncomment this when/if these get finished.
/datum/trait/modifier/mental/synthphobe
name = "Synthphobic"
desc = "You know, deep down, that synthetics cannot be trusted, and so you are always on guard whenever you see one wandering around. No one knows how a Positronic's mind works, \
Drones are just waiting for the right time for Emergence, and the poor brains trapped in the cage of Man Machine Interfaces are now soulless, despite being unaware of it. None \
can be trusted."
/datum/trait/modifier/mental/xenophobe
name = "Xenophobic"
desc = "The mind of the Alien is unknowable, and as such, their intentions cannot be known. You always watch the xenos closely, as they most certainly are watching you \
closely, waiting to strike."
mutually_exclusive = list(
/datum/trait/modifier/mental/humanphobe,
/datum/trait/modifier/mental/skrellphobe,
/datum/trait/modifier/mental/tajaraphobe,
/datum/trait/modifier/mental/unathiphobe,
/datum/trait/modifier/mental/teshariphobe,
/datum/trait/modifier/mental/prometheanphobe
)
/datum/trait/modifier/mental/humanphobe
name = "Human-phobic"
desc = "Boilerplate racism for monkeys goes here."
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
/datum/trait/modifier/mental/skrellphobe
name = "Skrell-phobic"
desc = "Boilerplate racism for squid goes here."
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
/datum/trait/modifier/mental/tajaraphobe
name = "Tajara-phobic"
desc = "Boilerplate racism for cats goes here."
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
/datum/trait/modifier/mental/unathiphobe
name = "Unathi-phobic"
desc = "Boilerplate racism for lizards goes here."
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
// Not sure why anyone would hate/fear these guys but for the sake of completeness here we are.
/datum/trait/modifier/mental/dionaphobe
name = "Diona-phobic"
desc = "Boilerplate racism for trees goes here."
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
/datum/trait/modifier/mental/teshariphobe
name = "Teshari-phobic"
desc = "Boilerplate racism for birds goes here."
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
/datum/trait/modifier/mental/prometheanphobe
name = "Promethean-phobic"
desc = "Boilerplate racism for jellos goes here."
mutually_exclusive = list(/datum/trait/modifier/mental/xenophobe)
*/
@@ -0,0 +1,196 @@
var/list/trait_datums = list() // Assoc list using name = instance. Traits are saved as a list of strings.
var/list/trait_type_to_ref = list() // Similar to above but uses paths, which is more reliable but more risky to save.
var/list/trait_categories = list() // The categories available for the trait menu.
/hook/startup/proc/populate_trait_list()
//create a list of trait datums
for(var/trait_type in typesof(/datum/trait) - list(/datum/trait, /datum/trait/modifier))
var/datum/trait/T = new trait_type
if(!T.name)
error("Trait Menu - Missing name: [T.type]")
continue
if(!T.category)
error("Trait Menu - Missing category: [T.type]")
continue
T.desc = T.generate_desc()
trait_datums[T.name] = T
trait_type_to_ref[T.type] = T
if(!(T.category in trait_categories))
trait_categories += T.category
return 1
/datum/category_item/player_setup_item/traits
name = "Quirks" //VOREStation Edit
sort_order = 1
var/current_tab = "Physical"
/datum/category_item/player_setup_item/traits/load_character(var/savefile/S)
S["traits"] >> pref.traits
/datum/category_item/player_setup_item/traits/save_character(var/savefile/S)
S["traits"] << pref.traits
/datum/category_item/player_setup_item/traits/content()
. = list()
. += "<table align = 'center' width = 100%>"
. += "<tr><td colspan=3><hr></td></tr>"
. += "<tr><td colspan=3><b><center>Traits</center></b></td></tr>"
. += "<tr><td colspan=3><hr></td></tr>"
. += "<tr><td colspan=3><center>"
var/firstcat = 1
for(var/category in trait_categories)
if(firstcat)
firstcat = 0
else
. += " |"
if(category == current_tab)
. += " <span class='linkOn'>[category]</span> "
else
. += " <a href='?src=\ref[src];select_category=[category]'>[category]</a> "
. += "</center></td></tr>"
for(var/trait_name in trait_datums)
var/datum/trait/T = trait_datums[trait_name]
if(T.category != current_tab)
continue
var/ticked = (T.name in pref.traits)
var/style_class
if(!T.validate(pref.traits, src))
style_class = "linkOff"
else if(ticked)
style_class = "linkOn"
. += "<tr style='vertical-align:top;'><td width=25%><div align='center'><a style='white-space:normal;' [style_class ? "class='[style_class]' " : ""]href='?src=\ref[src];toggle_trait=[html_encode(T.name)]'>[T.name]</a></div></td>"
// . += "<td width = 10% style='vertical-align:top'>[G.cost]</td>"
var/invalidity = T.test_for_invalidity(src)
var/conflicts = T.test_for_trait_conflict(pref.traits)
var/invalid = ""
if(invalidity)
invalid += "[invalidity] "
if(conflicts)
invalid += "This trait is mutually exclusive with [conflicts]."
. += "<td width = 75%><font size=2><i>[T.desc]</i>\
[invalid ? "<font color='#FF0000'><br>Cannot take trait. Reason: [invalid]</font>":""]</font></td></tr>"
// if(ticked)
// . += "<tr><td colspan=3>"
// for(var/datum/gear_tweak/tweak in G.gear_tweaks)
// . += " <a href='?src=\ref[src];gear=[G.display_name];tweak=\ref[tweak]'>[tweak.get_contents(get_tweak_metadata(G, tweak))]</a>"
// . += "</td></tr>"
. += "</table>"
. = jointext(., null)
/datum/category_item/player_setup_item/traits/sanitize_character()
var/mob/preference_mob = preference_mob()
if(!islist(pref.traits))
pref.traits = list()
for(var/trait_name in pref.traits)
if(!(trait_name in trait_datums))
pref.traits -= trait_name
for(var/trait_name in pref.traits)
if(!trait_datums[trait_name])
preference_mob << "<span class='warning'>You cannot have more than one of trait: [trait_name]</span>"
pref.traits -= trait_name
else
var/datum/trait/T = trait_datums[trait_name]
var/invalidity = T.test_for_invalidity(src)
if(invalidity)
pref.traits -= trait_name
preference_mob << "<span class='warning'>You cannot take the [trait_name] trait. Reason: [invalidity]</span>"
var/conflicts = T.test_for_trait_conflict(pref.traits)
if(conflicts)
pref.traits -= trait_name
to_chat(preference_mob, "<span class='warning'>The [trait_name] trait is mutually exclusive with [conflicts].</span>")
/datum/category_item/player_setup_item/traits/OnTopic(href, href_list, user)
if(href_list["toggle_trait"])
var/datum/trait/T = trait_datums[href_list["toggle_trait"]]
if(T.name in pref.traits)
pref.traits -= T.name
else
var/invalidity = T.test_for_invalidity(src)
if(invalidity)
to_chat(user, "<span class='warning'>You cannot take the [T.name] trait. Reason: [invalidity]</span>")
return TOPIC_NOACTION
var/conflicts = T.test_for_trait_conflict(pref.traits)
if(conflicts)
to_chat(user, "<span class='warning'>The [T.name] trait is mutually exclusive with [conflicts].</span>")
return TOPIC_NOACTION
pref.traits += T.name
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["select_category"])
current_tab = href_list["select_category"]
return TOPIC_REFRESH
return ..()
/datum/trait
var/name = null // Name to show on UI
var/desc = null // Description of what it does, also shown on UI.
var/list/mutually_exclusive = list() // List of trait types which cannot be taken alongside this trait.
var/category = null // What section to place this trait inside.
// Applies effects to the newly spawned mob.
/datum/trait/proc/apply_trait_post_spawn(var/mob/living/L)
return
// Used to forbid a trait based on certain criteria (e.g. if they are an FBP).
// It receives the player_setup_item datum since some reasons for being invalid depend on the currently loaded preferences.
// Returns a string explaining why the trait is invalid. Returns null if valid.
/datum/trait/proc/test_for_invalidity(var/datum/category_item/player_setup_item/traits/setup)
return null
// Checks mutually_exclusive. current_traits needs to be a list of strings.
// Returns null if everything is well, similar to the above proc. Otherwise returns an english_list() of conflicting traits.
/datum/trait/proc/test_for_trait_conflict(var/list/current_traits)
var/list/conflicts = list()
var/result
if(mutually_exclusive.len)
for(var/trait_name in current_traits)
var/datum/trait/T = trait_datums[trait_name]
if(T.type in mutually_exclusive)
conflicts.Add(T.name)
if(conflicts.len)
result = english_list(conflicts)
return result
// Similar to above, but uses the above two procs, in one place.
// Returns TRUE is everything is well.
/datum/trait/proc/validate(var/list/current_traits, var/datum/category_item/player_setup_item/traits/setup)
if(test_for_invalidity(setup))
return FALSE
if(test_for_trait_conflict(current_traits))
return FALSE
return TRUE
// Creates a description, if one doesn't exist.
// This one is for inheritence, and so doesn't do anything.
/datum/trait/proc/generate_desc()
return desc
/mob/living/proc/apply_traits()
if(!mind || !mind.traits || !mind.traits.len)
return
for(var/trait in mind.traits)
var/datum/trait/T = trait_datums[trait]
if(istype(T))
T.apply_trait_post_spawn(src)
+5
View File
@@ -50,6 +50,11 @@ datum/preferences
var/list/alternate_languages = list() //Secondary language(s)
var/list/language_prefixes = list() //Kanguage prefix keys
var/list/gear //Custom/fluff item loadout.
var/list/traits //Traits which modifier characters for better or worse (mostly worse).
var/synth_color = 0 //Lets normally uncolorable synth parts be colorable.
var/r_synth //Used with synth_color to color synth parts that normaly can't be colored.
var/g_synth //Same as above
var/b_synth //Same as above
//Some faction information.
var/home_system = "Unset" //System of birth.
+60 -1
View File
@@ -170,6 +170,7 @@
icon_state = O.icon_state
set_dir(O.dir)
////////////////////////////////////////////////////////////////////////////////////////
//Gloves
/obj/item/clothing/gloves
name = "gloves"
@@ -183,8 +184,11 @@
siemens_coefficient = 0.75
var/wired = 0
var/obj/item/weapon/cell/cell = 0
var/overgloves = 0
var/fingerprint_chance = 0 //How likely the glove is to let fingerprints through
var/obj/item/clothing/gloves/ring = null //Covered ring
var/mob/living/carbon/human/wearer = null //Used for covered rings when dropping
var/glove_level = 2 //What "layer" the glove is on
var/overgloves = 0 //Used by gauntlets and arm_guards
body_parts_covered = HANDS
slot_flags = SLOT_GLOVES
attack_verb = list("challenged")
@@ -201,6 +205,8 @@
/obj/item/clothing/gloves/emp_act(severity)
if(cell)
cell.emp_act(severity)
if(ring)
ring.emp_act(severity)
..()
// Called just before an attack_hand(), in mob/UnarmedAttack()
@@ -225,6 +231,59 @@
species_restricted -= "Tajara"
return
*/
/obj/item/clothing/gloves/mob_can_equip(mob/user, slot)
var/mob/living/carbon/human/H = user
if(slot && slot == slot_gloves)
if(istype(H.gloves, /obj/item/clothing/gloves/ring))
ring = H.gloves
if(ring.glove_level >= src.glove_level)
to_chat(user, "You are unable to wear \the [src] as \the [H.gloves] are in the way.")
ring = null
return 0
else
H.drop_from_inventory(ring) //Remove the ring (or other under-glove item in the hand slot?) so you can put on the gloves.
ring.forceMove(src)
to_chat(user, "You slip \the [src] on over \the [src.ring].")
else
ring = null
if(!..())
if(ring) //Put the ring back on if the check fails.
if(H.equip_to_slot_if_possible(ring, slot_gloves))
src.ring = null
return 0
wearer = H //TODO clean this when magboots are cleaned
return 1
/obj/item/clothing/gloves/dropped()
..()
if(!wearer)
return
var/mob/living/carbon/human/H = wearer
if(ring && istype(H))
if(!H.equip_to_slot_if_possible(ring, slot_gloves))
ring.forceMove(get_turf(src))
src.ring = null
wearer = null
/////////////////////////////////////////////////////////////////////
//Rings
/obj/item/clothing/gloves/ring
name = "ring"
w_class = ITEMSIZE_TINY
icon = 'icons/obj/clothing/rings.dmi'
gender = NEUTER
species_restricted = list("exclude", "Diona")
siemens_coefficient = 1
glove_level = 1
fingerprint_chance = 100
///////////////////////////////////////////////////////////////////////
//Head
/obj/item/clothing/head
+2 -2
View File
@@ -5,11 +5,11 @@
overgloves = 1
w_class = ITEMSIZE_NORMAL
/obj/item/clothing/gloves/arm_guard/mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0)
/obj/item/clothing/gloves/arm_guard/mob_can_equip(var/mob/living/carbon/human/H, slot)
if(..()) //This will only run if no other problems occured when equiping.
if(H.wear_suit)
if(H.wear_suit.body_parts_covered & ARMS)
H << "<span class='warning'>You can't wear \the [src] with \the [H.wear_suit], it's in the way.</span>"
to_chat(H, "<span class='warning'>You can't wear \the [src] with \the [H.wear_suit], it's in the way.</span>")
return 0
return 1
+6 -5
View File
@@ -9,16 +9,16 @@
/obj/item/clothing/gloves/gauntlets //Used to cover gloves, otherwise act as gloves.
name = "gauntlets"
desc = "These gloves go over regular gloves."
glove_level = 3
overgloves = 1
var/obj/item/clothing/gloves/gloves = null //Undergloves
var/mob/living/carbon/human/wearer = null //For glove procs
/obj/item/clothing/gloves/gauntlets/mob_can_equip(mob/user)
var/mob/living/carbon/human/H = user
if(H.gloves)
gloves = H.gloves
if(gloves.overgloves)
user << "You are unable to wear \the [src] as \the [H.gloves] are in the way."
to_chat(user, "You are unable to wear \the [src] as \the [H.gloves] are in the way.")
gloves = null
return 0
H.drop_from_inventory(gloves)
@@ -30,7 +30,7 @@
gloves = null
return 0
if(gloves)
user << "You slip \the [src] on over \the [gloves]."
to_chat(user, "You slip \the [src] on over \the [gloves].")
wearer = H
return 1
@@ -39,6 +39,7 @@
if(gloves)
if(!H.equip_to_slot_if_possible(gloves, slot_gloves))
gloves.forceMove(get_turf(src))
if(ring)
gloves.ring = ring
src.gloves = null
wearer = null
..()
wearer = null
+8 -1
View File
@@ -31,12 +31,19 @@
//Chaplain
/obj/item/clothing/head/chaplain_hood
name = "chaplain's hood"
desc = "It's hood that covers the head. It keeps you warm during the space winters."
desc = "It's a hood that covers the head. It keeps you warm during the space winters."
icon_state = "chaplain_hood"
item_state_slots = list(slot_r_hand_str = "beret_black", slot_l_hand_str = "beret_black")
flags_inv = BLOCKHAIR
body_parts_covered = HEAD
//Chaplain but spookier
/obj/item/clothing/head/chaplain_hood/whiteout
name = "white hood"
desc = "It's a generic white hood. Very spooky."
icon_state = "whiteout_hood"
item_state_slots = list(slot_r_hand_str = "beret_white", slot_l_hand_str = "beret_white")
//Chaplain
/obj/item/clothing/head/nun_hood
name = "nun hood"
+5 -5
View File
@@ -16,17 +16,17 @@
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 75, rad = 0)
/obj/item/clothing/mask/gas/filter_air(datum/gas_mixture/air)
var/datum/gas_mixture/filtered = new
var/datum/gas_mixture/gas_filtered = new
for(var/g in filtered_gases)
if(air.gas[g])
filtered.gas[g] = air.gas[g] * gas_filter_strength
air.gas[g] -= filtered.gas[g]
gas_filtered.gas[g] = air.gas[g] * gas_filter_strength
air.gas[g] -= gas_filtered.gas[g]
air.update_values()
filtered.update_values()
gas_filtered.update_values()
return filtered
return gas_filtered
/obj/item/clothing/mask/gas/half
name = "face mask"
+47
View File
@@ -0,0 +1,47 @@
/////////////////////////////////////////
//Material Rings
/obj/item/clothing/gloves/ring/material
icon = 'icons/obj/clothing/rings.dmi'
icon_state = "material"
/obj/item/clothing/gloves/ring/material/New(var/newloc, var/new_material)
..(newloc)
if(!new_material)
new_material = DEFAULT_WALL_MATERIAL
material = get_material_by_name(new_material)
if(!istype(material))
qdel(src)
return
name = "[material.display_name] ring"
desc = "A ring made from [material.display_name]."
color = material.icon_colour
/obj/item/clothing/gloves/ring/material/get_material()
return material
/obj/item/clothing/gloves/ring/material/wood/New(var/newloc)
..(newloc, "wood")
/obj/item/clothing/gloves/ring/material/plastic/New(var/newloc)
..(newloc, "plastic")
/obj/item/clothing/gloves/ring/material/iron/New(var/newloc)
..(newloc, "iron")
/obj/item/clothing/gloves/ring/material/steel/New(var/newloc)
..(newloc, "steel")
/obj/item/clothing/gloves/ring/material/silver/New(var/newloc)
..(newloc, "silver")
/obj/item/clothing/gloves/ring/material/gold/New(var/newloc)
..(newloc, "gold")
/obj/item/clothing/gloves/ring/material/platinum/New(var/newloc)
..(newloc, "platinum")
/obj/item/clothing/gloves/ring/material/phoron/New(var/newloc)
..(newloc, "phoron")
/obj/item/clothing/gloves/ring/material/glass/New(var/newloc)
..(newloc, "glass")
+85
View File
@@ -0,0 +1,85 @@
/////////////////////////////////////////
//Standard Rings
/obj/item/clothing/gloves/ring/engagement
name = "engagement ring"
desc = "An engagement ring. It certainly looks expensive."
icon_state = "diamond"
/obj/item/clothing/gloves/ring/engagement/attack_self(mob/user)
user.visible_message("<span class='warning'>\The [user] gets down on one knee, presenting \the [src].</span>","<span class='warning'>You get down on one knee, presenting \the [src].</span>")
/obj/item/clothing/gloves/ring/cti
name = "CTI ring"
desc = "A ring commemorating graduation from CTI."
icon_state = "cti-grad"
/obj/item/clothing/gloves/ring/mariner
name = "Mariner University ring"
desc = "A ring commemorating graduation from Mariner University."
icon_state = "mariner-grad"
/////////////////////////////////////////
//Reagent Rings
/obj/item/clothing/gloves/ring/reagent
flags = OPENCONTAINER
origin_tech = list(TECH_MATERIAL = 2, TECH_ILLEGAL = 4)
/obj/item/clothing/gloves/ring/reagent/New()
..()
create_reagents(15)
/obj/item/clothing/gloves/ring/reagent/equipped(var/mob/living/carbon/human/H)
..()
if(istype(H) && H.gloves==src)
if(reagents.total_volume)
to_chat(H, "<span class='danger'>You feel a prick as you slip on \the [src].</span>")
if(H.reagents)
var/contained_reagents = reagents.get_reagents()
var/trans = reagents.trans_to_mob(H, 15, CHEM_BLOOD)
admin_inject_log(usr, H, src, contained_reagents, trans)
return
//Sleepy Ring
/obj/item/clothing/gloves/ring/reagent/sleepy
name = "silver ring"
desc = "A ring made from what appears to be silver."
icon_state = "material"
origin_tech = list(TECH_MATERIAL = 2, TECH_ILLEGAL = 5)
/obj/item/clothing/gloves/ring/reagent/sleepy/New()
..()
reagents.add_reagent(/datum/reagent/chloralhydrate, 15) // Less than a sleepy-pen, but still enough to knock someone out
/////////////////////////////////////////
//Seals and Signet Rings
/obj/item/clothing/gloves/ring/seal/secgen
name = "Secretary-General's official seal"
desc = "The official seal of the Secretary-General of the Sol Central Government, featured prominently on a silver ring."
icon_state = "seal-secgen"
/obj/item/clothing/gloves/ring/seal/mason
name = "masonic ring"
desc = "The Square and Compasses feature prominently on this Masonic ring."
icon_state = "seal-masonic"
/obj/item/clothing/gloves/ring/seal/signet
name = "signet ring"
desc = "A signet ring, for when you're too sophisticated to sign letters."
icon_state = "seal-signet"
var/nameset = 0
/obj/item/clothing/gloves/ring/seal/signet/attack_self(mob/user)
if(nameset)
to_chat(user, "<span class='notice'>The [src] has already been claimed!</span>")
return
to_chat(user, "<span class='notice'>You claim the [src] as your own!</span>")
change_name(user)
nameset = 1
/obj/item/clothing/gloves/ring/seal/signet/proc/change_name(var/signet_name = "Unknown")
name = "[signet_name]'s signet ring"
desc = "A signet ring belonging to [signet_name], for when you're too sophisticated to sign letters."
+5 -3
View File
@@ -36,13 +36,14 @@
user.update_inv_shoes() //so our mob-overlays update
user.update_action_buttons()
/obj/item/clothing/shoes/magboots/mob_can_equip(mob/user)
/obj/item/clothing/shoes/magboots/mob_can_equip(mob/user, slot)
var/mob/living/carbon/human/H = user
if(H.shoes)
shoes = H.shoes
if(shoes.overshoes)
user << "You are unable to wear \the [src] as \the [H.shoes] are in the way."
if(slot && slot == slot_shoes)
to_chat(user, "You are unable to wear \the [src] as \the [H.shoes] are in the way.")
shoes = null
return 0
H.drop_from_inventory(shoes) //Remove the old shoes so you can put on the magboots.
@@ -55,7 +56,8 @@
return 0
if (shoes)
user << "You slip \the [src] on over \the [shoes]."
if(slot && slot == slot_shoes)
to_chat(user, "You slip \the [src] on over \the [shoes].")
set_slowdown()
wearer = H
return 1
+9
View File
@@ -39,6 +39,15 @@
hoodtype = /obj/item/clothing/head/chaplain_hood
allowed = list (/obj/item/weapon/storage/bible)
//Chaplain but spookier
/obj/item/clothing/suit/storage/hooded/chaplain_hoodie/whiteout
name = "white robe"
desc = "A long, flowing white robe. It looks comfortable, but not very warm."
icon_state = "whiteout_robe"
item_state_slots = list(slot_r_hand_str = "suit_white", slot_l_hand_str = "suit_white")
flags_inv = HIDEJUMPSUIT|HIDETIE|HIDEHOLSTER
hoodtype = /obj/item/clothing/head/chaplain_hood/whiteout
//Chaplain
/obj/item/clothing/suit/nun
name = "nun robe"
+9 -3
View File
@@ -208,7 +208,7 @@
/obj/item/clothing/suit/iasexy
name = "sexy internal affairs suit"
desc = "Now where's your pen?~..."
desc = "Now where's your pen?~"
icon_state = "iacost"
body_parts_covered = UPPER_TORSO|FEET|LOWER_TORSO|EYES
flags_inv = HIDEJUMPSUIT|HIDESHOES|HIDETIE|HIDEHOLSTER
@@ -377,12 +377,18 @@ obj/item/clothing/suit/storage/toggle/peacoat
desc = "A thick jacket with a rubbery, water-resistant shell."
icon_state = "pufferjacket"
item_state_slots = list(slot_r_hand_str = "chainmail", slot_l_hand_str = "chainmail")
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
cold_protection = UPPER_TORSO|LOWER_TORSO|ARMS
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
flags_inv = HIDEHOLSTER
/obj/item/clothing/suit/jacket/puffer/vest
name = "puffer vest"
desc = "A thick vest with a rubbery, water-resistant shell."
icon_state = "puffervest"
item_state_slots = list(slot_r_hand_str = "chainmail", slot_l_hand_str = "chainmail")
body_parts_covered = UPPER_TORSO|LOWER_TORSO
cold_protection = UPPER_TORSO|LOWER_TORSO
/obj/item/clothing/suit/storage/miljacket
name = "military jacket"
@@ -590,7 +596,7 @@ obj/item/clothing/suit/storage/toggle/peacoat
/obj/item/clothing/suit/whitedress
name = "white dress"
desc = "A fancy white dress."
desc = "A fancy dress."
icon_state = "white_dress"
item_state_slots = list(slot_r_hand_str = "white_dress", slot_l_hand_str = "white_dress")
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS
@@ -827,7 +833,7 @@ obj/item/clothing/suit/storage/toggle/peacoat
*/
/obj/item/clothing/suit/storage/toggle/track
name = "track jacket"
desc = "a track jacket, for the athletic."
desc = "A track jacket, for the athletic."
icon_state = "trackjacket"
item_state_slots = list(slot_r_hand_str = "black_labcoat", slot_l_hand_str = "black_labcoat")
allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight,/obj/item/weapon/tank/emergency/oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask)
@@ -115,6 +115,58 @@
icon_state = "cargoponcho"
item_state = "cargoponcho"
/*
* Cloak
*/
/obj/item/clothing/accessory/poncho/roles/cloak
name = "brown cloak"
desc = "An elaborate brown cloak."
icon_state = "qmcloak"
item_state = "qmcloak"
body_parts_covered = null
/obj/item/clothing/accessory/poncho/roles/cloak/ce
name = "chief engineer's cloak"
desc = "An elaborate cloak worn by the chief engineer."
icon_state = "cecloak"
item_state = "cecloak"
/obj/item/clothing/accessory/poncho/roles/cloak/cmo
name = "chief medical officer's cloak"
desc = "An elaborate cloak meant to be worn by the chief medical officer."
icon_state = "cmocloak"
item_state = "cmocloak"
/obj/item/clothing/accessory/poncho/roles/cloak/hop
name = "head of personnel's cloak"
desc = "An elaborate cloak meant to be worn by the head of personnel."
icon_state = "hopcloak"
item_state = "hopcloak"
/obj/item/clothing/accessory/poncho/roles/cloak/rd
name = "research director's cloak"
desc = "An elaborate cloak meant to be worn by the research director."
icon_state = "rdcloak"
item_state = "rdcloak"
/obj/item/clothing/accessory/poncho/roles/cloak/qm
name = "quartermaster's cloak"
desc = "An elaborate cloak meant to be worn by the quartermaster."
icon_state = "qmcloak"
item_state = "qmcloak"
/obj/item/clothing/accessory/poncho/roles/cloak/hos
name = "head of security's cloak"
desc = "An elaborate cloak meant to be worn by the head of security."
icon_state = "hoscloak"
item_state = "hoscloak"
/obj/item/clothing/accessory/poncho/roles/cloak/captain
name = "colony director's cloak"
desc = "An elaborate cloak meant to be worn by the colony director."
icon_state = "capcloak"
item_state = "capcloak"
/obj/item/clothing/accessory/hawaii
name = "flower-pattern shirt"
desc = "You probably need some welder googles to look at this."
+2 -2
View File
@@ -16,7 +16,7 @@
/obj/item/clothing/under/rank/research_director/dress_rd
name = "research director dress uniform"
desc = "Feminine fashion for the style concious RD. Its fabric provides minor protection from biological contaminants."
desc = "Feminine fashion for the style conscious RD. Its fabric provides minor protection from biological contaminants."
icon_state = "dress_rd"
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0)
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
@@ -194,4 +194,4 @@
item_state_slots = list(slot_r_hand_str = "white", slot_l_hand_str = "white")
permeability_coefficient = 0.50
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0)
rolled_sleeves = 0
rolled_sleeves = 0
+3 -3
View File
@@ -363,13 +363,13 @@
/obj/item/clothing/under/dress/dress_cap
name = "colony director's dress uniform"
desc = "Feminine fashion for the style concious Colony Director."
desc = "Feminine fashion for the style conscious Colony Director."
icon_state = "dress_cap"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
/obj/item/clothing/under/dress/dress_hop
name = "head of personnel dress uniform"
desc = "Feminine fashion for the style concious HoP."
desc = "Feminine fashion for the style conscious HoP."
icon_state = "dress_hop"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
@@ -808,4 +808,4 @@
name = "bathrobe"
desc = "A fluffy robe to keep you from showing off to the world."
icon_state = "bathrobe"
worn_state = "bathrobe"
worn_state = "bathrobe"
@@ -85,12 +85,12 @@
//Normal valves
/obj/machinery/atmospherics/valve
description_info = "Click this to turn the valve. If red, the pipes on each end are seperated. Otherwise, they are connected."
description_info = "Click this to turn the valve. If red, the pipes on each end are separated. Otherwise, they are connected."
//TEG ports
/obj/machinery/atmospherics/binary/circulator
description_info = "This generates electricity, depending on the difference in temperature between each side of the machine. The meter in \
the center of the machine gives an indicator of how much elecrtricity is being generated."
the center of the machine gives an indicator of how much electricity is being generated."
//Passive gates
/obj/machinery/atmospherics/binary/passive_gate
@@ -118,7 +118,7 @@
//Gas injectors
/obj/machinery/atmospherics/unary/outlet_injector
description_info = "Outputs the pipe's gas into the atmosphere, similar to an airvent. It can be controlled by a nearby atmospherics computer. \
description_info = "Outputs the pipe's gas into the atmosphere, similar to an air vent. It can be controlled by a nearby atmospherics computer. \
A green light on it means it is on."
//Scrubbers
@@ -127,7 +127,7 @@
It can be controlled from an Air Alarm. It can be configured to drain all air rapidly with a 'panic syphon' from an air alarm."
//Omni filters
/obj/machinery/atmospherics/omni/filter
/obj/machinery/atmospherics/omni/atmos_filter
description_info = "Filters gas from a custom input direction, with up to two filtered outputs and a 'everything else' \
output. The filtered output's arrows glow orange."
@@ -23,7 +23,7 @@
description_fluff = "This is a NanoTrasen branded can of Lemon-Lime juice. NanoTrasen swears to their 'natural' beverage, but most people think differently."
/obj/item/weapon/reagent_containers/food/drinks/cans/iced_tea
description_fluff = "Vrisk Iced Tea is named after it's creator, Penelope Vrisk. She was a canner for Federov Beverages who wanted to create an authentic-tasting Southern iced tea. After finishing her formula and managing to get it produced, the tea became an instant hit."
description_fluff = "Vrisk Iced Tea is named after its creator, Penelope Vrisk. She was a canner for Federov Beverages who wanted to create an authentic-tasting Southern iced tea. After finishing her formula and managing to get it produced, the tea became an instant hit."
/obj/item/weapon/reagent_containers/food/drinks/cans/grape_juice
description_fluff = "This is a NanoTrasen branded can of grape juice. NanoTrasen claims that they use the same grapes that this juice is made of to make their wine."
@@ -33,3 +33,66 @@
/obj/item/weapon/reagent_containers/food/drinks/cans/sodawater
description_fluff = "This is a NanoTrasen branded can of soda water. They use the same water for this that they use for the bottled water that they sell. That may explain why the stuff isn't exactly flying off of the shelves."
/obj/item/weapon/reagent_containers/food/drinks/cans/gingerale
description_fluff = "Somehow, NanoTrasen wound up taking this ginger ale formula from Centauri Provisions, some say as payback for the DONKpocket incident. It tastes like ginger ale."
/obj/item/weapon/reagent_containers/food/drinks/bottle/gin
description_fluff = "Griffeater Gin was originally an independent disillery in Alpha Centauri, but financial troubles obligated them to sell out to Centauri Provisions. It's said that Centauri ruined the brew, but it's pretty much impossible to tell."
/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey
description_fluff = "Uncle Git's is a product of Abel's Rest, supply shortages and ubiqtuous observation during the occupation giving Takeshi 'Uncle' Git a chance to perfect this refinement of the common bathtub whiskey."
/obj/item/weapon/reagent_containers/food/drinks/bottle/specialwhiskey
description_fluff = "Nobody knows what Special Blend Whiskey really is, how it's made, or where it comes from. It's an expensive Gilthari product, for only the most luxurious, but NanoTrasen managed to secure a supply deal."
/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka
description_fluff = "Centauri Provisions claims that their vodka wins in blind taste-tests against traditional mixes from Earth, but they're not fooling anyone."
/obj/item/weapon/reagent_containers/food/drinks/bottle/tequilla
description_fluff = "This tequilla comes from the 'Cancer Craze' of the 20's, where consumer products would openly advertize their blatently carcinogenic nature to a burgeoning middle class with newfound access to cloned organs."
/obj/item/weapon/reagent_containers/food/drinks/bottle/patron
description_fluff = "This emerged as a response to Caccavo, with Patron advertising claiming to be even more toxic and dangerous. Unfortunately, when the Cancer Craze ended, Patron's stocks nosedived and they now operate only a handful of distilleries."
/obj/item/weapon/reagent_containers/food/drinks/bottle/rum
description_fluff = "Captain Pete's was involved in a long, expensive lawsuit against Gilthari concerning their claims to be from Cuba. They're actually owned and operated by none other than Centauri Provisions, with no distillaries on Earth to speak of."
/obj/item/weapon/reagent_containers/food/drinks/bottle/vermouth
description_fluff = "One of Gilthari's less expensive products, Goldeneye Vermouth still manages to sell itself as a drink for only the richest and most successful; giving any number of poseurs a swollen head in the process."
/obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua
description_fluff = "One of Centauri Provision's least successful products, this coffee liquour continues to be produced for the handful of mixed drinks requiring it. Surprisingly energizing!"
/obj/item/weapon/reagent_containers/food/drinks/bottle/goldschlager
description_fluff = "Drinks laced with gold and other precious metals are a common indulgence among those who live on planets where these metals are still somewhat rare and expensive. On asteroid colonies and better-developed regions, they're seen as a ridiculous waste of materials."
/obj/item/weapon/reagent_containers/food/drinks/bottle/cognac
description_fluff = "Another Gilthari product, Chataeu du Baton is one of the few brandies to still be produced using traditional methods, instead of chemical synthesizers."
/obj/item/weapon/reagent_containers/food/drinks/bottle/wine
description_fluff = "NanoTrasen makes this wine, which is generally regarded as better used for cooking than actually drinking. Morpheus specifically names Doublebeard in their recipe for Twobread."
/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe
description_fluff = "A product of the anarchists of Casini's Reach, Jailebreaker Verte is an open-source synthesized liquour that has actually managed to succeed over traditional absinthes. Gilthari is livid."
/obj/item/weapon/reagent_containers/food/drinks/bottle/melonliquor
description_fluff = "Melon liquor, formerly an obscure drink, took off when young Skrell started dabbling in alcohol. This brand is owned by Vey-Med, one of their few diversified holdings."
/obj/item/weapon/reagent_containers/food/drinks/bottle/bluecuracao
description_fluff = "Centauri Provisions is currently marketing Miss Blue as the next big thing in mixed drinks. Analysts suggest that they're mistaken."
/obj/item/weapon/reagent_containers/food/drinks/bottle/pwine
description_fluff = "You've never heard of this before, but it looks vaguely Gilthari, so it's probably good, right?"
/obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice
description_fluff = "Morpheus used to sell 'Tomato Juice' that was actually synthetic blood in a carton, until they got sued for damages."
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer
description_fluff = "Getting synthesized booze to taste decent is always a challenge, but Space Beer is a resounding success. As the most popular drink in human space, it'd have to be."
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale
description_fluff = "A product of Titan and enjoyed widely among the hydrocarbon workers of the oil moon. Often described as 'Beer, but better.'"
/obj/item/weapon/reagent_containers/food/drinks/bottle/sake
description_fluff = "An export from New Kyoto, Mono-no-Aware promises to show to the drinker the beautiful transience of all life. Mostly it just tastes like dry booze."
@@ -10,7 +10,7 @@
Touching the supermatter will result in *instant death*, with no corpse left behind! You can drag the supermatter, but anything else will kill you. \
It is advised to obtain a genetic backup before trying to drag it."
description_antag = "Exposing the supermatter to oxygen or vaccum will cause it to start rapidly heating up. Sabotaging the supermatter and making it explode will \
description_antag = "Exposing the supermatter to oxygen or vacuum will cause it to start rapidly heating up. Sabotaging the supermatter and making it explode will \
cause a period of lag as the explosion is processed by the server, as well as irradiating the entire station and causing hallucinations to happen. \
Wearing radiation equipment will protect you from most of the delamination effects sans explosion."
@@ -75,4 +75,4 @@
results += "[desc_panel_image("wrench")]to connect or disconnect from a connector port below."
results += "[desc_panel_image("air tank")]to fill the air tank from this canister."
return results
return results
+2 -2
View File
@@ -1,8 +1,8 @@
/mob/living/silicon/robot/drone
description_info = "Drones are player-controlled synthetics which are lawed to maintain the station and not \
interact with anyone else, except for other drones. They hold a wide array of tools to build, repair, maintain, and clean. \
They fuction similarly to other synthetics, in that they require recharging regularly, have laws, and are resilient to many hazards, \
They function similarly to other synthetics, in that they require recharging regularly, have laws, and are resilient to many hazards, \
such as fire, radiation, vacuum, and more. Ghosts can join the round as a maintenance drone by using the appropriate verb in the 'ghost' tab. \
An inactive drone can be rebooted by swiping an ID card on it with engineering or robotics access, and an active drone can be shut down in the same manner."
description_antag = "An Electromagnetic Sequencer can be used to subvert the drone to your cause."
description_antag = "An Electromagnetic Sequencer can be used to subvert the drone to your cause."
@@ -1,7 +1,7 @@
/obj/structure/girder
description_info = "Use metal sheets on this to build a normal wall. Adding plasteel instead will make a reinforced wall.<br>\
A false wall can be made by using a crowbar on this girder, and then adding metal or plasteel.<br>\
You can dismantle the grider with a wrench."
You can dismantle the girder with a wrench."
/obj/structure/girder/reinforced
description_info = "Add another sheet of plasteel to finish."
@@ -18,4 +18,4 @@
description_info = "Click and drag yourself (or anyone) to this to buckle in. Click on this with an empty hand to undo the buckles.<br>\
<br>\
Anyone with restraints, such as handcuffs, will not be able to unbuckle themselves. They must use the Resist button, or verb, to break free of \
the buckles, instead."
the buckles, instead."
+2 -2
View File
@@ -50,7 +50,7 @@
/obj/item/weapon/gun/projectile
description_info = "This is a ballistic weapon. To fire the weapon, ensure your intent is *not* set to 'help', have your gun mode set to 'fire', \
then click where you want to fire. To reload, click the weapon in your hand to unload (if needed), then add the appropiate ammo. The description \
then click where you want to fire. To reload, click the weapon in your hand to unload (if needed), then add the appropriate ammo. The description \
will tell you what caliber you need."
/obj/item/weapon/gun/energy/chameleon
@@ -89,4 +89,4 @@
it can be concealed in your pocket or bag."
/obj/item/weapon/melee/cultblade
description_antag = "This sword is a powerful weapon, capable of severing limbs easily, if they are targeted. Nonbelivers are unable to use this weapon."
description_antag = "This sword is a powerful weapon, capable of severing limbs easily, if they are targeted. Nonbelievers are unable to use this weapon."
@@ -91,7 +91,7 @@
/datum/lore/codex/page/southern_cross/add_content()
name = "Southern Cross (Artificial Satellite)"
keywords += list("Southern Cross")
keywords += list("Southern Cross", "NLS Southern Cross")
data = "The Southern Cross is a telecommunications and supply hub for [quick_link("NanoTrasen")], named after it's companion satellite, the \
[quick_link("Northern Star")]. It acts as a logistics hub for the smaller installations NanoTrasen has in Sif orbit and on the surface."
@@ -12,6 +12,8 @@
recipes += new/datum/stack_recipe("[display_name] spoon", /obj/item/weapon/material/kitchen/utensil/spoon/plastic, 1, on_floor = 1, supplied_material = "[name]")
recipes += new/datum/stack_recipe("[display_name] armor plate", /obj/item/weapon/material/armor_plating, 1, time = 20, on_floor = 1, supplied_material = "[name]")
recipes += new/datum/stack_recipe("[display_name] grave marker", /obj/item/weapon/material/gravemarker, 5, time = 50, supplied_material = "[name]")
recipes += new/datum/stack_recipe("[display_name] ring", /obj/item/clothing/gloves/ring/material, 1, on_floor = 1, supplied_material = "[name]")
if(integrity>=50)
recipes += new/datum/stack_recipe("[display_name] door", /obj/structure/simple_door, 10, one_per_turf = 1, on_floor = 1, supplied_material = "[name]")
@@ -135,6 +137,7 @@
recipes += new/datum/stack_recipe("book shelf", /obj/structure/bookcase, 5, time = 15, one_per_turf = 1, on_floor = 1)
recipes += new/datum/stack_recipe("noticeboard frame", /obj/item/frame/noticeboard, 4, time = 5, one_per_turf = 0, on_floor = 1)
recipes += new/datum/stack_recipe("wooden bucket", /obj/item/weapon/reagent_containers/glass/bucket/wood, 2, time = 4, one_per_turf = 0, on_floor = 0)
recipes += new/datum/stack_recipe("coilgun stock", /obj/item/weapon/coilgun_assembly, 5)
/material/cardboard/generate_recipes()
..()
+8
View File
@@ -34,4 +34,12 @@
on_created_text = "<span class='warning'>Life suddenly feels more precious.</span>"
on_expired_text = "<span class='notice'>Death is cheap again.</span>"
flags = MODIFIER_GENETIC
// Prevents borging (specifically the MMI part), actual effect is on the MMI.
/datum/modifier/no_borg
name = "Cyboernetic Incompatability"
desc = "For whatever reason, your brain is incompatable with direct cybernetic interfaces, such as the MMI."
flags = MODIFIER_GENETIC
+73 -2
View File
@@ -37,6 +37,10 @@
var/slowdown // Negative numbers speed up, positive numbers slow down movement.
var/haste // If set to 1, the mob will be 'hasted', which makes it ignore slowdown and go really fast.
var/evasion // Positive numbers reduce the odds of being hit by 15% each. Negative numbers increase the odds.
var/bleeding_rate_percent // Adjusts amount of blood lost when bleeding.
var/accuracy // Positive numbers makes hitting things with guns easier, negatives make it harder. Each point makes it 15% easier or harder, just like evasion.
var/accuracy_dispersion // Positive numbers make gun firing cover a wider tile range, and therefore more inaccurate. Negatives help negate dispersion penalties.
var/metabolism_percent // Adjusts the mob's metabolic rate, which affects reagent processing. Won't affect mobs without reagent processing.
/datum/modifier/New(var/new_holder, var/new_origin)
holder = new_holder
@@ -123,7 +127,7 @@
// Removes all modifiers of a type
/mob/living/proc/remove_modifiers_of_type(var/modifier_type, var/silent = FALSE)
for(var/datum/modifier/M in modifiers)
if(istype(M, modifier_type))
if(ispath(M.type, modifier_type))
M.expire(silent)
// Removes all modifiers, useful if the mob's being deleted
@@ -136,4 +140,71 @@
for(var/datum/modifier/M in modifiers)
if(istype(M, modifier_type))
return TRUE
return FALSE
return FALSE
// This displays the actual 'numbers' that a modifier is doing. Should only be shown in OOC contexts.
// When adding new effects, be sure to update this as well.
/datum/modifier/proc/describe_modifier_effects()
var/list/effects = list()
if(!isnull(max_health_flat))
effects += "You [max_health_flat > 0 ? "gain" : "lose"] [abs(max_health_flat)] maximum health."
if(!isnull(max_health_percent))
effects += "You [max_health_percent > 1.0 ? "gain" : "lose"] [multipler_to_percentage(max_health_percent, TRUE)] maximum health."
if(!isnull(disable_duration_percent))
effects += "Disabling effects on you last [multipler_to_percentage(disable_duration_percent, TRUE)] [disable_duration_percent > 1.0 ? "longer" : "shorter"]"
if(!isnull(incoming_damage_percent))
effects += "You take [multipler_to_percentage(incoming_damage_percent, TRUE)] [incoming_damage_percent > 1.0 ? "more" : "less"] damage."
if(!isnull(incoming_brute_damage_percent))
effects += "You take [multipler_to_percentage(incoming_brute_damage_percent, TRUE)] [incoming_brute_damage_percent > 1.0 ? "more" : "less"] brute damage."
if(!isnull(incoming_fire_damage_percent))
effects += "You take [multipler_to_percentage(incoming_fire_damage_percent, TRUE)] [incoming_fire_damage_percent > 1.0 ? "more" : "less"] fire damage."
if(!isnull(incoming_tox_damage_percent))
effects += "You take [multipler_to_percentage(incoming_tox_damage_percent, TRUE)] [incoming_tox_damage_percent > 1.0 ? "more" : "less"] toxin damage."
if(!isnull(incoming_oxy_damage_percent))
effects += "You take [multipler_to_percentage(incoming_oxy_damage_percent, TRUE)] [incoming_oxy_damage_percent > 1.0 ? "more" : "less"] oxy damage."
if(!isnull(incoming_clone_damage_percent))
effects += "You take [multipler_to_percentage(incoming_clone_damage_percent, TRUE)] [incoming_clone_damage_percent > 1.0 ? "more" : "less"] clone damage."
if(!isnull(incoming_hal_damage_percent))
effects += "You take [multipler_to_percentage(incoming_hal_damage_percent, TRUE)] [incoming_hal_damage_percent > 1.0 ? "more" : "less"] agony damage."
if(!isnull(incoming_healing_percent))
effects += "Healing applied to you is [multipler_to_percentage(incoming_healing_percent, TRUE)] [incoming_healing_percent > 1.0 ? "stronger" : "weaker"]."
if(!isnull(outgoing_melee_damage_percent))
effects += "Damage you do with melee weapons and unarmed combat is [multipler_to_percentage(outgoing_melee_damage_percent, TRUE)] \
[outgoing_melee_damage_percent > 1.0 ? "higher" : "lower"]."
if(!isnull(slowdown))
effects += "[slowdown > 0 ? "lose" : "gain"] [slowdown] slowdown."
if(!isnull(haste))
effects += "You move at maximum speed, and cannot be slowed by any means."
if(!isnull(evasion))
effects += "You are [abs(evasion * 15)]% [evasion > 0 ? "harder" : "easier"] to hit with weapons."
if(!isnull(bleeding_rate_percent))
effects += "You bleed [multipler_to_percentage(bleeding_rate_percent, TRUE)] [bleeding_rate_percent > 1.0 ? "faster" : "slower"]."
if(!isnull(accuracy))
effects += "It is [abs(accuracy * 15)]% [accuracy > 0 ? "easier" : "harder"] for you to hit someone with a ranged weapon."
if(!isnull(accuracy_dispersion))
effects += "Projectiles you fire are [accuracy_dispersion > 0 ? "more" : "less"] likely to stray from your intended target."
if(!isnull(metabolism_percent))
effects += "Your metabolism is [metabolism_percent > 1.0 ? "faster" : "slower"], \
causing reagents in your body to process, and hunger to occur [multipler_to_percentage(metabolism_percent, TRUE)] [metabolism_percent > 1.0 ? "faster" : "slower"]."
return jointext(effects, "<br>")
// Helper to format multiplers (e.g. 1.4) to percentages (like '40%')
/proc/multipler_to_percentage(var/multi, var/abs = FALSE)
if(abs)
return "[abs( ((multi - 1) * 100) )]%"
return "[((multi - 1) * 100)]%"
+56 -5
View File
@@ -1,10 +1,61 @@
/datum/modifier/frail
name = "frail"
desc = "You are more delicate than the average person."
/datum/modifier/trait
flags = MODIFIER_GENETIC // We want traits to persist if the person gets cloned.
flags = MODIFIER_GENETIC
/datum/modifier/trait/flimsy
name = "flimsy"
desc = "You're more fragile than most, and have less of an ability to endure harm."
on_created_text = "<span class='warning'>You feel rather weak.</span>"
on_expired_text = "<span class='notice'>You feel your strength returning to you.</span>"
max_health_percent = 0.8
/datum/modifier/trait/frail
name = "frail"
desc = "Your body is very fragile, and has even less of an ability to endure harm."
on_created_text = "<span class='warning'>You feel really weak.</span>"
on_expired_text = "<span class='notice'>You feel your strength returning to you.</span>"
max_health_percent = 0.9
max_health_percent = 0.6
/datum/modifier/trait/weak
name = "weak"
desc = "A lack of physical strength causes a diminshed capability in close quarters combat"
outgoing_melee_damage_percent = 0.8
/datum/modifier/trait/wimpy
name = "wimpy"
desc = "An extreme lack of physical strength causes greatly diminished capability in close quarters combat."
outgoing_melee_damage_percent = 0.6
/datum/modifier/trait/haemophilia
name = "haemophilia"
desc = "You bleed much faster than average."
bleeding_rate_percent = 3.0
/datum/modifier/trait/inaccurate
name = "Inaccurate"
desc = "You're rather inexperienced with guns, you've never used one in your life, or you're just really rusty. \
Regardless, you find it quite difficult to land shots where you wanted them to go."
accuracy = -1
accuracy_dispersion = 1
/datum/modifier/trait/high_metabolism
name = "High Metabolsim"
desc = "Your body's metabolism is faster than average."
metabolism_percent = 2.0
incoming_healing_percent = 1.4
/datum/modifier/trait/low_metabolism
name = "Low Metabolism"
desc = "Your body's metabolism is slower than average."
metabolism_percent = 0.5
incoming_healing_percent = 0.6
@@ -0,0 +1,491 @@
// Gives various spooky messages to people afraid of a specific thing.
// Doesn't have any real mechanical effect, and is more of an aid to remind someone "You're supposed to be afraid of the dark", and such.
/datum/modifier/trait/phobia
var/current_fear = 0 // Counter for how 'afraid' the holder is.
var/max_fear = 100 // Cap for current_fear.
var/fear_decay_rate = 1 // How much is subtracted every Life() tick when not being spooked by something.
var/list/zero_fear_up = list() // Message displayed to holder when current_fear raises above 0.
var/list/zero_fear_down = list() // Message displayed when reaching 0.
var/list/half_fear_up = list() // Message displayed when current_fear passes half of max_fear.
var/list/half_fear_down = list() // Message displayed when current_fear goes below half of max_fear.
var/list/full_fear_up = list() // Similar to above, but for the cap.
var/list/full_fear_down = list() // Ditto.
/datum/modifier/trait/phobia/tick()
if(holder.stat)
return // You got bigger problems.
var/new_fear = should_fear()
if(new_fear)
adjust_fear(new_fear)
else
adjust_fear(-fear_decay_rate)
/datum/modifier/trait/phobia/proc/adjust_fear(var/amount)
var/last_fear = current_fear
current_fear = between(0, current_fear + amount, max_fear)
// Handle messages. safepick() is used so that if no messages are defined, it just does nothing, verses runtiming.
var/message = null
if(amount > 0) // Increase in spooks.
if(current_fear == max_fear && last_fear < max_fear)
message = safepick(full_fear_up)
else if(current_fear >= (max_fear / 2) && last_fear < (max_fear / 2))
message = safepick(half_fear_up)
else if(current_fear > 0 && last_fear == 0)
message = safepick(zero_fear_up)
else if(amount < 0) // Decrease in spooks.
if(last_fear == max_fear && current_fear < max_fear)
message = safepick(full_fear_down)
else if(last_fear >= (max_fear / 2) && current_fear < (max_fear / 2))
message = safepick(half_fear_down)
else if(last_fear > 0 && current_fear == 0)
message = safepick(zero_fear_down)
if(message)
to_chat(holder, message)
// Override for specific fears, e.g. seeing blood or spiders.
/datum/modifier/trait/phobia/proc/should_fear()
return FALSE
// Actual phobia trait implementations below.
/datum/modifier/trait/phobia/haemophobia
name = "haemophobia"
desc = "Seeing a bunch of blood isn't really pleasant for most people, but for you, it is very distressing."
fear_decay_rate = 4
on_created_text = "<span class='warning'>You are terrified of seeing blood.</span>"
on_expired_text = "<span class='notice'>You feel that blood doesn't bother you, at least, as much as it used to.</span>"
zero_fear_up = list(
"<span class='warning'><font size='3'>You see some blood nearby...</font></span>",
"<span class='warning'><font size='3'>You try to avoid looking at the blood nearby.</font></span>"
)
zero_fear_down = list(
"<span class='notice'>You feel better now, with no blood in sight.</span>",
"<span class='notice'>At last, the blood is gone.</span>",
"<span class='notice'>Hopefully you won't see anymore blood today.</span>"
)
half_fear_up = list(
"<span class='danger'><font size='3'>You're still near the blood!</font></span>",
"<span class='danger'><font size='3'>So much blood... You can't stand it.</font></span>"
)
half_fear_down = list(
"<span class='warning'>The blood is gone now, but you're still worked up.</span>",
"<span class='warning'>You can't see the blood now, but you're still anxious.</span>"
)
full_fear_up = list(
"<span class='danger'><font size='4'>The blood is too much!</font></span>",
"<span class='danger'><font size='4'>There is so much blood here, you need to leave!</font></span>",
"<span class='danger'><font size='4'>You gotta get away from the blood!</font></span>"
)
full_fear_down = list(
"<span class='danger'>The blood is gone, but you're still very anxious.</span>",
"<span class='danger'>No more blood... Please.</span>"
)
/datum/modifier/trait/phobia/haemophobia/check_if_valid()
if(iscultist(holder)) // Nar-nar can't be having cultists afraid of blood.
expire()
else
..()
/datum/modifier/trait/phobia/haemophobia/should_fear()
if(holder.blinded)
return 0 // Can't fear what cannot be seen.
var/fear_amount = 0
for(var/atom/thing in view(5, holder)) // It's 5 and not 7 so players have a chance to go away before getting the prompts, and for performance.
// Blood stains are bad.
if(istype(thing, /obj/effect/decal/cleanable/blood))
var/obj/effect/decal/cleanable/blood/B = thing
// Tracks are special, apparently.
if(istype(thing, /obj/effect/decal/cleanable/blood/tracks))
var/obj/effect/decal/cleanable/blood/tracks/T = B
for(var/datum/fluidtrack/F in T.stack)
if(F.basecolor != SYNTH_BLOOD_COLOUR)
fear_amount++
break
else
if(B.basecolor != SYNTH_BLOOD_COLOUR)
fear_amount++
// People covered in blood is also bad.
// Feel free to trim down if its too expensive CPU wise.
if(istype(thing, /mob/living/carbon/human))
var/mob/living/carbon/human/H = thing
var/self_multiplier = H == holder ? 2 : 1
var/human_blood_fear_amount = 0
if(!H.gloves && H.bloody_hands && H.hand_blood_color != SYNTH_BLOOD_COLOUR)
human_blood_fear_amount += 1
if(!H.shoes && H.feet_blood_color && H.feet_blood_color != SYNTH_BLOOD_COLOUR)
human_blood_fear_amount += 1
// List of slots. Some slots like pockets are omitted due to not being visible, if H isn't the holder.
var/list/clothing_slots = list(H.back, H.wear_mask, H.l_hand, H.r_hand, H.wear_id, H.glasses, H.gloves, H.head, H.shoes, H.belt, H.wear_suit, H.w_uniform, H.s_store, H.l_ear, H.r_ear)
if(H == holder)
clothing_slots += list(H.l_store, H.r_store)
for(var/obj/item/clothing/C in clothing_slots)
if(C.blood_DNA && C.blood_color && C.blood_color != SYNTH_BLOOD_COLOUR)
human_blood_fear_amount += 1
// This is divided, since humans can wear so many items at once.
human_blood_fear_amount = round( (human_blood_fear_amount * self_multiplier) / 3, 1)
fear_amount += human_blood_fear_amount
// Bloody objects are also bad.
if(istype(thing, /obj))
var/obj/O = thing
if(O.blood_DNA && O.blood_color && O.blood_color != SYNTH_BLOOD_COLOUR)
fear_amount++
return fear_amount
/datum/modifier/trait/phobia/arachnophobe
name = "arachnophobia"
desc = "Spiders are quite creepy to most people, however for you, those chitters of pure evil inspire pure dread and fear."
fear_decay_rate = 1
on_created_text = "<span class='warning'>You are terrified of seeing spiders.</span>"
on_expired_text = "<span class='notice'>You feel that your fear of spiders has gone from 'crippling' to 'nope nope nope', which is still an improvement.</span>"
zero_fear_up = list(
"<span class='warning'><font size='3'>You see a spider!</font></span>",
"<span class='warning'><font size='3'>Spider!</font></span>"
)
zero_fear_down = list(
"<span class='notice'>Those evil spiders are finally gone.</span>",
"<span class='notice'>At last, the chitters are gone.</span>",
"<span class='notice'>The spiders are gone, at last.</span>"
)
half_fear_up = list(
"<span class='danger'><font size='3'>The spiders are gonna eat you!</font></span>",
"<span class='danger'><font size='3'>The spiders are still here!</font></span>",
"<span class='danger'><font size='3'>The spiders will lay eggs inside you if you don't run!</font></span>",
)
half_fear_down = list(
"<span class='warning'>The spiders are gone... right?</span>",
"<span class='warning'>You can't see any spiders now, but you're still anxious.</span>"
)
full_fear_up = list(
"<span class='danger'><font size='4'>The chittering is driving you mad!</font></span>",
"<span class='danger'><font size='4'>You're gonna be spider-food if you don't run!</font></span>",
"<span class='danger'><font size='4'>The spiders are gonna feast on your eyes!</font></span>"
)
full_fear_down = list(
"<span class='danger'>The spiders must surely be hiding somewhere...</span>",
"<span class='danger'>No more spiders... Please.</span>"
)
/datum/modifier/trait/phobia/arachnophobe/should_fear()
if(holder.blinded)
return 0 // Can't fear what cannot be seen.
var/fear_amount = 0
for(var/atom/thing in view(5, holder)) // See haemophobia for why this is 5.
if(istype(thing, /obj/effect/decal/cleanable/spiderling_remains)) // Dead spiderlings are a bit spooky.
fear_amount += 1
if(istype(thing, /obj/effect/spider/spiderling)) // Live spiderlings are also spooky.
fear_amount += 2
if(istype(thing, /obj/item/toy/plushie/spider)) // Plushies are spooky so people can be assholes with them.
fear_amount += 1
if(istype(thing, /mob/living/simple_animal/hostile/giant_spider)) // Actual giant spiders are the scariest of them all.
var/mob/living/simple_animal/hostile/giant_spider/S = thing
if(S.stat == DEAD) // Dead giant spiders are less scary than alive ones.
fear_amount += 4
else
fear_amount += 8
return fear_amount
/datum/modifier/trait/phobia/nyctophobe
name = "nyctophobia"
desc = "More commonly known as the fear of darkness. The shadows can hide many dangers, which makes the prospect of going into the depths of Maintenance rather worrisome."
fear_decay_rate = 5
on_created_text = "<span class='warning'>You are terrified of the dark.</span>"
on_expired_text = "<span class='notice'>You feel that darkness isn't quite as scary anymore.</span>"
var/fear_threshold = 0.5 // Average lighting needs to be below this to start increasing fear.
zero_fear_up = list(
"<span class='warning'><font size='3'>It's so dark here!</font></span>",
"<span class='warning'><font size='3'>It's too dark!</font></span>"
)
zero_fear_down = list(
"<span class='notice'>You feel calmer, now that you're in the light.</span>",
"<span class='notice'>At last, no more darkness.</span>",
"<span class='notice'>The light makes you feel calmer.</span>"
)
half_fear_up = list(
"<span class='danger'><font size='3'>You need to escape this darkness!</font></span>",
"<span class='danger'><font size='3'>Something might be lurking near you, but you can't see in this darkness.</font></span>",
"<span class='danger'><font size='3'>You need to find a light!</font></span>",
)
half_fear_down = list(
"<span class='warning'>The darkness is gone, for now...</span>",
"<span class='warning'>You're not in the dark anymore, but you're still anxious.</span>"
)
full_fear_up = list(
"<span class='danger'><font size='4'>What was that?</font></span>",
"<span class='danger'><font size='4'>Something is nearby...</font></span>"
)
full_fear_down = list(
"<span class='danger'>Light, at last!</span>",
"<span class='danger'>The darkness is finally gone!</span>"
)
/datum/modifier/trait/phobia/nyctophobe/should_fear()
if(holder.blinded)
return 5 // Unlike most other fears coded here, being blind when afraid of darkness is pretty bad, I imagine.
if(holder.see_in_dark >= 5)
return 0 // What darkness?
var/fear_amount = 0
var/total_lum = 0
var/total_tiles = 0
var/average_lum = null
for(var/turf/simulated/T in view(5, get_turf(holder))) // See haemophobia for why this is 5. This uses get_turf() since darkness makes tiles not visible to holder.
total_lum += T.get_lumcount()
total_tiles++
average_lum = total_lum / total_tiles
if(average_lum > fear_threshold)
switch(average_lum)
if(0.0 to 0.1)
fear_amount += 5
if(0.1 to 0.2)
fear_amount += 4
if(0.2 to 0.3)
fear_amount += 3
if(0.3 to 0.4)
fear_amount += 2
if(0.4 to 0.5)
fear_amount += 1
var/turf/T = get_turf(holder)
if(T.get_lumcount() <= LIGHTING_SOFT_THRESHOLD) // Standing in complete darkness.
fear_amount += 5
return fear_amount
/datum/modifier/trait/phobia/claustrophobe
name = "claustrophobia"
desc = "Small spaces and tight quarters makes you feel distressed. Unfortunately both are rather common when living in space."
fear_decay_rate = 2
var/open_tiles_needed = 15 // Tends to be just right, as maint triggers this but hallways don't.
on_created_text = "<span class='warning'>You are terrified of tight spaces. Why did you come to space??</span>"
on_expired_text = "<span class='notice'>Small rooms aren't so bad now.</span>"
zero_fear_up = list(
"<span class='warning'><font size='3'>This room is too small...</font></span>",
"<span class='warning'><font size='3'>The walls are too close together...</font></span>"
)
zero_fear_down = list(
"<span class='notice'>You feel calmer, now that you're in a larger room.</span>",
"<span class='notice'>At last, the walls are far apart.</span>",
"<span class='notice'>The relatively open area makes you feel calmer.</span>"
)
half_fear_up = list(
"<span class='danger'><font size='3'>Your surroundings look like they are closing in.</font></span>",
"<span class='danger'><font size='3'>Is the room getting smaller?</font></span>",
"<span class='danger'><font size='3'>You need to get out of here!</font></span>",
)
half_fear_down = list(
"<span class='warning'>Your surroundings seem to have stopped closing in.</span>",
"<span class='warning'>You're not in a tight space anymore, but you're still anxious.</span>"
)
full_fear_up = list(
"<span class='danger'><font size='4'>You need to escape!</font></span>",
"<span class='danger'><font size='4'>There's barely any room to move around!</font></span>"
)
full_fear_down = list(
"<span class='danger'>The surroundings stop shrinking.</span>",
"<span class='danger'>The walls seem to have stopped.</span>"
)
/datum/modifier/trait/phobia/claustrophobe/should_fear()
if(holder.blinded)
return 0 // No idea if this is accurate.
if(holder.loc && !isturf(holder.loc)) // Hiding in a locker or inside an exosuit is spooky.
return 5
var/fear_amount = 0
var/open_tiles = 0
var/radius = 5 // See haemophobia for why this is 5.
var/max_open_tiles = radius * radius // Potential maximum tiles. In practice it will be rare for someone to be inside a 5x5 plane.
for(var/turf/T in view(radius, holder))
var/open = TRUE
if(T.density)
continue
for(var/atom/movable/AM in T)
if(AM.density)
open = FALSE
break
if(open)
open_tiles++
if(open_tiles < open_tiles_needed)
var/fear_reduction = abs( (open_tiles / max_open_tiles) - 1) // The smaller the space, the smaller this number is, and fear will build up faster.
fear_amount = 5 * fear_reduction
return fear_amount
// Note for the below 'phobias' are of the xeno-phobic variety, and are less centered on pure fear as above, and more on a mix of distrust, fear, and disdainfulness.
// As such, they are mechanically different than the fear-based phobias, in that instead of a buildup of fearful messages, it does intermittent messages specific to what holder sees.
// This is the catch-all 'everyone but [my species] is up to no good' trait, as opposed to the other specialized variants.
/datum/modifier/trait/phobia/xenophobia
name = "xenophobia"
desc = "The mind of the Alien is unknowable, and as such, their intentions cannot be known. You always watch the xenos closely, as they most certainly are watching you \
closely, waiting to strike."
on_created_text = "<span class='warning'>You remain vigilant against the Alien.</span>"
on_expired_text = "<span class='notice'>Aliens aren't so bad afterall.</span>"
var/last_message = null // world.time we last did a message.
var/message_cooldown = 1 MINUTE
/datum/modifier/trait/phobia/xenophobia/tick()
if(holder.stat)
return // You got bigger problems.
if(last_message + message_cooldown <= world.time)
if(intermittent_message())
last_message = world.time
/datum/modifier/trait/phobia/xenophobia/proc/intermittent_message()
var/list/xenos = get_xenos()
if(xenos.len)
var/chosen_xeno = pick(xenos)
to_chat(holder, "<span class='warning'><font size='3'>[make_message(chosen_xeno)]</font></span>")
return TRUE
else
return FALSE // No xenos in sight, so don't apply the cooldown.
/datum/modifier/trait/phobia/xenophobia/proc/get_xenos()
return list()
/datum/modifier/trait/phobia/xenophobia/proc/make_message(var/mob/living/L)
return "Someone forgot to override this output message."
// This is the catch-all 'everyone but [my species] is up to no good' trait, as opposed to the other specialized variants.
/datum/modifier/trait/phobia/xenophobia/generic
name = "xenophobia"
desc = "The mind of the Alien is unknowable, and as such, their intentions cannot be known. You always watch the xenos closely, as they most certainly are watching you \
closely, waiting to strike."
on_created_text = "<span class='warning'>You remain vigilant against the Alien.</span>"
on_expired_text = "<span class='notice'>Aliens aren't so bad afterall.</span>"
/datum/modifier/trait/phobia/xenophobia/generic/get_xenos()
var/list/xenos = list()
if(!ishuman(holder))
return
var/mob/living/carbon/human/us = holder
for(var/mob/living/carbon/human/H in view(5, holder)) // See haemophobia for why this is 5.
if(!(istype(us.species, H.species) )) // Are they a different species?
xenos += H
return xenos
/datum/modifier/trait/phobia/xenophobia/generic/make_message(var/mob/living/carbon/human/H)
// Do special responses first if possible.
// if(H.stat == DEAD)
// return pick( list("Unsurprising to see a weak and inferior [H.species.name] fail to survive.", "If that [H.species.name] were a [holder.species.name], this wouldn't've have happened.") )
// Generic responses if none of the above apply.
var/list/generic_responses = list(
"That [H.species.name] is likely trying to spy on you.",
"[H.species.name_plural] tend to be ugly, but this one near you is even worse!",
"[H.species.name] scum.",
"The [H.species.name] nearby is certainly a spy for Them.",
"That [H.species.name] smells awful.",
"Can't trust [H.species.name_plural]."
)
return pick(generic_responses)
// *********
// * Human *
// *********
/datum/modifier/trait/phobia/xenophobia/human
name = "anti-human sentiment"
desc = "Humans are bound to get us all killed with their reckless use of technology..."
on_created_text = "<span class='warning'>You unfortunately are likely to have to deal with humans today.</span>"
on_expired_text = "<span class='notice'>Humans aren't so bad afterall.</span>"
/datum/modifier/trait/phobia/xenophobia/human/get_xenos()
var/list/humans = list()
for(var/mob/living/carbon/human/H in view(5, holder)) // See haemophobia for why this is 5.
if(H == holder)
continue // No self loathing here.
if(istype(H.species, /datum/species/human) ) // Are they a human.
humans += H
return humans
/datum/modifier/trait/phobia/xenophobia/human/make_message(var/mob/living/carbon/human/H)
// Do special responses first if possible.
// Generic responses if none of the above apply.
var/list/generic_responses = list(
"Why did you travel to human space? It's full of them."
)
return pick(generic_responses)
// **********
// * Skrell *
// **********
/datum/modifier/trait/phobia/xenophobia/skrell
name = "anti-skrell sentiment"
desc = "The Skrell pretend that they are Humanity's enlightened allies, but you can see past that."
on_created_text = "<span class='warning'>Hopefully no Skrell show up today.</span>"
on_expired_text = "<span class='notice'>Skrell aren't so bad afterall.</span>"
/datum/modifier/trait/phobia/xenophobia/skrell/get_xenos()
var/list/skrell = list()
for(var/mob/living/carbon/human/H in view(5, holder)) // See haemophobia for why this is 5.
if(H == holder)
continue // No self loathing here.
if(istype(H.species, /datum/species/skrell) ) // Are they a squid now?
skrell += H
return skrell
/datum/modifier/trait/phobia/xenophobia/skrell/make_message(var/mob/living/carbon/human/H)
// Do special responses first if possible.
// Generic responses if none of the above apply.
var/list/generic_responses = list(
"WetSkrell was a mistake."
)
return pick(generic_responses)
@@ -52,6 +52,11 @@
user << "<span class='warning'>You aren't sure where this brain came from, but you're pretty sure it's useless.</span>"
return
for(var/modifier_type in B.brainmob.modifiers) //Can't be shoved in an MMI.
if(istype(modifier_type, /datum/modifier/no_borg))
to_chat(user, "<span class='warning'>\The [src] appears to reject this brain. It is incompatable.</span>")
return
user.visible_message("<span class='notice'>\The [user] sticks \a [O] into \the [src].</span>")
brainmob = B.brainmob
@@ -118,6 +123,11 @@
brainmob.dna = H.dna
brainmob.container = src
// Copy modifiers.
for(var/datum/modifier/M in H.modifiers)
if(M.flags & MODIFIER_GENETIC)
brainmob.add_modifier(M.type)
name = "Man-Machine Interface: [brainmob.real_name]"
icon_state = "mmi_full"
locked = 1
+2 -2
View File
@@ -70,8 +70,8 @@
//handle mask filtering
if(istype(wear_mask, /obj/item/clothing/mask) && breath)
var/obj/item/clothing/mask/M = wear_mask
var/datum/gas_mixture/filtered = M.filter_air(breath)
loc.assume_air(filtered)
var/datum/gas_mixture/gas_filtered = M.filter_air(breath)
loc.assume_air(gas_filtered)
return breath
return null
@@ -112,5 +112,5 @@
mutations.Add(SKELETON)
status_flags |= DISFIGURED
update_body(0)
update_body(1)
return
+40 -11
View File
@@ -233,14 +233,28 @@
m_type = 1
else
if(!muzzled)
message = "coughs!"
var/robotic = 0
m_type = 2
if(gender == FEMALE)
if(species.female_cough_sounds)
playsound(src, pick(species.female_cough_sounds), 120)
if(should_have_organ(O_LUNGS))
var/obj/item/organ/internal/lungs/L = internal_organs_by_name[O_LUNGS]
if(L && L.robotic == 2) //Hard-coded to 2, incase we add lifelike robotic lungs
robotic = 1
if(!robotic)
message = "coughs!"
if(gender == FEMALE)
if(species.female_cough_sounds)
playsound(src, pick(species.female_cough_sounds), 120)
else
if(species.male_cough_sounds)
playsound(src, pick(species.male_cough_sounds), 120)
else
if(species.male_cough_sounds)
playsound(src, pick(species.male_cough_sounds), 120)
message = "emits a robotic cough"
var/use_sound
if(gender == FEMALE)
use_sound = pick('sound/effects/mob_effects/f_machine_cougha.ogg','sound/effects/mob_effects/f_machine_coughb.ogg')
else
use_sound = pick('sound/effects/mob_effects/m_machine_cougha.ogg','sound/effects/mob_effects/m_machine_coughb.ogg', 'sound/effects/mob_effects/m_machine_coughc.ogg')
playsound(src.loc, use_sound, 50, 0)
else
message = "makes a strong noise."
m_type = 2
@@ -493,12 +507,27 @@
m_type = 1
else
if(!muzzled)
message = "sneezes."
if(gender == FEMALE)
playsound(src, species.female_sneeze_sound, 70)
else
playsound(src, species.male_sneeze_sound, 70)
var/robotic = 0
m_type = 2
if(should_have_organ(O_LUNGS))
var/obj/item/organ/internal/lungs/L = internal_organs_by_name[O_LUNGS]
if(L && L.robotic == 2) //Hard-coded to 2, incase we add lifelike robotic lungs
robotic = 1
if(!robotic)
message = "sneezes."
if(gender == FEMALE)
playsound(src, species.female_sneeze_sound, 70)
else
playsound(src, species.male_sneeze_sound, 70)
m_type = 2
else
message = "emits a robotic sneeze"
var/use_sound
if(gender == FEMALE)
use_sound = 'sound/effects/mob_effects/machine_sneeze.ogg'
else
use_sound = 'sound/effects/mob_effects/f_machine_sneeze.ogg'
playsound(src.loc, use_sound, 50, 0)
else
message = "makes a strange noise."
m_type = 2
@@ -1217,6 +1217,8 @@
hud_used = new /datum/hud(src)
if(species)
//if(mind) //VOREStation Removal
//apply_traits() //VOREStation Removal
return 1
else
return 0
@@ -1554,7 +1556,7 @@
return species.fire_icon_state
// Called by job_controller. Makes drones start with a permit, might be useful for other people later too.
/mob/living/carbon/human/equip_post_job()
/mob/living/carbon/human/equip_post_job() //Drone Permit moved to equip_survival_gear()
var/braintype = get_FBP_type()
if(braintype == FBP_DRONE)
var/turf/T = get_turf(src)
@@ -23,9 +23,13 @@
var/g_skin = 0
var/b_skin = 0
// VoreStation (Moved to /mob/living)
// var/size_multiplier = 1 //multiplier for the mob's icon size
//Synth colors
var/synth_color = 0 //Lets normally uncolorable synth parts be colorable.
var/r_synth //Used with synth_color to color synth parts that normaly can't be colored.
var/g_synth //Same as above
var/b_synth //Same as above
//var/size_multiplier = 1 //multiplier for the mob's icon size //VOREStation Edit (Moved to /mob/living)
var/damage_multiplier = 1 //multiplies melee combat damage
var/icon_update = 1 //whether icon updating shall take place
+9 -3
View File
@@ -651,7 +651,7 @@
if(status_flags & GODMODE)
return 1 //godmode
if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
var/cold_dam = 0
if(bodytemperature <= species.cold_level_1)
@@ -864,8 +864,14 @@
heal_overall_damage(1,1)
// nutrition decrease
if (nutrition > 0 && stat != 2)
nutrition = max (0, nutrition - species.hunger_factor)
if (nutrition > 0 && stat != DEAD)
var/nutrition_reduction = species.hunger_factor
for(var/datum/modifier/mod in modifiers)
if(!isnull(mod.metabolism_percent))
nutrition_reduction *= mod.metabolism_percent
nutrition = max (0, nutrition - nutrition_reduction)
if (nutrition > 450)
if(overeatduration < 600) //capped so people don't take forever to unfat
@@ -0,0 +1,53 @@
/datum/species/skeleton
name = "Skeleton"
name_plural = "Skeletons"
icobase = 'icons/mob/human_races/r_skeleton.dmi'
primitive_form = "Monkey"
language = "Sol Common"
unarmed_types = list(/datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/sharp) //Bones are pointy, fight me.
blurb = "Spooky Scary Skeletons!"
name_language = null // Use the first-name last-name generator rather than a language scrambler
min_age = 17
max_age = 110
health_hud_intensity = 1.5
flags = NO_SCAN | NO_PAIN | NO_SLIP | NO_POISON | NO_MINOR_CUT | NO_BLOOD | UNDEAD
spawn_flags = SPECIES_IS_RESTRICTED
appearance_flags = null
show_ssd = null
blood_volume = null
taste_sensitivity = TASTE_DULL
hunger_factor = 0
metabolic_rate = 0
virus_immune = 1
brute_mod = 1
burn_mod = 0
oxy_mod = 0
toxins_mod = 0
radiation_mod = 0
flash_mod = 0
chemOD_mod = 0
siemens_coefficient = 0
death_message = "falls over and stops moving!"
knockout_message = "falls over and stops moving!"
has_organ = list()
warning_low_pressure = 50
hazard_low_pressure = -1
cold_level_1 = 50
cold_level_2 = -1
cold_level_3 = -1
heat_level_1 = 2000
heat_level_2 = 3000
heat_level_3 = 4000
body_temperature = T20C
+6
View File
@@ -1,4 +1,10 @@
/mob/living/carbon/proc/ingest(var/datum/reagents/from, var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0) //we kind of 'sneak' a proc in here for ingesting stuff so we can play with it.
if(ishuman(src))
var/mob/living/carbon/human/H = src
var/braintype = H.get_FBP_type()
if(braintype == FBP_DRONE || braintype == FBP_POSI)
return from.trans_to_holder(target,amount,multiplier,copy) //skip the taste, complete transfer
if(last_taste_time + 50 < world.time)
var/datum/reagents/temp = new(amount) //temporary holder used to analyse what gets transfered.
from.trans_to_holder(temp, amount, multiplier, 1)
+3 -1
View File
@@ -87,7 +87,7 @@
return 1
/mob/living/proc/apply_effects(var/stun = 0, var/weaken = 0, var/paralyze = 0, var/irradiate = 0, var/stutter = 0, var/eyeblur = 0, var/drowsy = 0, var/agony = 0, var/blocked = 0)
/mob/living/proc/apply_effects(var/stun = 0, var/weaken = 0, var/paralyze = 0, var/irradiate = 0, var/stutter = 0, var/eyeblur = 0, var/drowsy = 0, var/agony = 0, var/blocked = 0, var/ignite = 0, var/flammable = 0)
if(blocked >= 100)
return 0
if(stun) apply_effect(stun, STUN, blocked)
@@ -98,4 +98,6 @@
if(eyeblur) apply_effect(eyeblur, EYE_BLUR, blocked)
if(drowsy) apply_effect(drowsy, DROWSY, blocked)
if(agony) apply_effect(agony, AGONY, blocked)
if(flammable) adjust_fire_stacks(flammable)
if(ignite) IgniteMob()
return 1
+28 -9
View File
@@ -319,7 +319,7 @@ default behaviour is:
return fireloss
/mob/living/proc/getActualFireLoss() // Mostly for humans with robolimbs.
return getBruteLoss()
return getFireLoss()
/mob/living/proc/adjustFireLoss(var/amount)
if(status_flags & GODMODE) return 0 //godmode
@@ -724,9 +724,21 @@ default behaviour is:
if(A.has_gravity)
//this is the gay blood on floor shit -- Added back -- Skie
if (M.lying && (prob(M.getBruteLoss() / 6)))
var/turf/location = M.loc
if (istype(location, /turf/simulated))
location.add_blood(M)
var/bloodtrail = 1 //Checks if it's possible to even spill blood
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.species.flags & NO_BLOOD)
bloodtrail = 0
else
var/blood_volume = round((H.vessel.get_reagent_amount("blood")/H.species.blood_volume)*100)
if(blood_volume < BLOOD_VOLUME_SURVIVE)
bloodtrail = 0 //Most of it's gone already, just leave it be
else
H.vessel.remove_reagent("blood", 1)
if(bloodtrail)
var/turf/location = M.loc
if(istype(location, /turf/simulated))
location.add_blood(M)
//pull damage with injured people
if(prob(25))
M.adjustBruteLoss(1)
@@ -737,13 +749,20 @@ default behaviour is:
visible_message("<span class='danger'>\The [M]'s [M.isSynthetic() ? "state" : "wounds"] worsen terribly from being dragged!</span>")
var/turf/location = M.loc
if (istype(location, /turf/simulated))
location.add_blood(M)
var/bloodtrail = 1 //Checks if it's possible to even spill blood
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/blood_volume = round(H.vessel.get_reagent_amount("blood"))
if(blood_volume > 0)
H.vessel.remove_reagent("blood", 1)
if(H.species.flags & NO_BLOOD)
bloodtrail = 0
else
var/blood_volume = round((H.vessel.get_reagent_amount("blood")/H.species.blood_volume)*100)
if(blood_volume < BLOOD_VOLUME_SURVIVE)
bloodtrail = 0 //Most of it's gone already, just leave it be
else
H.vessel.remove_reagent("blood", 1)
if(bloodtrail)
if(istype(location, /turf/simulated))
location.add_blood(M)
step(pulling, get_dir(pulling.loc, T))
if(t)
+1 -2
View File
@@ -303,14 +303,13 @@ proc/get_radio_key_from_channel(var/channel)
var/image/speech_bubble = image('icons/mob/talk.dmi',src,"[speech_type][speech_bubble_test]")
spawn(30) qdel(speech_bubble)
// VOREStation Edit - Attempt Multi-Z Talking
var/mob/above = src.shadow
while(!QDELETED(above))
var/turf/ST = get_turf(above)
if(ST)
var/list/results = get_mobs_and_objs_in_view_fast(ST, world.view)
var/image/z_speech_bubble = image('icons/mob/talk_vr.dmi', above, "h[speech_bubble_test]")
var/image/z_speech_bubble = image('icons/mob/talk.dmi', above, "h[speech_bubble_test]")
spawn(30) qdel(z_speech_bubble)
for(var/item in results["mobs"])
if(item != above && !(item in listening))
@@ -22,6 +22,9 @@
playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0)
/mob/living/silicon/robot/lost/speech_bubble_appearance()
return "synthetic_evil"
/mob/living/silicon/robot/lost/randomlaws
/mob/living/silicon/robot/lost/randomlaws/init()
@@ -51,6 +51,9 @@
say_maybe_target = list("Possible threat detected. Investigating.", "Motion detected.", "Investigating.")
say_got_target = list("Threat detected.", "New task: Remove threat.", "Threat removal engaged.", "Engaging target.")
/mob/living/simple_animal/hostile/hivebot/isSynthetic()
return TRUE
// Subtypes.
// Melee like the base type, but more fragile.
@@ -212,7 +212,7 @@
Z << "<B>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</B>"
Z.cancel_camera()
qdel(src)
/obj/item/device/soulstone/proc/transfer_soul(var/choice as text, var/target, var/mob/U as mob).
/obj/item/device/soulstone/proc/transfer_soul(var/choice as text, var/target, var/mob/U as mob)
switch(choice)
if("VICTIM")
transfer_human(target,U)
@@ -78,6 +78,7 @@
W.assignment = corpseidjob
W.registered_name = M.real_name
M.equip_to_slot_or_del(W, slot_wear_id)
delete_me = 1
qdel(src)
@@ -228,19 +228,14 @@
//Should we be dead?
/mob/living/simple_animal/updatehealth()
health = getMaxHealth() - getToxLoss() - getFireLoss() - getBruteLoss()
//Alive, becoming dead
if((stat < DEAD) && (health <= 0))
death()
//Dead, becoming alive
else if((stat >= DEAD) && (health > 0))
dead_mob_list -= src
living_mob_list += src
stat = CONSCIOUS
density = 1
//Overhealth
else if(health > getMaxHealth())
if(health > getMaxHealth())
health = getMaxHealth()
/mob/living/simple_animal/update_icon()
@@ -628,6 +623,16 @@
var/tally = 0 //Incase I need to add stuff other than "speed" later
tally = speed
if(force_max_speed)
return -3
for(var/datum/modifier/M in modifiers)
if(!isnull(M.haste) && M.haste == TRUE)
return -3
if(!isnull(M.slowdown))
tally += M.slowdown
if(purge)//Purged creatures will move more slowly. The more time before their purge stops, the slower they'll move.
if(tally <= 0)
tally = 1
@@ -681,52 +686,6 @@
if(3.0)
adjustBruteLoss(30)
// Don't understand why simple animals don't use the regular /mob/living health system.
/mob/living/simple_animal/adjustBruteLoss(damage)
if(damage > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
damage *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
damage *= M.incoming_brute_damage_percent
else if(damage < 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_healing_percent))
damage *= M.incoming_healing_percent
health = Clamp(health - damage, 0, getMaxHealth())
updatehealth()
/mob/living/simple_animal/adjustFireLoss(damage)
if(damage > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
damage *= M.incoming_damage_percent
if(!isnull(M.incoming_fire_damage_percent))
damage *= M.incoming_brute_damage_percent
else if(damage < 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_healing_percent))
damage *= M.incoming_healing_percent
health = Clamp(health - damage, 0, getMaxHealth())
updatehealth()
/mob/living/simple_animal/adjustToxLoss(damage)
if(damage > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
damage *= M.incoming_damage_percent
if(!isnull(M.incoming_tox_damage_percent))
damage *= M.incoming_brute_damage_percent
else if(damage < 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_healing_percent))
damage *= M.incoming_healing_percent
health = Clamp(health - damage, 0, getMaxHealth())
updatehealth()
// Check target_mob if worthy of attack (i.e. check if they are dead or empty mecha)
/mob/living/simple_animal/proc/SA_attackable(target_mob)
ai_log("SA_attackable([target_mob])",3)
@@ -1245,6 +1204,9 @@
if(!isnull(M.outgoing_melee_damage_percent))
damage_to_do *= M.outgoing_melee_damage_percent
if(attack_sound)
playsound(src, attack_sound, 75, 1)
// SA attacks can be blocked with shields.
if(ishuman(A))
var/mob/living/carbon/human/H = A
@@ -367,6 +367,8 @@
// Equip our custom items only AFTER deploying to spawn points eh?
equip_custom_items(character)
//character.apply_traits() //VOREStation Removal
character.lastarea = get_area(loc)
// Moving wheelchair if they have one
if(character.buckled && istype(character.buckled, /obj/structure/bed/chair/wheelchair))
@@ -468,6 +470,7 @@
mind.loaded_from_ckey = client.ckey
mind.loaded_from_slot = client.prefs.default_slot
// VOREStation
mind.traits = client.prefs.traits.Copy()
mind.transfer_to(new_character) //won't transfer key since the mind is not active
new_character.name = real_name
+2 -2
View File
@@ -72,8 +72,8 @@
* Update icon and overlays of open space to be that of the turf below, plus any visible objects on that turf.
*/
/turf/simulated/open/update_icon()
overlays = list() //VOREStation Edit - Overlays are being crashy when modified.
update_icon_edge() //VOREStation Add - Get grass into open spaces and whatnot.
overlays = list() // Edit - Overlays are being crashy when modified.
update_icon_edge()// Add - Get grass into open spaces and whatnot.
var/turf/below = GetBelow(src)
if(below)
var/below_is_open = isopenspace(below)
+1 -1
View File
@@ -121,7 +121,7 @@
/mob/zshadow/set_typing_indicator(var/state)
if(!typing_indicator)
typing_indicator = new
typing_indicator.icon = 'icons/mob/talk_vr.dmi' //VOREStation Edit - Looks better on the right with job icons.
typing_indicator.icon = 'icons/mob/talk.dmi' //Looks better on the right with job icons.
typing_indicator.icon_state = "typing"
if(state && !typing)
overlays += typing_indicator
+13
View File
@@ -17,6 +17,9 @@ var/const/CE_STABLE_THRESHOLD = 0.5
if(vessel)
return
if(species.flags & NO_BLOOD)
return
vessel = new/datum/reagents(species.blood_volume)
vessel.my_atom = src
@@ -139,6 +142,16 @@ var/const/CE_STABLE_THRESHOLD = 0.5
//Bleeding out
var/blood_max = 0
var/blood_loss_divisor = 30 //lower factor = more blood loss
// Some modifiers can make bleeding better or worse. Higher multiplers = more bleeding.
var/blood_loss_modifier_multiplier = 1.0
for(var/datum/modifier/M in modifiers)
if(!isnull(M.bleeding_rate_percent))
blood_loss_modifier_multiplier += (M.bleeding_rate_percent - 1.0)
blood_loss_divisor /= blood_loss_modifier_multiplier
//This 30 is the "baseline" of a cut in the "vital" regions (head and torso).
for(var/obj/item/organ/external/temp in bad_external_organs)
if(!(temp.status & ORGAN_BLEEDING) || (temp.robotic >= ORGAN_ROBOT))
+5
View File
@@ -79,6 +79,11 @@
brainmob.dna = H.dna.Clone()
brainmob.timeofhostdeath = H.timeofdeath
// Copy modifiers.
for(var/datum/modifier/M in H.modifiers)
if(M.flags & MODIFIER_GENETIC)
brainmob.add_modifier(M.type)
if(H.mind)
H.mind.transfer_to(brainmob)
+4 -4
View File
@@ -487,13 +487,13 @@ This function completely restores a damaged organ to perfect condition.
//moved this before the open_wound check so that having many small wounds for example doesn't somehow protect you from taking internal damage (because of the return)
//Possibly trigger an internal wound, too.
var/local_damage = brute_dam + burn_dam + damage
if((damage > 15) && (type != BURN) && (local_damage > 30) && prob(damage) && (robotic < ORGAN_ROBOT))
if((damage > 15) && (type != BURN) && (local_damage > 30) && prob(damage) && (robotic < ORGAN_ROBOT) && !(species.flags & NO_BLOOD))
var/datum/wound/internal_bleeding/I = new (min(damage - 15, 15))
wounds += I
owner.custom_pain("You feel something rip in your [name]!", 50)
//Burn damage can cause fluid loss due to blistering and cook-off
if((damage > 5 || damage + burn_dam >= 15) && type == BURN && (robotic < ORGAN_ROBOT) && !istype(owner.loc,/mob/living) && !istype(owner.loc,/obj/item/device/dogborg/sleeper)) // VOREStation Edit
if((damage > 5 || damage + burn_dam >= 15) && type == BURN && (robotic < ORGAN_ROBOT) && !(species.flags & NO_BLOOD) && !istype(owner.loc,/mob/living) && !istype(owner.loc,/obj/item/device/dogborg/sleeper)) // VOREStation Edit
var/fluid_loss = 0.75 * (damage/(owner.getMaxHealth() - config.health_threshold_dead)) * owner.species.blood_volume*(1 - BLOOD_VOLUME_SURVIVE/100)
owner.remove_blood(fluid_loss)
@@ -681,7 +681,7 @@ Note that amputating the affected organ does in fact remove the infection from t
//Updating wounds. Handles wound natural I had some free spachealing, internal bleedings and infections
/obj/item/organ/external/proc/update_wounds()
if((robotic >= ORGAN_ROBOT)) //Robotic limbs don't heal or get worse.
if((robotic >= ORGAN_ROBOT) || (species.flags & UNDEAD)) //Robotic and dead limbs don't heal or get worse.
for(var/datum/wound/W in wounds) //Repaired wounds disappear though
if(W.damage <= 0) //and they disappear right away
wounds -= W //TODO: robot wounds for robot limbs
@@ -756,7 +756,7 @@ Note that amputating the affected organ does in fact remove the infection from t
else
brute_dam += W.damage
if(!(robotic >= ORGAN_ROBOT) && W.bleeding() && (H && H.should_have_organ(O_HEART)))
if(!(robotic >= ORGAN_ROBOT) && W.bleeding() && (H && H.should_have_organ(O_HEART)) && !(H.species.flags & NO_BLOOD))
W.bleed_timer--
status |= ORGAN_BLEEDING
+2
View File
@@ -19,6 +19,8 @@ var/global/list/limb_icon_cache = list()
if(robotic >= ORGAN_ROBOT)
var/datum/robolimb/franchise = all_robolimbs[model]
if(!(franchise && franchise.lifelike))
if(human.synth_color)
s_col = list(human.r_synth, human.g_synth, human.b_synth)
return
if(species && human.species && species.name != human.species.name)
return
+14
View File
@@ -245,6 +245,20 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\
green=xion_green;\
rgb=xion_rgb"
/datum/robolimb/xion_alt3
company = "Xion - Whiteout"
desc = "This limb has a minimalist black and white casing."
icon = 'icons/mob/human_races/cyberlimbs/xion/xion_alt3.dmi'
unavailable_to_build = 1
/datum/robolimb/xion_alt4
company = "Xion - Breach - Whiteout"
desc = "This limb has a minimalist black and white casing. Looks a bit menacing."
icon = 'icons/mob/human_races/cyberlimbs/xion/xion_alt4.dmi'
unavailable_to_build = 1
parts = list(BP_HEAD)
/datum/robolimb/xion_monitor
company = "Xion Monitor"
desc = "Xion Mfg.'s unique spin on a popular prosthetic head model. It looks and minimalist and utilitarian."
+2 -2
View File
@@ -2,7 +2,7 @@
name = "microbattery"
desc = "A small, powerful cell for use in fully prosthetic bodies."
icon_state = "scell"
organ_tag = "cell"
organ_tag = O_CELL
parent_organ = BP_TORSO
vital = 1
@@ -21,7 +21,7 @@
// Used for an MMI or posibrain being installed into a human.
/obj/item/organ/internal/mmi_holder
name = "brain interface"
organ_tag = "brain"
organ_tag = O_BRAIN
parent_organ = BP_HEAD
vital = 1
var/brain_type = /obj/item/device/mmi
+1 -1
View File
@@ -466,7 +466,7 @@
user << browse("<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[info_links][stamps]</BODY></HTML>", "window=[name]")
return
else if(istype(P, /obj/item/weapon/stamp))
else if(istype(P, /obj/item/weapon/stamp) || istype(P, /obj/item/clothing/gloves/ring/seal))
if((!in_range(src, usr) && loc != user && !( istype(loc, /obj/item/weapon/clipboard) ) && loc.loc != user && user.get_active_hand() != P))
return
+1
View File
@@ -6,6 +6,7 @@
item_state = "stamp"
throwforce = 0
w_class = ITEMSIZE_TINY
slot_flags = SLOT_HOLSTER
throw_speed = 7
throw_range = 15
matter = list(DEFAULT_WALL_MATERIAL = 60)
+2 -2
View File
@@ -17,8 +17,8 @@
var/turf/unsimulated/wall/planetary/planetary_wall_type = /turf/unsimulated/wall/planetary
var/turf/simulated/floor/planet_floors = list()
var/turf/unsimulated/wall/planetary/planet_walls = list()
var/list/turf/simulated/floor/planet_floors = list()
var/list/turf/unsimulated/wall/planetary/planet_walls = list()
var/needs_work = 0 // Bitflags to signal to the planet controller these need (properly deferrable) work. Flags defined in controller.
+7 -2
View File
@@ -174,6 +174,7 @@ datum/weather/sif
temp_high = T0C // 0c
temp_low = 243.15 // -30c
light_modifier = 0.5
flight_falure_modifier = 5
transition_chances = list(
WEATHER_LIGHT_SNOW = 20,
WEATHER_SNOW = 50,
@@ -197,6 +198,7 @@ datum/weather/sif
temp_high = 233.15 // -40c
temp_low = 213.15 // -60c
light_modifier = 0.3
flight_falure_modifier = 10
transition_chances = list(
WEATHER_SNOW = 45,
WEATHER_BLIZZARD = 40,
@@ -232,7 +234,7 @@ datum/weather/sif
if(!T.outdoors)
return // They're indoors, so no need to rain on them.
L.adjust_fire_stacks(-5)
L.water_act(1)
to_chat(L, "<span class='warning'>Rain falls on you.</span>")
/datum/weather/sif/storm
@@ -241,6 +243,7 @@ datum/weather/sif
temp_high = 243.15 // -30c
temp_low = 233.15 // -50c
light_modifier = 0.3
flight_falure_modifier = 10
transition_chances = list(
WEATHER_RAIN = 45,
WEATHER_STORM = 40,
@@ -255,7 +258,7 @@ datum/weather/sif
if(!T.outdoors)
return // They're indoors, so no need to rain on them.
L.adjust_fire_stacks(-10)
L.water_act(2)
to_chat(L, "<span class='warning'>Rain falls on you, drenching you in water.</span>")
/datum/weather/sif/hail
@@ -264,6 +267,7 @@ datum/weather/sif
temp_high = T0C // 0c
temp_low = 243.15 // -30c
light_modifier = 0.3
flight_falure_modifier = 15
transition_chances = list(
WEATHER_RAIN = 45,
WEATHER_STORM = 10,
@@ -295,6 +299,7 @@ datum/weather/sif
name = "blood moon"
light_modifier = 0.5
light_color = "#FF0000"
flight_falure_modifier = 25
transition_chances = list(
WEATHER_BLOODMOON = 100
)
+1
View File
@@ -59,6 +59,7 @@
var/temp_low = T0C
var/light_modifier = 1.0 // Lower numbers means more darkness.
var/light_color = null // If set, changes how the day/night light looks.
var/flight_falure_modifier = 0 // Some types of weather make flying harder, and therefore make crashes more likely.
var/transition_chances = list() // Assoc list
var/datum/weather_holder/holder = null
@@ -56,7 +56,7 @@
C.energy_setting = ENERGY_PHORON
continue
for(var/obj/effect/engine_setup/filter/F in world)
for(var/obj/effect/engine_setup/atmo_filter/F in world)
F.coolant = response
var/list/delayed_objects = list()
@@ -227,13 +227,13 @@
// Sets up filters. This assumes filters are set to filter out N2 back to the core loop by default!
/obj/effect/engine_setup/filter/
/obj/effect/engine_setup/atmo_filter/
name = "Omni Filter Marker"
var/coolant = null
/obj/effect/engine_setup/filter/activate()
/obj/effect/engine_setup/atmo_filter/activate()
..()
var/obj/machinery/atmospherics/omni/filter/F = locate() in get_turf(src)
var/obj/machinery/atmospherics/omni/atmos_filter/F = locate() in get_turf(src)
if(!F)
log_and_message_admins("## WARNING: Unable to locate omni filter at [x] [y] [z]!")
return SETUP_WARNING
@@ -0,0 +1,13 @@
/obj/item/weapon/magnetic_ammo
name = "flechette magazine"
desc = "A magazine containing steel flechettes."
icon = 'icons/obj/ammo.dmi'
icon_state = "5.56"
w_class = ITEMSIZE_SMALL
matter = list(DEFAULT_WALL_MATERIAL = 1800)
origin_tech = list(TECH_COMBAT = 1)
var/remaining = 9
/obj/item/weapon/magnetic_ammo/examine(mob/user)
. = ..()
to_chat(user, "There [(remaining == 1)? "is" : "are"] [remaining] flechette\s left!")
+8 -1
View File
@@ -515,7 +515,7 @@
damage_mult = 1.5
P.damage *= damage_mult
/obj/item/weapon/gun/proc/process_accuracy(obj/projectile, mob/user, atom/target, acc_mod, dispersion)
/obj/item/weapon/gun/proc/process_accuracy(obj/projectile, mob/living/user, atom/target, acc_mod, dispersion)
var/obj/item/projectile/P = projectile
if(!istype(P))
return //default behaviour only applies to true projectiles
@@ -539,6 +539,13 @@
//As opposed to no-delay pew pew
P.accuracy += 2
// Some modifiers make it harder or easier to hit things.
for(var/datum/modifier/M in user.modifiers)
if(!isnull(M.accuracy))
P.accuracy += M.accuracy
if(!isnull(M.accuracy_dispersion))
P.dispersion = max(P.dispersion + M.accuracy_dispersion, 0)
//does the actual launching of the projectile
/obj/item/weapon/gun/proc/process_projectile(obj/projectile, mob/user, atom/target, var/target_zone, var/params=null)
var/obj/item/projectile/P = projectile
+2 -1
View File
@@ -36,7 +36,7 @@
item_state = "crossbow"
origin_tech = list(TECH_COMBAT = 2, TECH_MAGNET = 2, TECH_ILLEGAL = 5)
matter = list(DEFAULT_WALL_MATERIAL = 2000)
slot_flags = SLOT_BELT
slot_flags = SLOT_BELT | SLOT_HOLSTER
silenced = 1
fire_sound = 'sound/weapons/Genhit.ogg'
projectile_type = /obj/item/projectile/energy/bolt
@@ -54,6 +54,7 @@
w_class = ITEMSIZE_LARGE
force = 10
matter = list(DEFAULT_WALL_MATERIAL = 200000)
slot_flags = SLOT_BELT
projectile_type = /obj/item/projectile/energy/bolt/large
/obj/item/weapon/gun/energy/plasmastun
@@ -0,0 +1,195 @@
/obj/item/weapon/gun/magnetic
name = "improvised coilgun"
desc = "A coilgun hastily thrown together out of a basic frame and advanced power storage components. Is it safe for it to be duct-taped together like that?"
icon_state = "coilgun"
item_state = "coilgun"
icon = 'icons/obj/railgun.dmi'
// one_hand_penalty = 1
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 4, TECH_ILLEGAL = 2, TECH_MAGNET = 4)
w_class = ITEMSIZE_LARGE
var/obj/item/weapon/cell/cell // Currently installed powercell.
var/obj/item/weapon/stock_parts/capacitor/capacitor // Installed capacitor. Higher rating == faster charge between shots.
var/removable_components = TRUE // Whether or not the gun can be dismantled.
var/gun_unreliable = 15 // Percentage chance of detonating in your hands.
var/obj/item/loaded // Currently loaded object, for retrieval/unloading.
var/load_type = /obj/item/stack/rods // Type of stack to load with.
var/projectile_type = /obj/item/projectile/bullet/magnetic // Actual fire type, since this isn't throw_at rod launcher.
var/power_cost = 950 // Cost per fire, should consume almost an entire basic cell.
var/power_per_tick // Capacitor charge per process(). Updated based on capacitor rating.
fire_sound = 'sound/weapons/railgun.ogg'
/obj/item/weapon/gun/magnetic/New()
processing_objects.Add(src)
if(capacitor)
power_per_tick = (power_cost*0.15) * capacitor.rating
update_icon()
. = ..()
/obj/item/weapon/gun/magnetic/Destroy()
processing_objects.Remove(src)
qdel_null(cell)
qdel_null(loaded)
qdel_null(capacitor)
. = ..()
/obj/item/weapon/gun/magnetic/process()
if(capacitor)
if(cell)
if(capacitor.charge < capacitor.max_charge && cell.checked_use(power_per_tick))
capacitor.charge(power_per_tick)
else
capacitor.use(capacitor.charge * 0.05)
update_icon()
/obj/item/weapon/gun/magnetic/update_icon()
var/list/overlays_to_add = list()
if(removable_components)
if(cell)
overlays_to_add += image(icon, "[icon_state]_cell")
if(capacitor)
overlays_to_add += image(icon, "[icon_state]_capacitor")
if(!cell || !capacitor)
overlays_to_add += image(icon, "[icon_state]_red")
else if(capacitor.charge < power_cost)
overlays_to_add += image(icon, "[icon_state]_amber")
else
overlays_to_add += image(icon, "[icon_state]_green")
if(loaded)
overlays_to_add += image(icon, "[icon_state]_loaded")
overlays = overlays_to_add
..()
/obj/item/weapon/gun/magnetic/proc/show_ammo(var/mob/user)
if(loaded)
to_chat(user, "<span class='notice'>It has \a [loaded] loaded.</span>")
/obj/item/weapon/gun/magnetic/examine(var/mob/user)
. = ..(user, 2)
if(.)
show_ammo(user)
if(cell)
to_chat(user, "<span class='notice'>The installed [cell.name] has a charge level of [round((cell.charge/cell.maxcharge)*100)]%.</span>")
if(capacitor)
to_chat(user, "<span class='notice'>The installed [capacitor.name] has a charge level of [round((capacitor.charge/capacitor.max_charge)*100)]%.</span>")
if(!cell || !capacitor)
to_chat(user, "<span class='notice'>The capacitor charge indicator is blinking <font color ='[COLOR_RED]'>red</font>. Maybe you should check the cell or capacitor.</span>")
else
if(capacitor.charge < power_cost)
to_chat(user, "<span class='notice'>The capacitor charge indicator is <font color ='[COLOR_ORANGE]'>amber</font>.</span>")
else
to_chat(user, "<span class='notice'>The capacitor charge indicator is <font color ='[COLOR_GREEN]'>green</font>.</span>")
return TRUE
/obj/item/weapon/gun/magnetic/attackby(var/obj/item/thing, var/mob/user)
if(removable_components)
if(istype(thing, /obj/item/weapon/cell))
if(cell)
to_chat(user, "<span class='warning'>\The [src] already has \a [cell] installed.</span>")
return
cell = thing
user.drop_from_inventory(cell)
cell.forceMove(src)
playsound(loc, 'sound/machines/click.ogg', 10, 1)
user.visible_message("<span class='notice'>\The [user] slots \the [cell] into \the [src].</span>")
update_icon()
return
if(isscrewdriver(thing))
if(!capacitor)
to_chat(user, "<span class='warning'>\The [src] has no capacitor installed.</span>")
return
capacitor.forceMove(get_turf(src))
user.put_in_hands(capacitor)
user.visible_message("<span class='notice'>\The [user] unscrews \the [capacitor] from \the [src].</span>")
playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1)
capacitor = null
update_icon()
return
if(istype(thing, /obj/item/weapon/stock_parts/capacitor))
if(capacitor)
to_chat(user, "<span class='warning'>\The [src] already has \a [capacitor] installed.</span>")
return
capacitor = thing
user.drop_from_inventory(capacitor)
capacitor.forceMove(src)
playsound(loc, 'sound/machines/click.ogg', 10, 1)
power_per_tick = (power_cost*0.15) * capacitor.rating
user.visible_message("<span class='notice'>\The [user] slots \the [capacitor] into \the [src].</span>")
update_icon()
return
if(istype(thing, load_type))
if(loaded)
to_chat(user, "<span class='warning'>\The [src] already has \a [loaded] loaded.</span>")
return
// This is not strictly necessary for the magnetic gun but something using
// specific ammo types may exist down the track.
var/obj/item/stack/ammo = thing
if(!istype(ammo))
loaded = thing
user.drop_from_inventory(thing)
thing.forceMove(src)
else
loaded = new load_type(src, 1)
ammo.use(1)
user.visible_message("<span class='notice'>\The [user] loads \the [src] with \the [loaded].</span>")
playsound(loc, 'sound/weapons/flipblade.ogg', 50, 1)
update_icon()
return
. = ..()
/obj/item/weapon/gun/magnetic/attack_hand(var/mob/user)
if(user.get_inactive_hand() == src)
var/obj/item/removing
if(loaded)
removing = loaded
loaded = null
else if(cell && removable_components)
removing = cell
cell = null
if(removing)
removing.forceMove(get_turf(src))
user.put_in_hands(removing)
user.visible_message("<span class='notice'>\The [user] removes \the [removing] from \the [src].</span>")
playsound(loc, 'sound/machines/click.ogg', 10, 1)
update_icon()
return
. = ..()
/obj/item/weapon/gun/magnetic/proc/check_ammo()
return loaded
/obj/item/weapon/gun/magnetic/proc/use_ammo()
qdel(loaded)
loaded = null
/obj/item/weapon/gun/magnetic/consume_next_projectile()
if(!check_ammo() || !capacitor || capacitor.charge < power_cost)
return
use_ammo()
capacitor.use(power_cost)
update_icon()
if(gun_unreliable && prob(gun_unreliable))
spawn(3) // So that it will still fire - considered modifying Fire() to return a value but burst fire makes that annoying.
visible_message("<span class='danger'>\The [src] explodes with the force of the shot!</span>")
explosion(get_turf(src), -1, 0, 2)
qdel(src)
return new projectile_type(src)
@@ -0,0 +1,101 @@
// We really need some datums for this.
/obj/item/weapon/coilgun_assembly
name = "coilgun stock"
desc = "It might be a coilgun, someday."
icon = 'icons/obj/coilgun.dmi'
icon_state = "coilgun_construction_1"
var/construction_stage = 1
/obj/item/weapon/coilgun_assembly/attackby(var/obj/item/thing, var/mob/user)
if(istype(thing, /obj/item/stack/material) && construction_stage == 1)
var/obj/item/stack/material/reinforcing = thing
var/material/reinforcing_with = reinforcing.get_material()
if(reinforcing_with.name == DEFAULT_WALL_MATERIAL) // Steel
if(reinforcing.get_amount() < 5)
to_chat(user, "<span class='warning'>You need at least 5 [reinforcing.singular_name]\s for this task.</span>")
return
reinforcing.use(5)
user.visible_message("<span class='notice'>\The [user] shapes some steel sheets around \the [src] to form a body.</span>")
increment_construction_stage()
return
if(istype(thing, /obj/item/weapon/tape_roll) && construction_stage == 2)
user.visible_message("<span class='notice'>\The [user] secures \the [src] together with \the [thing].</span>")
increment_construction_stage()
return
if(istype(thing, /obj/item/pipe) && construction_stage == 3)
user.drop_from_inventory(thing)
qdel(thing)
user.visible_message("<span class='notice'>\The [user] jams \the [thing] into \the [src].</span>")
increment_construction_stage()
return
if(istype(thing, /obj/item/weapon/weldingtool) && construction_stage == 4)
var/obj/item/weapon/weldingtool/welder = thing
if(!welder.isOn())
to_chat(user, "<span class='warning'>Turn it on first!</span>")
return
if(!welder.remove_fuel(0,user))
to_chat(user, "<span class='warning'>You need more fuel!</span>")
return
user.visible_message("<span class='notice'>\The [user] welds the barrel of \the [src] into place.</span>")
playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1)
increment_construction_stage()
return
if(istype(thing, /obj/item/stack/cable_coil) && construction_stage == 5)
var/obj/item/stack/cable_coil/cable = thing
if(cable.get_amount() < 5)
to_chat(user, "<span class='warning'>You need at least 5 lengths of cable for this task.</span>")
return
cable.use(5)
user.visible_message("<span class='notice'>\The [user] wires \the [src].</span>")
increment_construction_stage()
return
if(istype(thing, /obj/item/weapon/smes_coil) && construction_stage >= 6 && construction_stage <= 8)
user.visible_message("<span class='notice'>\The [user] installs \a [thing] into \the [src].</span>")
user.drop_from_inventory(thing)
qdel(thing)
increment_construction_stage()
return
if(isscrewdriver(thing) && construction_stage >= 9)
user.visible_message("<span class='notice'>\The [user] secures \the [src] and finishes it off.</span>")
playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1)
var/obj/item/weapon/gun/magnetic/coilgun = new(loc)
var/put_in_hands
var/mob/M = src.loc
if(istype(M))
put_in_hands = M == user
M.drop_from_inventory(src)
if(put_in_hands)
user.put_in_hands(coilgun)
qdel(src)
return
return ..()
/obj/item/weapon/coilgun_assembly/proc/increment_construction_stage()
if(construction_stage < 9)
construction_stage++
icon_state = "coilgun_construction_[construction_stage]"
/obj/item/weapon/coilgun_assembly/examine(var/mob/user)
. = ..(user,2)
if(.)
switch(construction_stage)
if(2) to_chat(user, "<span class='notice'>It has a metal frame loosely shaped around the stock.</span>")
if(3) to_chat(user, "<span class='notice'>It has a metal frame duct-taped to the stock.</span>")
if(4) to_chat(user, "<span class='notice'>It has a length of pipe attached to the body.</span>")
if(4) to_chat(user, "<span class='notice'>It has a length of pipe welded to the body.</span>")
if(6) to_chat(user, "<span class='notice'>It has a cable mount and capacitor jack wired to the frame.</span>")
if(7) to_chat(user, "<span class='notice'>It has a single superconducting coil threaded onto the barrel.</span>")
if(8) to_chat(user, "<span class='notice'>It has a pair of superconducting coils threaded onto the barrel.</span>")
if(9) to_chat(user, "<span class='notice'>It has three superconducting coils attached to the body, waiting to be secured.</span>")
@@ -0,0 +1,104 @@
/obj/item/weapon/gun/magnetic/railgun
name = "railgun"
desc = "The Mars Military Industries MI-76 Thunderclap. A man-portable mass driver for squad support anti-armour and destruction of fortifications and emplacements."
gun_unreliable = 0
icon_state = "railgun"
removable_components = FALSE
load_type = /obj/item/weapon/rcd_ammo
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 4, TECH_MAGNET = 4)
projectile_type = /obj/item/projectile/bullet/magnetic/slug
power_cost = 300
w_class = ITEMSIZE_HUGE
slot_flags = SLOT_BELT
loaded = /obj/item/weapon/rcd_ammo/large
var/initial_cell_type = /obj/item/weapon/cell/hyper
var/initial_capacitor_type = /obj/item/weapon/stock_parts/capacitor/adv
var/slowdown_held = 2
var/slowdown_worn = 1
/obj/item/weapon/gun/magnetic/railgun/New()
capacitor = new initial_capacitor_type(src)
capacitor.charge = capacitor.max_charge
cell = new initial_cell_type(src)
if (ispath(loaded))
loaded = new loaded
. = ..()
// Not going to check type repeatedly, if you code or varedit
// load_type and get runtime errors, don't come crying to me.
/obj/item/weapon/gun/magnetic/railgun/show_ammo(var/mob/user)
var/obj/item/weapon/rcd_ammo/ammo = loaded
if (ammo)
to_chat(user, "<span class='notice'>There are [ammo.remaining] shot\s remaining in \the [loaded].</span>")
else
to_chat(user, "<span class='notice'>There is nothing loaded.</span>")
/obj/item/weapon/gun/magnetic/railgun/check_ammo()
var/obj/item/weapon/rcd_ammo/ammo = loaded
return ammo && ammo.remaining
/obj/item/weapon/gun/magnetic/railgun/use_ammo()
var/obj/item/weapon/rcd_ammo/ammo = loaded
ammo.remaining--
if(ammo.remaining <= 0)
spawn(3)
playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 1)
out_of_ammo()
/obj/item/weapon/gun/magnetic/railgun/proc/out_of_ammo()
qdel(loaded)
loaded = null
visible_message("<span class='warning'>\The [src] beeps and ejects its empty cartridge.</span>")
/obj/item/weapon/gun/magnetic/railgun/automatic // Adminspawn only, this shit is absurd.
name = "\improper RHR accelerator"
desc = "The Mars Military Industries MI-227 Meteor. Originally a vehicle-mounted turret weapon for heavy anti-vehicular and anti-structural fire, the fact that it was made man-portable is mindboggling in itself."
icon_state = "heavy_railgun"
initial_cell_type = /obj/item/weapon/cell/infinite
initial_capacitor_type = /obj/item/weapon/stock_parts/capacitor/super
slowdown_held = 3
slowdown_worn = 2
slot_flags = SLOT_BACK
w_class = ITEMSIZE_NO_CONTAINER
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, one_hand_penalty=1, burst_accuracy=null, dispersion=null),
list(mode_name="short bursts", burst=3, fire_delay=null, move_delay=5, one_hand_penalty=2, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0)),
list(mode_name="long bursts", burst=6, fire_delay=null, move_delay=10, one_hand_penalty=2, burst_accuracy=list(0,-1,-1,-1,-2), dispersion=list(0.6, 0.6, 1.0, 1.0, 1.2)),
)
/obj/item/weapon/gun/magnetic/railgun/automatic/examine(var/mob/user)
. = ..(user,1)
if(.)
to_chat(user, "<span class='notice'>Someone has scratched <i>Ultima Ratio Regum</i> onto the side of the barrel.</span>")
/obj/item/weapon/gun/magnetic/railgun/flechette
name = "flechette gun"
desc = "The MI-12 Skadi is a burst fire capable railgun that fires flechette rounds at high velocity. Deadly against armour, but much less effective against soft targets."
icon_state = "flechette_gun"
item_state = "z8carbine"
initial_cell_type = /obj/item/weapon/cell/hyper
initial_capacitor_type = /obj/item/weapon/stock_parts/capacitor/adv
slot_flags = SLOT_BACK
slowdown_held = 0
slowdown_worn = 0
power_cost = 100
load_type = /obj/item/weapon/magnetic_ammo
projectile_type = /obj/item/projectile/bullet/magnetic/flechette
loaded = /obj/item/weapon/magnetic_ammo
fire_sound = 'sound/weapons/rapidslice.ogg'
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, one_hand_penalty=1, burst_accuracy=null, dispersion=null),
list(mode_name="short bursts", burst=3, fire_delay=null, move_delay=5, one_hand_penalty=2, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0)),
)
/obj/item/weapon/gun/magnetic/railgun/flechette/out_of_ammo()
audible_message("<span class='warning'>\The [src] beeps to indicate the magazine is empty.</span>")
playsound(loc, 'sound/weapons/smg_empty_alarm.ogg', 40, 1)
..()
+21 -4
View File
@@ -45,6 +45,8 @@
var/penetrating = 0 //If greater than zero, the projectile will pass through dense objects as specified by on_penetrate()
var/kill_count = 50 //This will de-increment every process(). When 0, it will delete the projectile.
//Effects
var/incendiary = 0 //1 for ignite on hit, 2 for trail of fire. 3 maybe later for burst of fire around the impact point. - Mech
var/flammability = 0 //Amount of fire stacks to add for the above.
var/stun = 0
var/weaken = 0
var/paralyze = 0
@@ -78,7 +80,7 @@
if(!isliving(target)) return 0
// if(isanimal(target)) return 0
var/mob/living/L = target
L.apply_effects(stun, weaken, paralyze, irradiate, stutter, eyeblur, drowsy, agony, blocked) // add in AGONY!
L.apply_effects(stun, weaken, paralyze, irradiate, stutter, eyeblur, drowsy, agony, blocked, incendiary, flammability) // add in AGONY!
return 1
//called when the projectile stops flying because it collided with something
@@ -233,9 +235,18 @@
//if they have a neck grab on someone, that person gets hit instead
var/obj/item/weapon/grab/G = locate() in M
if(G && G.state >= GRAB_NECK)
visible_message("<span class='danger'>\The [M] uses [G.affecting] as a shield!</span>")
if(Bump(G.affecting, forced=1))
return //If Bump() returns 0 (keep going) then we continue on to attack M.
if(G.affecting.stat == DEAD)
var/shield_chance = min(80, (30 * (M.mob_size / 10))) //Small mobs have a harder time keeping a dead body as a shield than a human-sized one. Unathi would have an easier job, if they are made to be SIZE_LARGE in the future. -Mech
if(prob(shield_chance))
visible_message("<span class='danger'>\The [M] uses [G.affecting] as a shield!</span>")
if(Bump(G.affecting, forced=1))
return
else
visible_message("<span class='danger'>\The [M] tries to use [G.affecting] as a shield, but fails!</span>")
else
visible_message("<span class='danger'>\The [M] uses [G.affecting] as a shield!</span>")
if(Bump(G.affecting, forced=1))
return //If Bump() returns 0 (keep going) then we continue on to attack M.
passthrough = !attack_mob(M, distance)
else
@@ -322,6 +333,10 @@
else if(!bumped)
tracer_effect(effect_transform)
if(incendiary >= 2)
var/trail_volume = (flammability * 0.10)
new /obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(src.loc, trail_volume, src.dir)
if(!hitscan)
sleep(step_delay) //add delay between movement iterations if it's not a hitscan weapon
@@ -404,6 +419,8 @@
return //cannot shoot yourself
if(istype(A, /obj/item/projectile))
return
if(istype(A, /obj/structure/foamedmetal)) //Turrets can detect through foamed metal, but will have to blast through it. Similar to windows, if someone runs behind it, a person should probably just not shoot.
return
if(istype(A, /mob/living) || istype(A, /obj/mecha) || istype(A, /obj/vehicle))
result = 2 //We hit someone, return 1!
return
@@ -252,6 +252,31 @@
explosion(target, -1, 0, 2)
..()
/* Incendiary */
/obj/item/projectile/bullet/incendiary
name = "incendiary bullet"
icon_state = "bullet_alt"
damage = 15
damage_type = BURN
incendiary = 1
flammability = 2
/obj/item/projectile/bullet/incendiary/flamethrower
name = "ball of fire"
desc = "Don't stand in the fire."
icon_state = "fireball"
damage = 10
embed_chance = 0
incendiary = 2
flammability = 4
agony = 30
kill_count = 4
/obj/item/projectile/bullet/incendiary/flamethrower/large
damage = 15
kill_count = 6
/obj/item/projectile/bullet/blank
invisibility = 101
damage = 1
@@ -0,0 +1,21 @@
// Rod for railguns. Slightly less nasty than the sniper round.
/obj/item/projectile/bullet/magnetic
name = "rod"
icon_state = "rod"
damage = 65
stun = 1
weaken = 1
penetrating = 5
armor_penetration = 70
/obj/item/projectile/bullet/magnetic/slug
name = "slug"
icon_state = "gauss_silenced"
damage = 75
armor_penetration = 90
/obj/item/projectile/bullet/magnetic/flechette
name = "flechette"
icon_state = "flechette"
damage = 20
armor_penetration = 100
@@ -63,7 +63,13 @@
return
var/removed = metabolism
if(!mrate_static == TRUE)
// Modifiers
for(var/datum/modifier/mod in M.modifiers)
if(!isnull(mod.metabolism_percent))
removed *= mod.metabolism_percent
// Species
removed *= M.species.metabolic_rate
if(ingest_met && (location == CHEM_INGEST))
removed = ingest_met
if(touch_met && (location == CHEM_TOUCH))
@@ -189,7 +189,7 @@
/obj/item/weapon/reagent_containers/food/drinks/bottle/gin
name = "Griffeater Gin"
desc = "A bottle of high quality gin, produced in the New London Space Station."
desc = "A bottle of high quality gin, produced in Alpha Centauri."
icon_state = "ginbottle"
center_of_mass = list("x"=16, "y"=4)
@@ -199,7 +199,7 @@
/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey
name = "Uncle Git's Special Reserve"
desc = "A premium single-malt whiskey, gently matured inside the tunnels of a nuclear shelter. TUNNEL WHISKEY RULES."
desc = "A premium single-malt whiskey, gently matured inside the tunnels of a nuclear shelter."
icon_state = "whiskeybottle"
center_of_mass = list("x"=16, "y"=3)
@@ -219,7 +219,7 @@
/obj/item/weapon/reagent_containers/food/drinks/bottle/vodka
name = "Tunguska Triple Distilled"
desc = "Aah, vodka. Prime choice of drink AND fuel by Russians worldwide."
desc = "Aah, vodka. Prime choice of drink and fuel by Russians worldwide."
icon_state = "vodkabottle"
center_of_mass = list("x"=17, "y"=3)
@@ -259,7 +259,7 @@
/obj/item/weapon/reagent_containers/food/drinks/bottle/rum
name = "Captain Pete's Cuban Spiced Rum"
desc = "This isn't just rum, oh no. It's practically GRIFF in a bottle."
desc = "This isn't just rum, oh no. It's practically Cuba in a bottle."
icon_state = "rumbottle"
center_of_mass = list("x"=16, "y"=8)
@@ -289,7 +289,7 @@
/obj/item/weapon/reagent_containers/food/drinks/bottle/kahlua
name = "Robert Robust's Coffee Liqueur"
desc = "A widely known, Mexican coffee-flavoured liqueur. In production since 1936, HONK"
desc = "A widely known, Mexican coffee-flavoured liqueur. In production since 1936."
icon_state = "kahluabottle"
center_of_mass = list("x"=17, "y"=3)
@@ -309,7 +309,7 @@
/obj/item/weapon/reagent_containers/food/drinks/bottle/cognac
name = "Chateau De Baton Premium Cognac"
desc = "A sweet and strongly alchoholic drink, made after numerous distillations and years of maturing. You might as well not scream 'SHITCURITY' this time."
desc = "A sweet and strongly alchoholic drink, made after numerous distillations and years of maturing."
icon_state = "cognacbottle"
center_of_mass = list("x"=16, "y"=6)
@@ -319,7 +319,7 @@
/obj/item/weapon/reagent_containers/food/drinks/bottle/wine
name = "Doublebeard Bearded Special Wine"
desc = "A faint aura of unease and asspainery surrounds the bottle."
desc = "Cheap cooking wine pretending to be drinkable."
icon_state = "winebottle"
center_of_mass = list("x"=16, "y"=4)
@@ -112,6 +112,8 @@
user << "<span class='notice'>You set the label to \"[tmp_label]\".</span>"
label_text = tmp_label
update_name_label()
if(istype(W,/obj/item/weapon/storage/bag))
..()
/obj/item/weapon/reagent_containers/glass/proc/update_name_label()
if(label_text == "")
+20 -1
View File
@@ -671,7 +671,7 @@ other types of metals and chemistry for reagents).
id = "s-filter"
req_tech = list(TECH_DATA = 3, TECH_MAGNET = 3)
materials = list(DEFAULT_WALL_MATERIAL = 40, "silver" = 10)
build_path = /obj/item/weapon/stock_parts/subspace/filter
build_path = /obj/item/weapon/stock_parts/subspace/sub_filter
sort_string = "UAAAB"
/datum/design/item/stock_part/subspace_amplifier
@@ -853,6 +853,25 @@ other types of metals and chemistry for reagents).
materials = list(DEFAULT_WALL_MATERIAL = 300, "silver" = 100)
build_path = /obj/item/weapon/crowbar/power
sort_string = "VASEA"
/datum/design/item/device/t_scanner_upg
name = "Upgraded T-ray Scanner"
desc = "An upgraded version of the terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
id = "upgradedtscanner"
req_tech = list(TECH_MAGNET = 3, TECH_ENGINEERING = 4, TECH_MATERIAL = 2)
materials = list(DEFAULT_WALL_MATERIAL = 500, "phoron" = 150)
build_path = /obj/item/device/t_scanner/upgraded
sort_string = "VASSA"
/datum/design/item/device/t_scanner_adv
name = "Advanced T-ray Scanner"
desc = "An advanced version of the terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
id = "advancedtscanner"
req_tech = list(TECH_MAGNET = 6, TECH_ENGINEERING = 6, TECH_MATERIAL = 6)
materials = list(DEFAULT_WALL_MATERIAL = 1250, "phoron" = 500, "silver" = 50)
build_path = /obj/item/device/t_scanner/advanced
sort_string = "VASSB"
/*
CIRCUITS BELOW
*/
+24
View File
@@ -354,6 +354,30 @@
materials = list(DEFAULT_WALL_MATERIAL = 15000, "gold" = 4500, "uranium" = 4500)
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang/clusterbang/limited
/datum/design/item/mecha/weapon/flamer
name = "CR-3 Mark 8 Flamethrower"
desc = "A weapon that violates the CCWC at two hundred gallons per minute."
id = "mech_flamer_full"
req_tech = list(TECH_MATERIAL = 4, TECH_COMBAT = 6, TECH_PHORON = 4, TECH_ILLEGAL = 4)
materials = list(DEFAULT_WALL_MATERIAL = 10000, "gold" = 2000, "uranium" = 3000, "phoron" = 8000)
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/flamer
/datum/design/item/mecha/weapon/flamer_rigged
name = "AA-CR-1 Mark 4 Flamethrower"
desc = "A weapon that accidentally violates the CCWC at one hundred gallons per minute."
id = "mech_flamer_rigged"
req_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 3, TECH_PHORON = 3, TECH_ILLEGAL = 2)
materials = list(DEFAULT_WALL_MATERIAL = 8000, "gold" = 1500, "silver" = 1500, "uranium" = 2000, "phoron" = 6000)
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/flamer/rigged
/datum/design/item/mecha/weapon/flame_mg
name = "DR-AC 3 Incendiary Rotary MG"
desc = "A weapon that violates the CCWC at sixty rounds a minute."
id = "mech_lmg_flamer"
req_tech = list(TECH_MATERIAL = 4, TECH_COMBAT = 5, TECH_PHORON = 2, TECH_ILLEGAL = 1)
materials = list(DEFAULT_WALL_MATERIAL = 8000, "gold" = 2000, "silver" = 1750, "uranium" = 1500, "phoron" = 4000)
build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/incendiary
// *** Nonweapon modules
/datum/design/item/mecha/wormhole_gen
name = "Wormhole generator"
+32
View File
@@ -160,6 +160,38 @@
materials = list(DEFAULT_WALL_MATERIAL = 5625, "glass" = 5625)
// req_tech = list(TECH_ENGINEERING = 2, TECH_MATERIAL = 2)
/datum/design/item/prosfab/pros/heart
name = "Prosthetic heart"
id = "pros_heart"
build_path = /obj/item/organ/internal/heart
time = 15
materials = list(DEFAULT_WALL_MATERIAL = 5625, "glass" = 1000)
// req_tech = list(TECH_ENGINEERING = 2, TECH_MATERIAL = 2)
/datum/design/item/prosfab/pros/lungs
name = "Prosthetic lungs"
id = "pros_lung"
build_path = /obj/item/organ/internal/lungs
time = 15
materials = list(DEFAULT_WALL_MATERIAL = 5625, "glass" = 1000)
// req_tech = list(TECH_ENGINEERING = 2, TECH_MATERIAL = 2)
/datum/design/item/prosfab/pros/liver
name = "Prosthetic liver"
id = "pros_liver"
build_path = /obj/item/organ/internal/liver
time = 15
materials = list(DEFAULT_WALL_MATERIAL = 5625, "glass" = 1000)
// req_tech = list(TECH_ENGINEERING = 2, TECH_MATERIAL = 2)
/datum/design/item/prosfab/pros/kidneys
name = "Prosthetic liver"
id = "pros_kidney"
build_path = /obj/item/organ/internal/kidneys
time = 15
materials = list(DEFAULT_WALL_MATERIAL = 5625, "glass" = 1000)
// req_tech = list(TECH_ENGINEERING = 2, TECH_MATERIAL = 2)
//////////////////// Cyborg Parts ////////////////////
/datum/design/item/prosfab/cyborg
category = "Cyborg Parts"
+24 -1
View File
@@ -12,6 +12,7 @@
var/datum/computer/file/embedded_program/docking/docking_controller //the controller itself. (micro-controller, not game controller)
var/arrive_time = 0 //the time at which the shuttle arrives when long jumping
var/depart_time = 0 //Similar to above, set when the shuttle leaves when long jumping, to compare against arrive time.
var/flags = SHUTTLE_FLAGS_PROCESS
var/category = /datum/shuttle
@@ -50,6 +51,14 @@
/datum/shuttle/proc/post_warmup_checks()
return TRUE
// If you need an event to occur when the shuttle jumps in short or long jump, override this.
/datum/shuttle/proc/on_shuttle_departure()
return
// Similar to above, but when it finishes moving to the target. Short jump generally makes this occur immediately after the above proc.
/datum/shuttle/proc/on_shuttle_arrival()
return
/datum/shuttle/proc/short_jump(var/area/origin,var/area/destination)
if(moving_status != SHUTTLE_IDLE)
return
@@ -70,9 +79,14 @@
make_sounds(origin, HYPERSPACE_END)
return //someone cancelled the launch
on_shuttle_departure()
moving_status = SHUTTLE_INTRANSIT //shouldn't matter but just to be safe
move(origin, destination)
moving_status = SHUTTLE_IDLE
on_shuttle_arrival()
make_sounds(destination, HYPERSPACE_END)
/datum/shuttle/proc/long_jump(var/area/departing, var/area/destination, var/area/interim, var/travel_time, var/direction)
@@ -98,7 +112,13 @@
return //someone cancelled the launch
arrive_time = world.time + travel_time*10
depart_time = world.time
on_shuttle_departure()
moving_status = SHUTTLE_INTRANSIT
move(departing, interim, direction)
if(process_longjump(departing, destination)) //VOREStation Edit - To hook custom shuttle code in
@@ -114,7 +134,10 @@
move(interim, destination, direction)
moving_status = SHUTTLE_IDLE
//make_sounds(destination, HYPERSPACE_END) //VOREStation Edit. See above comment.
//on_shuttle_arrival()//VOREStation Edit.
//make_sounds(destination, HYPERSPACE_END)//VOREStation Edit. See above comment.
/datum/shuttle/proc/dock()
if (!docking_controller)
+1 -1
View File
@@ -40,7 +40,7 @@
else
shuttle_status = "Standing-by at offsite location."
if(WAIT_LAUNCH, FORCE_LAUNCH)
shuttle_status = "Shuttle has recieved command and will depart shortly."
shuttle_status = "Shuttle has received command and will depart shortly."
if(WAIT_ARRIVE)
shuttle_status = "Proceeding to destination."
if(WAIT_FINISH)
+274
View File
@@ -0,0 +1,274 @@
//This shuttle traverses a "web" of route_datums to have a wider range of places to go and make flying feel like movement is actually occuring.
/datum/shuttle/web_shuttle
flags = SHUTTLE_FLAGS_NONE
var/cloaked = FALSE
var/can_cloak = FALSE
var/cooldown = 5 SECONDS
var/last_move = 0 //the time at which we last moved
var/area/current_area = null
var/datum/shuttle_web_master/web_master = null
var/web_master_type = null
var/flight_time_modifier = 1.0
category = /datum/shuttle/web_shuttle
/datum/shuttle/web_shuttle/New()
current_area = locate(current_area)
web_master = new web_master_type(src)
build_destinations()
..()
/datum/shuttle/web_shuttle/Destroy()
qdel(web_master)
return ..()
/datum/shuttle/web_shuttle/current_dock_target()
if(web_master)
return web_master.current_dock_target()
/datum/shuttle/web_shuttle/move(var/area/origin, var/area/destination)
..()
last_move = world.time
/datum/shuttle/web_shuttle/on_shuttle_departure()
web_master.on_shuttle_departure()
/datum/shuttle/web_shuttle/on_shuttle_arrival()
web_master.on_shuttle_arrival()
/datum/shuttle/web_shuttle/proc/build_destinations()
return
/obj/machinery/computer/shuttle_control/web
name = "flight computer"
icon_state = "flightcomp_center"
icon_keyboard = "flight_center_key"
icon_screen = "flight_center"
// Fairly copypasta-y.
/obj/machinery/computer/shuttle_control/web/attack_hand(mob/user)
if(..(user))
return
src.add_fingerprint(user)
ui_interact(user)
/*
// If nanoUI falls over and you want a non-nanoUI UI, feel free to uncomment this section.
var/datum/shuttle/web_shuttle/WS = shuttle_controller.shuttles[shuttle_tag]
if(!istype(WS))
message_admins("ERROR: Shuttle computer ([src]) ([shuttle_tag]) could not find their shuttle in the shuttles list.")
return
var/list/dat = list()
dat += "<center>[shuttle_tag] Ship Control<hr>"
if(WS.moving_status != SHUTTLE_IDLE)
dat += "Location: <font color='red'>Moving</font> <br>"
else
var/area/areacheck = get_area(src)
dat += "Location: [areacheck.name]<br>"
if((WS.last_move + WS.cooldown) > world.time)
dat += "<font color='red'>Engines charging.</font><br>"
else
dat += "<font color='green'>Engines ready.</font><br>"
if(WS.can_cloak)
dat += "<br><b><A href='?src=\ref[src];toggle_cloak=[1]'>Toggle cloaking field</A></b><br>"
for(var/datum/shuttle_route/route in WS.current_destination.routes)
dat += "<b><a href='?src=\ref[src];traverse=\ref[route]'>[route.display_route(WS.current_destination)]</a></b><br>"
//Docking
dat += "<br><br>"
if(WS.skip_docking_checks())
dat += "Docking Status: <font color='grey'>Not in use.</font>"
else
var/override_en = WS.docking_controller.override_enabled
var/docking_status = WS.docking_controller.get_docking_status()
dat += "Docking Status: "
switch(docking_status)
if("undocked")
dat += "<font color='[override_en? "red" : "grey"]'>Undocked</font>"
if("docking")
dat += "<font color='[override_en? "red" : "yellow"]'>Docking</font>"
if("undocking")
dat += "<font color='[override_en? "red" : "yellow"]'>Undocking</font>"
if("docked")
dat += "<font color='[override_en? "red" : "green"]'>Docked</font>"
if(override_en)
dat += " <font color='red'>(Override Enabled)</font>"
dat += ". <A href='?src=\ref[src];refresh=[1]'>\[Refresh\]</A><br><br>"
switch(docking_status)
if("undocked")
dat += "<b><A href='?src=\ref[src];dock_command=[1]'>Dock</A></b>"
if("docked")
dat += "<b><A href='?src=\ref[src];undock_command=[1]'>Undock</A></b>"
dat += "</center>"
user << browse(dat.Join(), "window=[shuttle_tag]shuttlecontrol;size=300x300")
*/
/obj/machinery/computer/shuttle_control/web/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
var/list/routes[0]
var/datum/shuttle/web_shuttle/shuttle = shuttle_controller.shuttles[shuttle_tag]
if(!istype(shuttle))
return
var/list/R = shuttle.web_master.get_available_routes()
for (var/i = 1 to length(R))
var/datum/shuttle_route/route = R[i]
var/travel_time = null
var/travel_modifier = shuttle.flight_time_modifier
if(route.travel_time == 0)
travel_time = "Instant"
else if( (route.travel_time * travel_modifier) >= 1 MINUTE)
travel_time = "[ (route.travel_time * travel_modifier) / (1 MINUTE)] minute\s"
else
travel_time = "[ (route.travel_time * travel_modifier) / (1 SECOND)] second\s"
routes.Add(list(list("name" = html_encode(capitalize(route.display_route(shuttle.web_master.current_destination) )), "index" = i, "travel_time" = travel_time)))
var/shuttle_location = shuttle.web_master.current_destination.name // Destination related, not loc.
var/future_location = null
if(shuttle.web_master.future_destination)
future_location = shuttle.web_master.future_destination.name
var/shuttle_state
switch(shuttle.moving_status)
if(SHUTTLE_IDLE)
shuttle_state = "idle"
if(SHUTTLE_WARMUP)
shuttle_state = "warmup"
if(SHUTTLE_INTRANSIT)
shuttle_state = "in_transit"
// For the progress bar.
var/elapsed_time = world.time - shuttle.depart_time
var/total_time = shuttle.arrive_time - shuttle.depart_time
var/percent_finished = 0
if(total_time) // Need to check or we might divide by zero.
percent_finished = (elapsed_time / total_time) * 100
data = list(
"shuttle_location" = shuttle_location,
"future_location" = future_location,
"shuttle_state" = shuttle_state,
"routes" = routes,
"has_docking" = shuttle.docking_controller? 1 : 0,
"skip_docking" = shuttle.skip_docking_checks(),
"is_moving" = shuttle.moving_status != SHUTTLE_IDLE,
"docking_status" = shuttle.docking_controller? shuttle.docking_controller.get_docking_status() : null,
"docking_override" = shuttle.docking_controller? shuttle.docking_controller.override_enabled : null,
"is_in_transit" = shuttle.has_arrive_time(),
"travel_progress" = between(0, percent_finished, 100),
"time_left" = round( (total_time - elapsed_time) / 10),
"can_cloak" = shuttle.can_cloak ? 1 : 0,
"cloaked" = shuttle.cloaked ? 1 : 0
)
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if(!ui)
ui = new(user, src, ui_key, "flight.tmpl", "[shuttle_tag] Flight Computer", 470, 500)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/computer/shuttle_control/web/Topic(href, href_list)
if(..())
return 1
usr.set_machine(src)
src.add_fingerprint(usr)
var/datum/shuttle/web_shuttle/WS = shuttle_controller.shuttles[shuttle_tag]
if(!istype(WS))
message_admins("ERROR: Shuttle computer ([src]) ([shuttle_tag]) could not find their shuttle in the shuttles list.")
return
if(href_list["refresh"])
ui_interact(usr)
if (WS.moving_status != SHUTTLE_IDLE)
usr << "<font color='blue'>[shuttle_tag] vessel is busy moving.</font>"
return
if(href_list["dock_command"])
WS.dock()
if(href_list["undock_command"])
WS.undock()
if(href_list["cloak_command"])
if(!WS.can_cloak)
return
WS.cloaked = TRUE
to_chat(usr, "<span class='danger'>Ship stealth systems have been activated. The station will not be warned of our arrival.</span>")
if(href_list["uncloak_command"])
if(!WS.can_cloak)
return
WS.cloaked = FALSE
to_chat(usr, "<span class='danger'>Ship stealth systems have been deactivated. The station will be warned of our arrival.</span>")
if(href_list["traverse"])
if((WS.last_move + WS.cooldown) > world.time)
usr << "<font color='red'>The ship's drive is inoperable while the engines are charging.</font>"
return
var/index = text2num(href_list["traverse"])
var/datum/shuttle_route/new_route = WS.web_master.current_destination.routes[index]
if(!istype(new_route))
message_admins("ERROR: Shuttle computer was asked to traverse a nonexistant route.")
return
if(!check_docking(WS))
// updateUsrDialog()
ui_interact(usr)
return
var/datum/shuttle_destination/target_destination = new_route.get_other_side(WS.web_master.current_destination)
if(!istype(target_destination))
message_admins("ERROR: Shuttle computer was asked to travel to a nonexistant destination.")
return
WS.web_master.future_destination = target_destination
to_chat(usr, "<span class='notice'>[shuttle_tag] flight computer received command.</span>")
var/travel_time = new_route.travel_time * WS.flight_time_modifier
if(new_route.interim && new_route.travel_time)
WS.long_jump(WS.current_area, target_destination.my_area, new_route.interim, travel_time / 10)
else
WS.short_jump(WS.current_area, target_destination.my_area)
ui_interact(usr)
// Props, for now.
/obj/structure/flight_left
name = "flight computer meters"
desc = "You hope the pilot knows what this does."
icon = 'icons/obj/flight_computer.dmi'
icon_state = "left"
density = TRUE
anchored = TRUE
/obj/structure/flight_right
name = "flight computer panel"
desc = "Probably shouldn't open it."
icon = 'icons/obj/flight_computer.dmi'
icon_state = "right"
density = TRUE
anchored = TRUE
+192
View File
@@ -0,0 +1,192 @@
// This file actually has three seperate datums.
// This is the first datum, and it connects shuttle_destinations together.
/datum/shuttle_route
var/datum/shuttle_destination/start = null // One of the two sides of this route. Start just means it was the creator of this route.
var/datum/shuttle_destination/end = null // The second side.
var/area/interim = null // Where the shuttle sits during the movement. Make sure no other shuttle shares this or Very Bad Things will happen.
var/travel_time = 0 // How long it takes to move from start to end, or end to start. Set to 0 for instant travel.
var/one_way = FALSE // If true, you can't travel from end to start.
/datum/shuttle_route/New(var/_start, var/_end, var/_interim, var/_time = 0, var/_oneway = FALSE)
start = _start
end = _end
if(_interim)
interim = locate(_interim)
travel_time = _time
one_way = _oneway
/datum/shuttle_route/Destroy()
start.routes -= src
end.routes -= src
return ..()
/datum/shuttle_route/proc/get_other_side(var/datum/shuttle_destination/PoV)
if(PoV == start)
return end
if(PoV == end)
return start
return null
/datum/shuttle_route/proc/display_route(var/datum/shuttle_destination/PoV)
var/datum/shuttle_destination/target = null
if(PoV == start)
target = end
else if(PoV == end)
target = start
else
return "ERROR"
return target.name
// This is the second datum, and contains information on all the potential destinations for a specific shuttle.
/datum/shuttle_destination
var/name = "a place" // Name of the destination, used for the flight computer.
var/area/my_area = null // Where the shuttle will move to when it actually arrives.
var/datum/shuttle_web_master/master = null // The datum that does the coordination with the actual shuttle datum.
var/list/routes = list() // Routes that are connected to this destination.
var/preferred_interim_area = null // When building a new route, use this interim area.
var/dock_target = null // The tag_id that the shuttle will use to try to dock to the destination, if able.
var/announcer = null // The name of the 'announcer' that will say the arrival/departure messages. Defaults to the map's boss name if blank.
var/arrival_message = null // Message said if the ship enters this destination. Not announced if the ship is cloaked.
var/departure_message = null // Message said if the ship exits this destination. Not announced if the ship is cloaked.
// When this destination is instantiated, it will go and instantiate other destinations in this assoc list and build routes between them.
// The list format is '/datum/shuttle_destination/subtype = 1 MINUTES'
var/list/destinations_to_create = list()
// When the web_master finishes creating all the destinations, it will go and build routes between this and them if they're on this list.
// The list format is '/datum/shuttle_destination/subtype = 1 MINUTES'
var/list/routes_to_make = list()
/datum/shuttle_destination/New(var/new_master)
my_area = locate(my_area)
master = new_master
/datum/shuttle_destination/Destroy()
for(var/datum/shuttle_route/R in routes)
qdel(R)
master = null
return ..()
// build_destinations()
// This builds destination instances connected to this instance, recursively.
/datum/shuttle_destination/proc/build_destinations(var/list/already_made = list())
already_made += src.type
world << "SHUTTLES: [name] is going to build destinations. already_made list is \[[english_list(already_made)]\]"
for(var/type_to_make in destinations_to_create)
if(type_to_make in already_made) // Avoid circular initializations.
world << "SHUTTLES: [name] can't build [type_to_make] due to being a duplicate."
continue
// Instance the new destination, and call this proc on their 'downstream' destinations.
var/datum/shuttle_destination/new_dest = new type_to_make()
world << "SHUTTLES: [name] has created [new_dest.name] and will make it build their own destinations."
already_made += new_dest.build_destinations(already_made)
// Now link our new destination to us.
var/travel_delay = destinations_to_create[type_to_make]
link_destinations(new_dest, preferred_interim_area, travel_delay)
world << "SHUTTLES: [name] has linked themselves to [new_dest.name]"
world << "SHUTTLES: [name] has finished building destinations. already_made list is \[[english_list(already_made)]\]."
return already_made
/datum/shuttle_destination/proc/enter(var/datum/shuttle_destination/old_destination)
announce_arrival()
/datum/shuttle_destination/proc/exit(var/datum/shuttle_destination/new_destination)
announce_departure()
/datum/shuttle_destination/proc/announce_departure()
if(isnull(departure_message) || master.my_shuttle.cloaked)
return
command_announcement.Announce(departure_message,(announcer ? announcer : "[using_map.boss_name]"))
/datum/shuttle_destination/proc/announce_arrival()
if(isnull(arrival_message) || master.my_shuttle.cloaked)
return
command_announcement.Announce(arrival_message,(announcer ? announcer : "[using_map.boss_name]"))
/datum/shuttle_destination/proc/link_destinations(var/datum/shuttle_destination/other_place, var/area/interim_area, var/travel_time = 0)
// First, check to make sure this doesn't cause a duplicate route.
for(var/datum/shuttle_route/R in routes)
if(R.start == other_place || R.end == other_place)
return
// Now we can connect them.
var/datum/shuttle_route/new_route = new(src, other_place, interim_area, travel_time)
routes += new_route
other_place.routes += new_route
// Depending on certain circumstances, the shuttles can fail.
// What happens depends on where the shuttle is. If it's in space, it just can't move until its fixed.
// If it's flying in Sif, however, things get interesting.
/datum/shuttle_destination/proc/flight_failure()
return
// This is the third and final datum, which coordinates with the shuttle datum to tell it where it is, where it can go, and how long it will take.
// It is also responsible for instancing all the destinations it has control over, and linking them together.
/datum/shuttle_web_master
var/datum/shuttle/web_shuttle/my_shuttle = null // Ref to the shuttle this datum is coordinating with.
var/datum/shuttle_destination/current_destination = null // Where the shuttle currently is. Bit of a misnomer.
var/datum/shuttle_destination/future_destination = null // Where it will be in the near future.
var/datum/shuttle_destination/starting_destination = null // Where the shuttle will start at, generally at the home base.
var/list/destinations = list() // List of currently instanced destinations.
var/destination_class = null // Type to use in typesof(), to build destinations.
/datum/shuttle_web_master/New(var/new_shuttle, var/new_destination_class = null)
my_shuttle = new_shuttle
if(new_destination_class)
destination_class = new_destination_class
build_destinations()
current_destination = get_destination_by_type(starting_destination)
/datum/shuttle_web_master/Destroy()
my_shuttle = null
for(var/datum/shuttle_destination/D in destinations)
qdel(D)
return ..()
/datum/shuttle_web_master/proc/build_destinations()
// First, instantiate all the destination subtypes relevant to this datum.
var/list/destination_types = typesof(destination_class) - destination_class
for(var/new_type in destination_types)
var/datum/shuttle_destination/D = new new_type(src)
destinations += D
// Now start the process of connecting all of them.
for(var/datum/shuttle_destination/D in destinations)
for(var/type_to_link in D.routes_to_make)
var/travel_delay = D.routes_to_make[type_to_link]
D.link_destinations(get_destination_by_type(type_to_link), D.preferred_interim_area, travel_delay)
/datum/shuttle_web_master/proc/on_shuttle_departure()
current_destination.exit()
/datum/shuttle_web_master/proc/on_shuttle_arrival()
if(future_destination)
future_destination.enter()
current_destination = future_destination
future_destination = null
my_shuttle.current_area = current_destination.my_area
/datum/shuttle_web_master/proc/current_dock_target()
if(current_destination)
return current_destination.dock_target
/datum/shuttle_web_master/proc/get_available_routes()
if(current_destination)
return current_destination.routes.Copy()
/datum/shuttle_web_master/proc/get_current_destination()
return current_destination
/datum/shuttle_web_master/proc/get_destination_by_type(var/type_to_get)
return locate(type_to_get) in destinations
+6 -3
View File
@@ -27,13 +27,16 @@
var/obj/item/organ/external/P = target.organs_by_name[E.parent_organ]
var/obj/item/organ/external/affected = target.get_organ(target_zone)
if (affected)
user << "<span class='warning'>Something is in the way! You can't attach [E] here!</span>"
to_chat(user, "<span class='warning'>Something is in the way! You can't attach [E] here!</span>")
return 0
if(!P)
user << "<span class='warning'>There's nothing to attach [E] to!</span>"
to_chat(user, "<span class='warning'>There's nothing to attach [E] to!</span>")
return 0
else if((P.robotic >= ORGAN_ROBOT) && (E.robotic < ORGAN_ROBOT))
user << "<span class='warning'>Attaching [E] to [P] wouldn't work well.</span>"
to_chat(user, "<span class='warning'>Attaching [E] to [P] wouldn't work well.</span>")
return 0
else if(istype(E, /obj/item/organ/external/head) && E.robotic >= ORGAN_ROBOT && P.robotic < ORGAN_ROBOT)
to_chat(user, "<span class='warning'>Attaching [E] to [P] might break [E].</span>")
return 0
else
return 1