Merge remote-tracking branch 'citadel/master' into eldritch_affairs

This commit is contained in:
kevinz000
2020-03-29 20:44:49 -07:00
110 changed files with 2217 additions and 1979 deletions
+1 -1
View File
@@ -25,7 +25,7 @@
to_chat(usr, "You seem to be selecting a mob that doesn't exist anymore.")
return
var/body = "<html><head><title>Options for [M.key]</title></head>"
var/body = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Options for [M.key]</title></head>"
body += "<body>Options panel for <b>[M]</b>"
if(M.client)
body += " played by <b>[M.client]</b> "
+1 -1
View File
@@ -136,7 +136,7 @@
if(!SSticker.HasRoundStarted())
alert("The game hasn't started yet!")
return
var/list/dat = list("<html><head><title>Round Status</title></head><body><h1><B>Round Status</B></h1>")
var/list/dat = list("<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Round Status</title></head><body><h1><B>Round Status</B></h1>")
if(SSticker.mode.replacementmode)
dat += "Former Game Mode: <B>[SSticker.mode.name]</B><BR>"
dat += "Replacement Game Mode: <B>[SSticker.mode.replacementmode.name]</B><BR>"
+3 -1
View File
@@ -83,7 +83,9 @@
<hr style='background:#000000; border:0; height:1px'>"}
qdel(query_check_unused_rank)
else if(!action)
output += {"<head>
output += {"
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<title>Permissions Panel</title>
<script type='text/javascript' src='search.js'></script>
</head>
+1 -1
View File
@@ -2,7 +2,7 @@
if(!check_rights())
return
log_admin("[key_name(usr)] checked the player panel.")
var/dat = "<html><head><title>Player Panel</title></head>"
var/dat = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Player Panel</title></head>"
//javascript, the part that does most of the work~
dat += {"
+2 -2
View File
@@ -79,7 +79,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
title = "Resolved Tickets"
if(!l2b)
return
var/list/dat = list("<html><head><title>[title]</title></head>")
var/list/dat = list("<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>[title]</title></head>")
dat += "<A href='?_src_=holder;[HrefToken()];ahelp_tickets=[state]'>Refresh</A><br><br>"
for(var/I in l2b)
var/datum/admin_help/AH = I
@@ -401,7 +401,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
//Show the ticket panel
/datum/admin_help/proc/TicketPanel()
var/list/dat = list("<html><head><title>Ticket #[id]</title></head>")
var/list/dat = list("<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Ticket #[id]</title></head>")
var/ref_src = "[REF(src)]"
dat += "<h4>Admin Help Ticket #[id]: [LinkedReplyName(ref_src)]</h4>"
dat += "<b>State: "
+3 -3
View File
@@ -934,7 +934,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
id_select += "</select>"
var/dat = {"
<html><head><title>Create Outfit</title></head><body>
<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Create Outfit</title></head><body>
<form name="outfit" action="byond://?src=[REF(src)];[HrefToken()]" method="get">
<input type="hidden" name="src" value="[REF(src)]">
[HrefTokenFormField()]
@@ -1360,7 +1360,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
return
var/list/msg = list()
msg += "<html><head><title>Playtime Report</title></head><body>Playtime:<BR><UL>"
msg += "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Playtime Report</title></head><body>Playtime:<BR><UL>"
for(var/client/C in GLOB.clients)
msg += "<LI> - [key_name_admin(C)]: <A href='?_src_=holder;[HrefToken()];getplaytimewindow=[REF(C.mob)]'>" + C.get_exp_living() + "</a></LI>"
msg += "</UL></BODY></HTML>"
@@ -1377,7 +1377,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
return
var/list/body = list()
body += "<html><head><title>Playtime for [C.key]</title></head><BODY><BR>Playtime:"
body += "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Playtime for [C.key]</title></head><BODY><BR>Playtime:"
body += C.get_exp_report()
body += "<A href='?_src_=holder;[HrefToken()];toggleexempt=[REF(C)]'>Toggle Exempt status</a>"
body += "</BODY></HTML>"
@@ -241,6 +241,9 @@ GLOBAL_LIST_EMPTY(antagonists)
/// Gets our threat level. Defaults to threat var, override for custom stuff like different traitor goals having different threats.
/datum/antagonist/proc/threat()
. = CONFIG_GET(keyed_list/antag_threat)[lowertext(name)]
if(. == null)
return threat
return threat
//This one is created by admin tools for custom objectives
@@ -92,7 +92,7 @@
owner.current.blood_volume = max(owner.current.blood_volume,BLOOD_VOLUME_SAFE)
/datum/antagonist/bloodsucker/threat()
return threat+3*vamplevel
return ..()+3*vamplevel
/datum/antagonist/bloodsucker/proc/SelectFirstName()
@@ -16,7 +16,7 @@
threat = -3
/datum/antagonist/vamphunter/threat()
return bad_dude ? -threat : threat
return bad_dude ? -(..()) : ..()
/datum/antagonist/vamphunter/on_gain()
+1 -1
View File
@@ -114,7 +114,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
var/ascendable = FALSE
/datum/antagonist/devil/threat()
return threat + form * 10
return ..() + form * 10
/datum/antagonist/devil/can_be_owned(datum/mind/new_owner)
. = ..()
+2 -1
View File
@@ -4,12 +4,13 @@
job_rank = ROLE_NINJA
show_name_in_check_antagonists = TRUE
antag_moodlet = /datum/mood_event/focused
threat = 8
var/helping_station = FALSE
var/give_objectives = TRUE
var/give_equipment = TRUE
/datum/antagonist/ninja/threat()
return helping_station ? -8 : 8
return helping_station ? -(..()) : ..()
/datum/antagonist/ninja/apply_innate_effects(mob/living/mob_override)
var/mob/living/M = mob_override || owner.current
@@ -96,6 +96,13 @@
equip(silent)
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/tatoralert.ogg', 100, FALSE, pressure_affected = FALSE)
/datum/antagonist/traitor/antag_panel_objectives()
. = ..()
if(contractor_hub?.assigned_targets && length(contractor_hub.assigned_targets))
. += "<i><b>Contract Targets</b></i>:<br>"
for(var/datum/mind/M in contractor_hub.assigned_targets)
. += "<b> - </b>[key_name(M, FALSE, TRUE)]<br>"
/datum/antagonist/traitor/apply_innate_effects(mob/living/mob_override)
. = ..()
update_traitor_icons_added()
@@ -292,4 +299,4 @@
return SSticker.mode.name == "traitor"
/datum/antagonist/traitor/threat()
return threat+traitor_kind.threat
return (..())+traitor_kind.threat
@@ -645,7 +645,7 @@
/obj/item/spellbook/proc/wrap(content)
var/dat = ""
dat +="<html><head><title>Spellbook</title></head>"
dat +="<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Spellbook</title></head>"
dat += {"
<head>
<style type="text/css">
-38
View File
@@ -164,17 +164,6 @@
/obj/item/shield/riot)
crate_name = "riot shields crate"
/datum/supply_pack/security/armory/riotshotguns
name = "Riot Shotgun Crate"
desc = "For when the greytide gets really uppity. Contains three riot shotguns, seven rubber shot and beanbag shells. Requires Armory access to open."
cost = 6500
contains = list(/obj/item/gun/ballistic/shotgun/riot,
/obj/item/gun/ballistic/shotgun/riot,
/obj/item/gun/ballistic/shotgun/riot,
/obj/item/storage/box/rubbershot,
/obj/item/storage/box/beanbag)
crate_name = "riot shotgun crate"
/datum/supply_pack/security/armory/russian
name = "Russian Surplus Crate"
desc = "Hello Comrade, we have the most modern russian military equipment the black market can offer, for the right price of course. Sadly we couldnt remove the lock so it requires Armory access to open."
@@ -216,23 +205,6 @@
/obj/item/clothing/gloves/combat)
crate_name = "swat crate"
/datum/supply_pack/security/armory/swattasers //Lesser AEG tbh
name = "SWAT tactical tasers Crate"
desc = "Contains two tactical energy gun, these guns are able to tase, disable and lethal as well as hold a seclight. Requires Armory access to open."
cost = 7000
contains = list(/obj/item/gun/energy/e_gun/stun,
/obj/item/gun/energy/e_gun/stun)
crate_name = "swat taser crate"
/datum/supply_pack/security/armory/woodstock
name = "WoodStock Classic Shotguns Crate"
desc = "Contains three rustic, pumpaction shotguns. Requires Armory access to open."
cost = 3000
contains = list(/obj/item/gun/ballistic/shotgun,
/obj/item/gun/ballistic/shotgun,
/obj/item/gun/ballistic/shotgun)
crate_name = "woodstock shotguns crate"
/datum/supply_pack/security/armory/wt550
name = "WT-550 Semi-Auto Rifle Crate"
desc = "Contains two high-powered, semiautomatic rifles chambered in 4.6x30mm. Requires Armory access to open."
@@ -260,13 +232,3 @@
/obj/item/ammo_box/magazine/wt550m9/wtrubber,
/obj/item/ammo_box/magazine/wt550m9/wtrubber)
crate_name = "auto rifle ammo crate"
/datum/supply_pack/security/armory/wt550ammo_special
name = "WT-550 Semi-Auto SMG Special Ammo Crate"
desc = "Contains 2 20-round Armour Piercing and Incendiary magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
cost = 3000
contains = list(/obj/item/ammo_box/magazine/wt550m9/wtap,
/obj/item/ammo_box/magazine/wt550m9/wtap,
/obj/item/ammo_box/magazine/wt550m9/wtic,
/obj/item/ammo_box/magazine/wt550m9/wtic)
crate_name = "auto rifle ammo crate"
-24
View File
@@ -206,30 +206,6 @@
/obj/item/storage/box/mre/menu4/safe)
crate_name = "MRE crate (emergency rations)"
/datum/supply_pack/emergency/syndicate
name = "NULL_ENTRY"
desc = "(#@&^$THIS PACKAGE CONTAINS 30TC WORTH OF SOME RANDOM SYNDICATE GEAR WE HAD LYING AROUND THE WAREHOUSE. GIVE EM HELL, OPERATIVE@&!*() "
hidden = TRUE
cost = 20000
contains = list()
crate_name = "emergency crate"
crate_type = /obj/structure/closet/crate/internals
dangerous = TRUE
/datum/supply_pack/emergency/syndicate/fill(obj/structure/closet/crate/C)
var/crate_value = 30
var/list/uplink_items = get_uplink_items(SSticker.mode)
while(crate_value)
var/category = pick(uplink_items)
var/item = pick(uplink_items[category])
var/datum/uplink_item/I = uplink_items[category][item]
if(!I.surplus_nullcrates || prob(100 - I.surplus_nullcrates))
continue
if(crate_value < I.cost)
continue
crate_value -= I.cost
new I.item(C)
/datum/supply_pack/emergency/plasma_spacesuit
name = "Plasmaman Space Envirosuits"
desc = "Contains two space-worthy envirosuits for Plasmamen. Order now and we'll throw in two free helmets! Requires EVA access to open."
-29
View File
@@ -108,17 +108,6 @@
/obj/item/clothing/gloves/color/latex/nitrile)
crate_name = "nitrile gloves crate"
/datum/supply_pack/science/nuke_b_gone
name = "Nuke Defusal Kit"
desc = "Contains set of tools to defuse a nuke."
cost = 7500 //Useful for traitors/nukies that fucked up
dangerous = TRUE
hidden = TRUE
contains = list(/obj/item/nuke_core_container/nt,
/obj/item/screwdriver/nuke/nt,
/obj/item/paper/guides/nt/nuke_instructions)
crate_name = "safe defusal kit storage"
/datum/supply_pack/science/plasma
name = "Plasma Assembly Crate"
desc = "Everything you need to burn something to the ground, this contains three plasma assembly sets. Each set contains a plasma tank, igniter, proximity sensor, and timer! Warranty void if exposed to high temperatures. Requires Toxins access to open."
@@ -191,17 +180,6 @@
crate_name = "slime core crate"
crate_type = /obj/structure/closet/crate/secure/science
/datum/supply_pack/science/supermater
name = "Supermatter Extraction Tools Crate"
desc = "Contains a set of tools to extract a sliver of supermatter. Consult your CE today!"
cost = 7500 //Useful for traitors that fucked up
hidden = TRUE
contains = list(/obj/item/nuke_core_container/supermatter,
/obj/item/scalpel/supermatter,
/obj/item/hemostat/supermatter,
/obj/item/paper/guides/antag/supermatter_sliver)
crate_name = "supermatter extraction kit crate"
/datum/supply_pack/science/tablets
name = "Tablet Crate"
desc = "What's a computer? Contains five cargo tablets."
@@ -224,10 +202,3 @@
crate_type = /obj/structure/closet/crate/secure/science
dangerous = TRUE
/datum/supply_pack/science/tech_slugs
name = "Tech Slug Ammo Shells"
desc = "A new type of shell that is able to be made into a few different dangerous types. Contains two boxes of tech slugs, 14 shells in all."
cost = 1700
contains = list(/obj/item/storage/box/techsslug,
/obj/item/storage/box/techsslug)
crate_name = "tech slug crate"
+4
View File
@@ -14,6 +14,10 @@
var/jobbancache = null //Used to cache this client's jobbans to save on DB queries
var/last_message = "" //Contains the last message sent by this client - used to protect against copy-paste spamming.
var/last_message_count = 0 //contins a number of how many times a message identical to last_message was sent.
///How many messages sent in the last 10 seconds
var/total_message_count = 0
///Next tick to reset the total message counter
var/total_count_reset = 0
var/ircreplyamount = 0
/////////
+36
View File
@@ -141,7 +141,43 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
return 0
return 1
/*
* Call back proc that should be checked in all paths where a client can send messages
*
* Handles checking for duplicate messages and people sending messages too fast
*
* The first checks are if you're sending too fast, this is defined as sending
* SPAM_TRIGGER_AUTOMUTE messages in
* 5 seconds, this will start supressing your messages,
* if you send 2* that limit, you also get muted
*
* The second checks for the same duplicate message too many times and mutes
* you for it
*/
/client/proc/handle_spam_prevention(message, mute_type)
//Increment message count
total_message_count += 1
//store the total to act on even after a reset
var/cache = total_message_count
if(total_count_reset <= world.time)
total_message_count = 0
total_count_reset = world.time + (5 SECONDS)
//If they're really going crazy, mute them
if(cache >= SPAM_TRIGGER_AUTOMUTE * 2)
total_message_count = 0
total_count_reset = 0
cmd_admin_mute(src, mute_type, 1)
return 1
//Otherwise just supress the message
else if(cache >= SPAM_TRIGGER_AUTOMUTE)
return 1
if(CONFIG_GET(flag/automute_on) && !holder && last_message == message)
src.last_message_count++
if(src.last_message_count >= SPAM_TRIGGER_AUTOMUTE)
+1 -1
View File
@@ -273,7 +273,7 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8")
return
var/list/body = list()
body += "<html><head><title>Playtime for [key]</title></head><BODY><BR>Playtime:"
body += "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Playtime for [key]</title></head><BODY><BR>Playtime:"
body += get_exp_report()
body += "</BODY></HTML>"
usr << browse(body.Join(), "window=playerplaytime[ckey];size=550x615")
+9 -1
View File
@@ -25,7 +25,15 @@
icon_state = "sneakboots"
item_state = "sneakboots"
resistance_flags = FIRE_PROOF | ACID_PROOF
clothing_flags = TRAIT_SILENT_STEP
/obj/item/clothing/shoes/combat/sneakboots/equipped(mob/user, slot)
. = ..()
if(slot == SLOT_SHOES)
ADD_TRAIT(user, TRAIT_SILENT_STEP, SHOES_TRAIT)
/obj/item/clothing/shoes/combat/sneakboots/dropped(mob/user)
. = ..()
REMOVE_TRAIT(user, TRAIT_SILENT_STEP, SHOES_TRAIT)
/obj/item/clothing/shoes/combat/swat //overpowered boots for death squads
name = "\improper SWAT boots"
+2 -2
View File
@@ -87,10 +87,10 @@
. = ..()
if(in_range(user, src) || isobserver(user))
if( !(ishuman(user) || isobserver(user) || hasSiliconAccessInArea(user)) )
user << browse("<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[stars(message)]</BODY></HTML>", "window=[name]")
user << browse("<HTML><HEAD><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><TITLE>[name]</TITLE></HEAD><BODY>[stars(message)]</BODY></HTML>", "window=[name]")
onclose(user, "[name]")
else
user << browse("<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[message]</BODY></HTML>", "window=[name]")
user << browse("<HTML><HEAD><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><TITLE>[name]</TITLE></HEAD><BODY>[message]</BODY></HTML>", "window=[name]")
onclose(user, "[name]")
else
. += "<span class='notice'>It is too far away.</span>"
@@ -116,3 +116,12 @@
bonus_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 4)
tastes = list("rice" = 1, "egg" = 1)
foodtype = GRAIN | MEAT //EGG = MEAT -NinjaNomNom 2017
/obj/item/reagent_containers/food/snacks/salad/caesar
name = "caesar salad"
desc = "You too?"
icon_state = "ceasar_salad"
trash = /obj/item/kitchen/knife
bonus_reagents = list(/datum/reagent/medicine/earthsblood = 1, /datum/reagent/iron = 4)
tastes = list("iron" = 1, "conspiracy" = 1)
foodtype = VEGETABLES
@@ -84,3 +84,13 @@
)
result = /obj/item/reagent_containers/food/snacks/salad/validsalad
subcategory = CAT_SALAD
/datum/crafting_recipe/food/caesarsalad
name = "Caesar salad"
reqs = list(
/obj/item/kitchen/knife = 1,
/obj/item/reagent_containers/food/snacks/grown/ambrosia/gaia = 1,
/obj/item/reagent_containers/food/snacks/grown/cabbage = 1
)
result = /obj/item/reagent_containers/food/snacks/salad/caesar
subcategory = CAT_SALAD
-2
View File
@@ -98,8 +98,6 @@
wine_power = 35
tastes = list("thistle" = 2, "artichoke" = 1)
// Cabbage
/obj/item/seeds/cabbage
name = "pack of cabbage seeds"
@@ -149,7 +149,7 @@
var/total_complexity = return_total_complexity()
var/HTML = ""
HTML += "<html><head><title>[name]</title></head><body>"
HTML += "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>[name]</title></head><body>"
HTML += "<a href='?src=[REF(src)]'>\[Refresh\]</a> | <a href='?src=[REF(src)];rename=1'>\[Rename\]</a><br>"
HTML += "[total_part_size]/[max_components] ([round((total_part_size / max_components) * 100, 0.1)]%) space taken up in the assembly.<br>"
@@ -139,7 +139,7 @@ a creative player the means to solve many problems. Circuits are held inside an
var/table_middle_width = "40%"
var/HTML = ""
HTML += "<html><head><title>[src.displayed_name]</title></head><body>"
HTML += "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>[src.displayed_name]</title></head><body>"
HTML += "<div align='center'>"
HTML += "<table border='1' style='undefined;table-layout: fixed; width: 80%'>"
+2 -1
View File
@@ -95,7 +95,8 @@
<!DOCTYPE html>
<HTML>
<HEAD>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<script>
function hexify(num) {
if(!num) num = 0;
@@ -580,7 +580,7 @@
qdel(src)
/mob/dead/new_player/proc/ViewManifest()
var/dat = "<html><body>"
var/dat = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'></head><body>"
dat += "<h4>Crew Manifest</h4>"
dat += GLOB.data_core.get_manifest(OOC = 1)
+2 -1
View File
@@ -288,7 +288,8 @@
var/output = {"
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<script src="jquery.min.js"></script>
<script src="jquery-ui.custom-core-widgit-mouse-sortable-min.js"></script>
<style>
@@ -380,6 +380,23 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
transfer_ckey(mind.current, FALSE)
return 1
/mob/dead/observer/verb/stay_dead()
set category = "Ghost"
set name = "Do Not Resuscitate"
if(!client)
return
if(!can_reenter_corpse)
to_chat(usr, "<span class='warning'>You're already stuck out of your body!</span>")
return FALSE
var/response = alert(src, "Are you sure you want to prevent (almost) all means of resuscitation? This cannot be undone. ","Are you sure you want to stay dead?","Yes","No")
if(response != "Yes")
return
can_reenter_corpse = FALSE
to_chat(src, "You can no longer be brought back into your body.")
return TRUE
/mob/dead/observer/proc/notify_cloning(var/message, var/sound, var/atom/source, flashwindow = TRUE)
if(flashwindow)
window_flash(client)
@@ -78,6 +78,7 @@
dat = {"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<style type=\"text/css\">
body { background-image:url('html/paigrid.png'); }
@@ -665,4 +666,4 @@
var/dat = "<h3>Sound Synthetizer</h3>"
dat += "<a href='byond://?src=[REF(src)];software=loudness;sub=1'>Open Synthesizer Interface</a><br>"
dat += "<a href='byond://?src=[REF(src)];software=loudness;sub=2'>Choose Instrument Type</a>"
return dat
return dat
+1 -1
View File
@@ -392,7 +392,7 @@
return aicamera.selectpicture(user)
/mob/living/silicon/proc/ai_roster()
var/dat = "<html><head><title>Crew Roster</title></head><body><b>Crew Roster:</b><br><br>"
var/dat = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Crew Roster</title></head><body><b>Crew Roster:</b><br><br>"
dat += GLOB.data_core.get_manifest()
dat += "</body></html>"
@@ -49,7 +49,7 @@
/mob/living/simple_animal/pet/bumbles/handle_automated_movement()
. = ..()
if(!isturf(loc) || !CHECK_MOBILITY(src, MOBILITY_MOVE) || buckled)
if(!isturf(loc) || buckled)
return
if(!resting && prob(1))
emote("me", EMOTE_VISIBLE, pick("curls up on the surface below ", "is looking very sleepy.", "buzzes softly ", "looks around for a flower nap "))
@@ -57,6 +57,7 @@
else if (resting && prob(1))
emote("me", EMOTE_VISIBLE, pick("wakes up with a smiling buzz.", "rolls upside down before waking up.", "stops resting."))
set_resting(FALSE)
/mob/living/simple_animal/pet/bumbles/update_mobility()
. = ..()
if(stat != DEAD)
@@ -17,9 +17,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
response_disarm = "flails at"
response_harm = "punches"
icon = 'icons/mob/guardian.dmi'
icon_state = "magicOrange"
icon_living = "magicOrange"
icon_dead = "magicOrange"
icon_state = "magicbase"
icon_living = "magicbase"
icon_dead = "magicbase"
speed = 0
blood_volume = 0
a_intent = INTENT_HARM
@@ -42,13 +42,16 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
AIStatus = AI_OFF
hud_type = /datum/hud/guardian
dextrous_hud_type = /datum/hud/dextrous/guardian //if we're set to dextrous, account for it.
var/mutable_appearance/cooloverlay
var/guardiancolor = "#ffffff"
var/recolorentiresprite
var/theme
var/list/guardian_overlays[GUARDIAN_TOTAL_LAYERS]
var/reset = 0 //if the summoner has reset the guardian already
var/cooldown = 0
var/mob/living/carbon/summoner
var/range = 13 //how far from the user the spirit can be
var/toggle_button_type = /obj/screen/guardian/ToggleMode/Inactive //what sort of toggle button the hud uses
var/datum/guardianname/namedatum = new/datum/guardianname()
var/playstyle_string = "<span class='holoparasite bold'>You are a standard Guardian. You shouldn't exist!</span>"
var/magic_fluff_string = "<span class='holoparasite'>You draw the Coder, symbolizing bugs and errors. This shouldn't happen! Submit a bug report!</span>"
var/tech_fluff_string = "<span class='holoparasite'>BOOT SEQUENCE COMPLETE. ERROR MODULE LOADED. THIS SHOULDN'T HAPPEN. Submit a bug report!</span>"
@@ -56,7 +59,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
/mob/living/simple_animal/hostile/guardian/Initialize(mapload, theme)
GLOB.parasites += src
setthemename(theme)
updatetheme(theme)
. = ..()
@@ -79,42 +82,36 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
GLOB.parasites -= src
return ..()
/mob/living/simple_animal/hostile/guardian/proc/setthemename(pickedtheme) //set the guardian's theme to something cool!
if(!pickedtheme)
pickedtheme = pick("magic", "tech", "carp")
var/list/possible_names = list()
switch(pickedtheme)
/mob/living/simple_animal/hostile/guardian/proc/updatetheme(theme) //update the guardian's theme
if(!theme)
theme = pick("magic", "tech", "carp")
switch(theme)//should make it easier to create new stand designs in the future if anyone likes that
if("magic")
for(var/type in (subtypesof(/datum/guardianname/magic) - namedatum.type))
possible_names += new type
name = "Guardian Spirit"
real_name = "Guardian Spirit"
bubble_icon = "guardian"
icon_state = "magicbase"
icon_living = "magicbase"
icon_dead = "magicbase"
if("tech")
for(var/type in (subtypesof(/datum/guardianname/tech) - namedatum.type))
possible_names += new type
name = "Holoparasite"
real_name = "Holoparasite"
bubble_icon = "holo"
icon_state = "techbase"
icon_living = "techbase"
icon_dead = "techbase"
if("carp")
for(var/type in (subtypesof(/datum/guardianname/carp) - namedatum.type))
possible_names += new type
namedatum = pick(possible_names)
updatetheme(pickedtheme)
/mob/living/simple_animal/hostile/guardian/proc/updatetheme(theme) //update the guardian's theme to whatever its datum is; proc for adminfuckery
name = "[namedatum.prefixname] [namedatum.suffixcolour]"
real_name = "[name]"
icon_living = "[namedatum.parasiteicon]"
icon_state = "[namedatum.parasiteicon]"
icon_dead = "[namedatum.parasiteicon]"
bubble_icon = "[namedatum.bubbleicon]"
if (namedatum.stainself)
add_atom_colour(namedatum.colour, FIXED_COLOUR_PRIORITY)
//Special case holocarp, because #snowflake code
if(theme == "carp")
speak_emote = list("gnashes")
desc = "A mysterious fish that stands by its charge, ever vigilant."
attacktext = "bites"
attack_sound = 'sound/weapons/bite.ogg'
name = "Holocarp"
real_name = "Holocarp"
bubble_icon = "holo"
icon_state = "holocarp"
icon_living = "holocarp"
icon_dead = "holocarp"
speak_emote = list("gnashes")
desc = "A mysterious fish that stands by its charge, ever vigilant."
attacktext = "bites"
attack_sound = 'sound/weapons/bite.ogg'
recolorentiresprite = TRUE
/mob/living/simple_animal/hostile/guardian/Login() //if we have a mind, set its name to ours when it logs in
..()
@@ -123,10 +120,37 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
if(!summoner)
to_chat(src, "<span class='holoparasite bold'>For some reason, somehow, you have no summoner. Please report this bug immediately.</span>")
return
to_chat(src, "<span class='holoparasite'>You are <font color=\"[namedatum.colour]\"><b>[real_name]</b></font>, bound to serve [summoner.real_name].</span>")
to_chat(src, "<span class='holoparasite'>You are a <b>[real_name]</b>, bound to serve [summoner.real_name].</span>")
to_chat(src, "<span class='holoparasite'>You are capable of manifesting or recalling to your master with the buttons on your HUD. You will also find a button to communicate with [summoner.p_them()] privately there.</span>")
to_chat(src, "<span class='holoparasite'>While personally invincible, you will die if [summoner.real_name] does, and any damage dealt to you will have a portion passed on to [summoner.p_them()] as you feed upon [summoner.p_them()] to sustain yourself.</span>")
to_chat(src, playstyle_string)
guardiancustomize()
/mob/living/simple_animal/hostile/guardian/proc/guardiancustomize()
guardianrecolor()
guardianrename()
/mob/living/simple_animal/hostile/guardian/proc/guardianrecolor()
guardiancolor = input(src,"What would you like your color to be?","Choose Your Color","#ffffff") as color|null
if(!guardiancolor) //redo proc until we get a color
to_chat(src, "<span class='warning'>Not a valid color, please try again.</span>")
guardianrecolor()
return
if(!recolorentiresprite)
cooloverlay.color = guardiancolor
cut_overlay(cooloverlay) //we need to get our new color
add_overlay(cooloverlay)
else
add_atom_colour(guardiancolor, FIXED_COLOUR_PRIORITY)
/mob/living/simple_animal/hostile/guardian/proc/guardianrename()
var/new_name = sanitize_name(reject_bad_text(stripped_input(src, "What would you like your name to be?", "Choose Your Name", real_name, MAX_NAME_LEN)))
if(!new_name) //redo proc until we get a good name
to_chat(src, "<span class='warning'>Not a valid name, please try again.</span>")
guardianrename()
return
visible_message("<span class='notice'>Your new name <span class='name'>[new_name]</span> anchors itself in your mind.</span>")
fully_replace_character_name(null, new_name)
/mob/living/simple_animal/hostile/guardian/Life() //Dies if the summoner dies
. = ..()
@@ -366,7 +390,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
return
var/preliminary_message = "<span class='holoparasite bold'>[input]</span>" //apply basic color/bolding
var/my_message = "<font color=\"[namedatum.colour]\"><b><i>[src]:</i></b></font> [preliminary_message]" //add source, color source with the guardian's color
var/my_message = "<font color=\"[guardiancolor]\"><b><i>[src]:</i></b></font> [preliminary_message]" //add source, color source with the guardian's color
to_chat(summoner, my_message)
var/list/guardians = summoner.hasparasites()
@@ -393,7 +417,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
var/list/guardians = hasparasites()
for(var/para in guardians)
var/mob/living/simple_animal/hostile/guardian/G = para
to_chat(G, "<font color=\"[G.namedatum.colour]\"><b><i>[src]:</i></b></font> [preliminary_message]" )
to_chat(G, "<font color=\"[G.guardiancolor]\"><b><i>[src]:</i></b></font> [preliminary_message]" )
for(var/M in GLOB.dead_mob_list)
var/link = FOLLOW_LINK(M, src)
to_chat(M, "[link] [my_message]")
@@ -424,27 +448,29 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
if(guardians.len)
var/mob/living/simple_animal/hostile/guardian/G = input(src, "Pick the guardian you wish to reset", "Guardian Reset") as null|anything in guardians
if(G)
to_chat(src, "<span class='holoparasite'>You attempt to reset <font color=\"[G.namedatum.colour]\"><b>[G.real_name]</b></font>'s personality...</span>")
to_chat(src, "<span class='holoparasite'>You attempt to reset <font color=\"[G.guardiancolor]\"><b>[G.real_name]</b></font>'s personality...</span>")
var/list/mob/candidates = pollGhostCandidates("Do you want to play as [src.real_name]'s [G.real_name]?", ROLE_PAI, null, FALSE, 100)
if(LAZYLEN(candidates))
var/mob/C = pick(candidates)
to_chat(G, "<span class='holoparasite'>Your user reset you, and your body was taken over by a ghost. Looks like they weren't happy with your performance.</span>")
to_chat(src, "<span class='holoparasite bold'>Your <font color=\"[G.namedatum.colour]\">[G.real_name]</font> has been successfully reset.</span>")
to_chat(src, "<span class='holoparasite bold'>Your <font color=\"[G.guardiancolor]\">[G.real_name]</font> has been successfully reset.</span>")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(G)])")
G.ghostize(FALSE)
G.setthemename(G.namedatum.theme) //give it a new color, to show it's a new person
G.guardiancustomize() //give it a new color, to show it's a new person
C.transfer_ckey(G)
G.reset = 1
switch(G.namedatum.theme)
switch(G.theme)
if("tech")
to_chat(src, "<span class='holoparasite'><font color=\"[G.namedatum.colour]\"><b>[G.real_name]</b></font> is now online!</span>")
to_chat(src, "<span class='holoparasite'><font color=\"[G.guardiancolor]\"><b>[G.real_name]</b></font> is now online!</span>")
if("magic")
to_chat(src, "<span class='holoparasite'><font color=\"[G.namedatum.colour]\"><b>[G.real_name]</b></font> has been summoned!</span>")
to_chat(src, "<span class='holoparasite'><font color=\"[G.guardiancolor]\"><b>[G.real_name]</b></font> has been summoned!</span>")
if("carp")
to_chat(src, "<span class='holoparasite'><font color=\"[G.guardiancolor]\"><b>[G.real_name]</b></font> has been caught!</span>")
guardians -= G
if(!guardians.len)
verbs -= /mob/living/proc/guardian_reset
else
to_chat(src, "<span class='holoparasite'>There were no ghosts willing to take control of <font color=\"[G.namedatum.colour]\"><b>[G.real_name]</b></font>. Looks like you're stuck with it for now.</span>")
to_chat(src, "<span class='holoparasite'>There were no ghosts willing to take control of <font color=\"[G.guardiancolor]\"><b>[G.real_name]</b></font>. Looks like you're stuck with it for now.</span>")
else
to_chat(src, "<span class='holoparasite'>You decide not to reset [guardians.len > 1 ? "any of your guardians":"your guardian"].</span>")
else
@@ -558,6 +584,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
used = FALSE
return
var/mob/living/simple_animal/hostile/guardian/G = new pickedtype(user, theme)
G.name = mob_name
G.summoner = user
G.key = key
G.mind.enslave_mind_to_creator(user)
@@ -565,13 +592,13 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
switch(theme)
if("tech")
to_chat(user, "[G.tech_fluff_string]")
to_chat(user, "<span class='holoparasite'><font color=\"[G.namedatum.colour]\"><b>[G.real_name]</b></font> is now online!</span>")
to_chat(user, "<span class='holoparasite'><b>[G.real_name]</b> is now online!</span>")
if("magic")
to_chat(user, "[G.magic_fluff_string]")
to_chat(user, "<span class='holoparasite'><font color=\"[G.namedatum.colour]\"><b>[G.real_name]</b></font> has been summoned!</span>")
to_chat(user, "<span class='holoparasite'><b>[G.real_name]</b> has been summoned!</span>")
if("carp")
to_chat(user, "[G.carp_fluff_string]")
to_chat(user, "<span class='holoparasite'><font color=\"[G.namedatum.colour]\"><b>[G.real_name]</b></font> has been caught!</span>")
to_chat(user, "<span class='holoparasite'><b>[G.real_name]</b> has been caught!</span>")
user.verbs += /mob/living/proc/guardian_comm
user.verbs += /mob/living/proc/guardian_recall
user.verbs += /mob/living/proc/guardian_reset
@@ -600,6 +627,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
/obj/item/guardiancreator/tech/choose/traitor
possible_guardians = list("Assassin", "Chaos", "Charger", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
allowling = FALSE
/obj/item/guardiancreator/tech/choose/traitor/check_uplink_validity()
return !used
@@ -683,8 +711,6 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
failure_message = "<span class='holoparasite bold'>You couldn't catch any carp spirits from the seas of Lake Carp. Maybe there are none, maybe you fucked up.</span>"
ling_failure = "<span class='holoparasite bold'>Carp'sie is fine with changelings, so you shouldn't be seeing this message.</span>"
allowmultiple = TRUE
allowling = TRUE
random = TRUE
/obj/item/guardiancreator/carp/choose
random = FALSE
@@ -1,161 +0,0 @@
/datum/guardianname
var/prefixname = "Default" //the prefix the guardian uses for its name
var/suffixcolour = "Name" //the suffix the guardian uses for its name
var/parasiteicon = "techbase" //the icon of the guardian
var/bubbleicon = "holo" //the speechbubble icon of the guardian
var/theme = "tech" //what the actual theme of the guardian is
var/colour = "#C3C3C3" //what color the guardian's name is in chat and what color is used for effects from the guardian
var/stainself = 0 //whether to use the color var to literally dye ourself our chosen colour, for lazy spriting
/datum/guardianname/carp
bubbleicon = "guardian"
theme = "carp"
parasiteicon = "holocarp"
stainself = 1
/datum/guardianname/carp/New()
prefixname = pick(GLOB.carp_names)
/datum/guardianname/carp/sand
suffixcolour = "Sand"
colour = "#C2B280"
/datum/guardianname/carp/seashell
suffixcolour = "Seashell"
colour = "#FFF5EE"
/datum/guardianname/carp/coral
suffixcolour = "Coral"
colour = "#FF7F50"
/datum/guardianname/carp/salmon
suffixcolour = "Salmon"
colour = "#FA8072"
/datum/guardianname/carp/sunset
suffixcolour = "Sunset"
colour = "#FAD6A5"
/datum/guardianname/carp/riptide
suffixcolour = "Riptide"
colour = "#89D9C8"
/datum/guardianname/carp/seagreen
suffixcolour = "Sea Green"
colour = "#2E8B57"
/datum/guardianname/carp/ultramarine
suffixcolour = "Ultramarine"
colour = "#3F00FF"
/datum/guardianname/carp/cerulean
suffixcolour = "Cerulean"
colour = "#007BA7"
/datum/guardianname/carp/aqua
suffixcolour = "Aqua"
colour = "#00FFFF"
/datum/guardianname/carp/paleaqua
suffixcolour = "Pale Aqua"
colour = "#BCD4E6"
/datum/guardianname/carp/hookergreen
suffixcolour = "Hooker Green"
colour = "#49796B"
/datum/guardianname/magic
bubbleicon = "guardian"
theme = "magic"
/datum/guardianname/magic/New()
prefixname = pick("Aries", "Leo", "Sagittarius", "Taurus", "Virgo", "Capricorn", "Gemini", "Libra", "Aquarius", "Cancer", "Scorpio", "Pisces", "Ophiuchus")
/datum/guardianname/magic/red
suffixcolour = "Red"
parasiteicon = "magicRed"
colour = "#E32114"
/datum/guardianname/magic/pink
suffixcolour = "Pink"
parasiteicon = "magicPink"
colour = "#FB5F9B"
/datum/guardianname/magic/orange
suffixcolour = "Orange"
parasiteicon = "magicOrange"
colour = "#F3CF24"
/datum/guardianname/magic/green
suffixcolour = "Green"
parasiteicon = "magicGreen"
colour = "#A4E836"
/datum/guardianname/magic/blue
suffixcolour = "Blue"
parasiteicon = "magicBlue"
colour = "#78C4DB"
/datum/guardianname/tech/New()
prefixname = pick("Gallium", "Indium", "Thallium", "Bismuth", "Aluminium", "Mercury", "Iron", "Silver", "Zinc", "Titanium", "Chromium", "Nickel", "Platinum", "Tellurium", "Palladium", "Rhodium", "Cobalt", "Osmium", "Tungsten", "Iridium")
/datum/guardianname/tech/rose
suffixcolour = "Rose"
parasiteicon = "techRose"
colour = "#F62C6B"
/datum/guardianname/tech/peony
suffixcolour = "Peony"
parasiteicon = "techPeony"
colour = "#E54750"
/datum/guardianname/tech/lily
suffixcolour = "Lily"
parasiteicon = "techLily"
colour = "#F6562C"
/datum/guardianname/tech/daisy
suffixcolour = "Daisy"
parasiteicon = "techDaisy"
colour = "#ECCD39"
/datum/guardianname/tech/zinnia
suffixcolour = "Zinnia"
parasiteicon = "techZinnia"
colour = "#89F62C"
/datum/guardianname/tech/ivy
suffixcolour = "Ivy"
parasiteicon = "techIvy"
colour = "#5DF62C"
/datum/guardianname/tech/iris
suffixcolour = "Iris"
parasiteicon = "techIris"
colour = "#2CF6B8"
/datum/guardianname/tech/petunia
suffixcolour = "Petunia"
parasiteicon = "techPetunia"
colour = "#51A9D4"
/datum/guardianname/tech/violet
suffixcolour = "Violet"
parasiteicon = "techViolet"
colour = "#8A347C"
/datum/guardianname/tech/lotus
suffixcolour = "Lotus"
parasiteicon = "techLotus"
colour = "#463546"
/datum/guardianname/tech/lilac
suffixcolour = "Lilac"
parasiteicon = "techLilac"
colour = "#C7A0F6"
/datum/guardianname/tech/orchid
suffixcolour = "Orchid"
parasiteicon = "techOrchid"
colour = "#F62CF5"
@@ -77,7 +77,7 @@
user.ex_act(EXPLODE_HEAVY)
qdel(src)
else
to_chat(user, "<span class='holoparasite'>[src] glows with a strange <font color=\"[spawner.namedatum.colour]\">light</font>, and you don't touch it.</span>")
to_chat(user, "<span class='holoparasite'>[src] glows with a strange <font color=\"[spawner.guardiancolor]\">light</font>, and you don't touch it.</span>")
/obj/guardian_bomb/Bump(atom/A)
detonate(A)
@@ -93,4 +93,4 @@
/obj/guardian_bomb/examine(mob/user)
. = stored_obj.examine(user)
if(get_dist(user,src)<=2)
. += "<span class='holoparasite'>It glows with a strange <font color=\"[spawner.namedatum.colour]\">light</font>!</span>"
. += "<span class='holoparasite'>It glows with a strange <font color=\"[spawner.guardiancolor]\">light</font>!</span>"
@@ -21,8 +21,8 @@
. = ..()
if(. > 0 && toggle)
var/image/I = new('icons/effects/effects.dmi', src, "shield-flash", MOB_LAYER+0.01, dir = pick(GLOB.cardinals))
if(namedatum)
I.color = namedatum.colour
if(guardiancolor)
I.color = guardiancolor
flick_overlay_view(I, src, 5)
/mob/living/simple_animal/hostile/guardian/protector/ToggleMode()
@@ -39,8 +39,8 @@
toggle = FALSE
else
var/mutable_appearance/shield_overlay = mutable_appearance('icons/effects/effects.dmi', "shield-grey")
if(namedatum)
shield_overlay.color = namedatum.colour
if(guardiancolor)
shield_overlay.color = guardiancolor
add_overlay(shield_overlay)
melee_damage_lower = 5
melee_damage_upper = 5
@@ -59,7 +59,7 @@
visible_message("<span class='danger'>\The [src] jumps back to its user.</span>")
Recall(TRUE)
else
to_chat(summoner, "<span class='holoparasite'>You moved out of range, and were pulled back! You can only move [range] meters from <font color=\"[namedatum.colour]\"><b>[real_name]</b></font>!</span>")
to_chat(summoner, "<span class='holoparasite'>You moved out of range, and were pulled back! You can only move [range] meters from <font color=\"[guardiancolor]\"><b>[real_name]</b></font>!</span>")
summoner.visible_message("<span class='danger'>\The [summoner] jumps back to [summoner.p_their()] protector.</span>")
new /obj/effect/temp_visual/guardian/phase/out(get_turf(summoner))
summoner.forceMove(get_turf(src))
@@ -55,8 +55,8 @@
. = ..()
if(istype(., /obj/item/projectile))
var/obj/item/projectile/P = .
if(namedatum)
P.color = namedatum.colour
if(guardiancolor)
P.color = guardiancolor
/mob/living/simple_animal/hostile/guardian/ranged/ToggleLight()
var/msg
@@ -32,8 +32,8 @@
C.adjustOxyLoss(-5)
C.adjustToxLoss(-5, forced = TRUE)
var/obj/effect/temp_visual/heal/H = new /obj/effect/temp_visual/heal(get_turf(C))
if(namedatum)
H.color = namedatum.colour
if(guardiancolor)
H.color = guardiancolor
if(C == summoner)
update_health_hud()
med_hud_set_health()
@@ -96,8 +96,8 @@
/obj/structure/receiving_pad/New(loc, mob/living/simple_animal/hostile/guardian/healer/G)
. = ..()
if(G.namedatum)
add_atom_colour(G.namedatum.colour, FIXED_COLOUR_PRIORITY)
if(G.guardiancolor)
add_atom_colour(G.guardiancolor, FIXED_COLOUR_PRIORITY)
/obj/structure/receiving_pad/proc/disappear()
visible_message("[src] vanishes!")
+2 -2
View File
@@ -15,8 +15,8 @@
/obj/item/clothing/shoes/space_ninja/equipped(mob/user, slot)
. = ..()
if(slot == SLOT_SHOES)
ADD_TRAIT(user, TRAIT_SILENT_STEP, "ninja_shoes_[REF(src)]")
ADD_TRAIT(user, TRAIT_SILENT_STEP, SHOES_TRAIT)
/obj/item/clothing/shoes/space_ninja/dropped(mob/user)
. = ..()
REMOVE_TRAIT(user, TRAIT_SILENT_STEP, "ninja_shoes_[REF(src)]")
REMOVE_TRAIT(user, TRAIT_SILENT_STEP, SHOES_TRAIT)
+1 -1
View File
@@ -80,7 +80,7 @@
var/obj/item/P = contents[i]
dat += "<tr><td><a href='?src=[REF(src)];retrieve=[REF(P)]'>[P.name]</a></td></tr>"
dat += "</table></center>"
user << browse("<html><head><title>[name]</title></head><body>[dat]</body></html>", "window=filingcabinet;size=350x300")
user << browse("<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>[name]</title></head><body>[dat]</body></html>", "window=filingcabinet;size=350x300")
/obj/structure/filingcabinet/attack_tk(mob/user)
if(anchored)
+4 -4
View File
@@ -62,11 +62,11 @@
/obj/item/paper/oui_getcontent(mob/target)
if(!target.is_literate() || force_stars)
force_stars = FALSE
return "<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[stars(info)]<HR>[stamps]</BODY></HTML>"
return "<HTML><HEAD><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><TITLE>[name]</TITLE></HEAD><BODY>[stars(info)]<HR>[stamps]</BODY></HTML>"
else if(istype(target.get_active_held_item(), /obj/item/pen) | istype(target.get_active_held_item(), /obj/item/toy/crayon))
return "<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[info_links]<HR>[stamps]</BODY><div align='right'style='position:fixed;bottom:0;font-style:bold;'><A href='?src=[REF(src)];help=1'>\[?\]</A></div></HTML>"
return "<HTML><HEAD><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><TITLE>[name]</TITLE></HEAD><BODY>[info_links]<HR>[stamps]</BODY><div align='right'style='position:fixed;bottom:0;font-style:bold;'><A href='?src=[REF(src)];help=1'>\[?\]</A></div></HTML>"
else
return "<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[info]<HR>[stamps]</BODY></HTML>"
return "<HTML><HEAD><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><TITLE>[name]</TITLE></HEAD><BODY>[info]<HR>[stamps]</BODY></HTML>"
/obj/item/paper/oui_canview(mob/target)
if(check_rights_for(target.client, R_FUN)) //Allows admins to view faxes
@@ -231,7 +231,7 @@
/obj/item/paper/proc/openhelp(mob/user)
user << browse({"<HTML><HEAD><TITLE>Paper Help</TITLE></HEAD>
user << browse({"<HTML><HEAD><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><TITLE>Paper Help</TITLE></HEAD>
<BODY>
You can use backslash (\\) to escape special characters.<br>
<br>
+1 -1
View File
@@ -72,7 +72,7 @@
to_chat(user, "<span class='warning'>[src] seems to be blank...</span>")
return
user << browse_rsc(picture.picture_image, "tmp_photo.png")
user << browse("<html><head><title>[name]</title></head>" \
user << browse("<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>[name]</title></head>" \
+ "<body style='overflow:hidden;margin:0;text-align:center'>" \
+ "<img src='tmp_photo.png' width='480' style='-ms-interpolation-mode:nearest-neighbor' />" \
+ "[scribble ? "<br>Written on the back:<br><i>[scribble]</i>" : ""]"\
@@ -95,7 +95,7 @@
name = "scatter laser shell"
desc = "An advanced shotgun shell that uses a micro laser to replicate the effects of a scatter laser weapon in a ballistic package."
icon_state = "lshell"
projectile_type = /obj/item/projectile/beam/weak
projectile_type = /obj/item/projectile/beam/scatter
pellets = 6
variance = 35
@@ -130,12 +130,16 @@
ENABLE_BITFIELD(reagents.reagents_holder_flags, NO_REACT)
/obj/item/ammo_casing/shotgun/dart/bioterror
desc = "A shotgun dart filled with deadly toxins."
desc = "A shotgun dart filled with an obscene amount of lethal reagents. God help whoever is shot with this."
projectile_type = /obj/item/projectile/bullet/dart/piercing
reagent_amount = 50
/obj/item/ammo_casing/shotgun/dart/bioterror/Initialize()
. = ..()
reagents.add_reagent(/datum/reagent/toxin/fentanyl, 6)
reagents.add_reagent(/datum/reagent/toxin/spore, 6)
reagents.add_reagent(/datum/reagent/toxin/mutetoxin, 6) //;HELP OPS IN MAINT
reagents.add_reagent(/datum/reagent/toxin/coniine, 6)
reagents.add_reagent(/datum/reagent/toxin/sodium_thiopental, 6)
reagents.add_reagent(/datum/reagent/toxin/amanitin, 12) //for a nasty surprise after you get shot and somehow escape and don't think to quickly purge, and even shock those who are loaded up on purging agents
reagents.add_reagent(/datum/reagent/toxin/chloralhydrate, 6)
reagents.add_reagent(/datum/reagent/toxin/mutetoxin, 6) //;HELPIES OPS IN MAINT
reagents.add_reagent(/datum/reagent/impedrezene, 6)
reagents.add_reagent(/datum/reagent/toxin/acid/fluacid, 5) //this and the acid equal about 25ish burn, not counting the minute toxin damage dealt by their metabolism, this makes each dart about as lethal as a stechkin shot in upfront damage
reagents.add_reagent(/datum/reagent/toxin/acid, 5)
reagents.add_reagent(/datum/reagent/consumable/frostoil, 10) //tempgun slowdown goes both ways and adds to the burn
@@ -273,7 +273,7 @@
icon_state = "dshotgun"
item_state = "shotgun"
w_class = WEIGHT_CLASS_BULKY
weapon_weight = WEAPON_HEAVY
weapon_weight = WEAPON_MEDIUM
force = 10
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BACK
+1 -1
View File
@@ -50,7 +50,7 @@
/obj/item/projectile/beam/scatter
name = "laser pellet"
icon_state = "scatterlaser"
damage = 5
damage = 12.5
/obj/item/projectile/beam/xray
name = "\improper X-ray beam"
@@ -29,6 +29,9 @@
reagents.handle_reactions()
return BULLET_ACT_HIT
/obj/item/projectile/bullet/dart/piercing
piercing = TRUE
/obj/item/projectile/bullet/dart/metalfoam/Initialize()
. = ..()
reagents.add_reagent(/datum/reagent/aluminium, 15)
@@ -18,13 +18,28 @@
/obj/item/projectile/bullet/shotgun_stunslug
name = "stunslug"
damage = 5
stamina = 20
knockdown = 100
stamina = 30
stutter = 5
jitter = 20
range = 7
icon_state = "spark"
color = "#FFFF00"
var/tase_duration = 50
/obj/item/projectile/bullet/shotgun_stunslug/on_hit(atom/target, blocked = FALSE)
. = ..()
if(!ismob(target) || blocked >= 100) //Fully blocked by mob or collided with dense object - burst into sparks!
do_sparks(1, TRUE, src)
if(iscarbon(target))
var/mob/living/carbon/C = target
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "tased", /datum/mood_event/tased)
SEND_SIGNAL(C, COMSIG_LIVING_MINOR_SHOCK)
C.IgniteMob()
if(C.dna && C.dna.check_mutation(HULK))
C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
else if(tase_duration && (C.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(C, TRAIT_STUNIMMUNE) && !HAS_TRAIT(C, TRAIT_TASED_RESISTANCE))
C.electrocute_act(15, src, 1, SHOCK_NOSTUN)
C.apply_status_effect(STATUS_EFFECT_TASED_WEAK, tase_duration)
/obj/item/projectile/bullet/shotgun_meteorslug
name = "meteorslug"
@@ -93,7 +108,6 @@
/obj/item/projectile/bullet/scattershot
damage = 20
stamina = 65
/obj/item/projectile/bullet/seed
damage = 4
-6
View File
@@ -65,7 +65,6 @@
var/refund_amount = 0 // specified refund amount in case there needs to be a TC penalty for refunds.
var/refundable = FALSE
var/surplus = 100 // Chance of being included in the surplus crate.
var/surplus_nullcrates //Chance of being included in null crates. null = pull from surplus
var/cant_discount = FALSE
var/limited_stock = -1 //Setting this above zero limits how many times this item can be bought by the same traitor in a round, -1 is unlimited
var/list/include_modes = list() // Game modes to allow this item in.
@@ -76,11 +75,6 @@
var/restricted = FALSE // Adds restrictions for VR/Events
var/illegal_tech = TRUE // Can this item be deconstructed to unlock certain techweb research nodes?
/datum/uplink_item/New()
. = ..()
if(isnull(surplus_nullcrates))
surplus_nullcrates = surplus
/datum/uplink_item/proc/get_discount()
return pick(4;0.75,2;0.5,1;0.25)
@@ -56,6 +56,13 @@
item = /obj/item/storage/backpack/duffelbag/syndie/ammo/shotgun
cost = 12
/datum/uplink_item/ammo/shotgun/bioterror
name = "12g Bioterror Dart Drum"
desc = "An additional 8-round bioterror dart magazine for use with the Bulldog shotgun. \
Pierces armor and injects are horrid cocktail of death into your target. Be careful about friendly fire."
cost = 6 //legacy price
item = /obj/item/ammo_box/magazine/m12g/bioterror
/datum/uplink_item/ammo/shotgun/buck
name = "12g Buckshot Drum"
desc = "An additional 8-round buckshot magazine for use with the Bulldog shotgun. Front towards enemy."
@@ -66,20 +73,12 @@
desc = "An alternative 8-round dragon's breath magazine for use in the Bulldog shotgun. \
'I'm a fire starter, twisted fire starter!'"
item = /obj/item/ammo_box/magazine/m12g/dragon
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/ammo/shotgun/meteor
name = "12g Meteorslug Shells"
desc = "An alternative 8-round meteorslug magazine for use in the Bulldog shotgun. \
Great for blasting airlocks off their frames and knocking down enemies."
item = /obj/item/ammo_box/magazine/m12g/meteor
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/ammo/shotgun/scatter
name = "12g Scatter Laser shot Slugs"
desc = "An alternative 8-round Scatter Laser Shot magazine for use in the Bulldog shotgun."
item = /obj/item/ammo_box/magazine/m12g/scatter
cost = 4 // most armor has less laser protection then bullet
/datum/uplink_item/ammo/shotgun/slug
name = "12g Slug Drum"
@@ -93,7 +92,6 @@
desc = "An alternative 8-round stun slug magazine for use with the Bulldog shotgun. \
Saying that they're completely non-lethal would be lying."
item = /obj/item/ammo_box/magazine/m12g/stun
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/ammo/revolver
name = ".357 Speed Loader"