mirror of
https://github.com/CHOMPstation/CHOMPstation.git
synced 2026-07-18 10:32:32 +01:00
Polaris Sync
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -83,12 +83,12 @@
|
||||
if (!fqs)
|
||||
output += " <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 += " [filter]: ERROR<br>"
|
||||
output += " [radio_filter]: ERROR<br>"
|
||||
continue
|
||||
output += " [filter]: [f.len]<br>"
|
||||
output += " [radio_filter]: [f.len]<br>"
|
||||
for (var/device in f)
|
||||
if (isobj(device))
|
||||
output += " [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,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)
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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")
|
||||
@@ -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."
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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()
|
||||
..()
|
||||
|
||||
@@ -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
|
||||
@@ -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)]%"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
)
|
||||
@@ -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!")
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
..()
|
||||
@@ -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 == "")
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user