diff --git a/.gitignore b/.gitignore index 0dc17248d0..7daab15618 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,3 @@ *.rsc *.dmb *.lk - -#ignore any files in config/, except those in subdirectories. -/config/* -!/config/*/* - -/baystation12.int diff --git a/baystation12.dme b/baystation12.dme index b8631a47eb..1c736af88b 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -824,6 +824,7 @@ #include "code\modules\maps\reader.dm" #include "code\modules\maps\swapmaps.dm" #include "code\modules\maps\writer.dm" +#include "code\modules\mining\abandonedcrates.dm" #include "code\modules\mining\machine_input_output_plates.dm" #include "code\modules\mining\machine_processing.dm" #include "code\modules\mining\machine_stacking.dm" @@ -1253,6 +1254,7 @@ #include "code\modules\surgery\ribcage.dm" #include "code\modules\surgery\robolimbs.dm" #include "code\modules\surgery\surgery.dm" +#include "code\modules\telesci\bscrystal.dm" #include "code\modules\telesci\gps.dm" #include "code\modules\telesci\telepad.dm" #include "code\modules\telesci\telesci_computer.dm" diff --git a/baystation12.int b/baystation12.int index ac308bf822..4cd21b6565 100644 --- a/baystation12.int +++ b/baystation12.int @@ -2,8 +2,8 @@ /* MAP_ICON_TYPE: 0 LAST_COMPILE_VERSION: 501.1217 -DIR: code code\_onclick code\datums code\datums\visibility_networks code\defines\obj code\game code\game\gamemodes code\game\gamemodes\blob code\game\gamemodes\blob\blobs code\game\gamemodes\cult code\game\gamemodes\events code\game\gamemodes\malfunction code\modules code\modules\mob code\modules\mob\dead code\modules\mob\dead\observer code\modules\mob\spirit code\modules\mob\spirit\mask icons icons\mob icons\mob\spirits -LAST_COMPILE_TIME: 1385167549 +DIR: code code\_onclick code\datums code\datums\visibility_networks code\defines\obj code\game code\game\gamemodes code\game\gamemodes\blob code\game\gamemodes\blob\blobs code\game\gamemodes\cult code\game\gamemodes\events code\game\gamemodes\malfunction code\modules code\modules\mining code\modules\telesci +LAST_COMPILE_TIME: 1385167744 AUTO_FILE_DIR: OFF */ // END_INTERNALS diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 0b535a44c3..8da220bf67 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -327,3 +327,41 @@ proc/isInSight(var/atom/A, var/atom/B) spawn(delay) for(var/client/C in group) C.screen -= O + +datum/projectile_data + var/src_x + var/src_y + var/time + var/distance + var/power_x + var/power_y + var/dest_x + var/dest_y + +/datum/projectile_data/New(var/src_x, var/src_y, var/time, var/distance, \ + var/power_x, var/power_y, var/dest_x, var/dest_y) + src.src_x = src_x + src.src_y = src_y + src.time = time + src.distance = distance + src.power_x = power_x + src.power_y = power_y + src.dest_x = dest_x + src.dest_y = dest_y + +/proc/projectile_trajectory(var/src_x, var/src_y, var/rotation, var/angle, var/power) + + // returns the destination (Vx,y) that a projectile shot at [src_x], [src_y], with an angle of [angle], + // rotated at [rotation] and with the power of [power] + // Thanks to VistaPOWA for this function + + var/power_x = power * cos(angle) + var/power_y = power * sin(angle) + var/time = 2* power_y / 10 //10 = g + + var/distance = time * power_x + + var/dest_x = src_x + distance*sin(rotation); + var/dest_y = src_y + distance*cos(rotation); + + return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y) diff --git a/code/controllers/autotransfer.dm b/code/controllers/autotransfer.dm new file mode 100644 index 0000000000..c69290c7bd --- /dev/null +++ b/code/controllers/autotransfer.dm @@ -0,0 +1,13 @@ +var/datum/controller/transfer_controller = new /transfer_controller() +var/timerbuffer = 0 //buffer for time check +/transfer_controller/New() + timerbuffer = config.vote_autotransfer_initial + processing_objects += src + +/transfer_controller/Del() + processing_objects -= src + +/transfer_controller/proc/process() + if (world.time >= timerbuffer - 600) + vote.autotransfer() + timerbuffer = timerbuffer + config.vote_autotransfer_interval \ No newline at end of file diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 42ac1cdc97..f2b5f01ce3 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -43,7 +43,8 @@ var/Tickcomp = 0 var/socket_talk = 0 // use socket_talk to communicate with other processes var/list/resource_urls = null - + var/antag_hud_allowed = 0 // Ghosts can turn on Antagovision to see a HUD of who is the bad guys this round. + var/antag_hud_restricted = 0 // Ghosts that turn on Antagovision cannot rejoin the round. var/list/mode_names = list() var/list/modes = list() // allowed modes var/list/votable_modes = list() // votable modes @@ -385,6 +386,11 @@ if("ticklag") Ticklag = text2num(value) + if("allow_antag_hud") + config.antag_hud_allowed = 1 + if("antag_hud_restricted") + config.antag_hud_restricted = 1 + if("socket_talk") socket_talk = text2num(value) diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm index 452c174b35..92f55a3fd6 100644 --- a/code/controllers/voting.dm +++ b/code/controllers/voting.dm @@ -50,7 +50,6 @@ datum/controller/vote initiate_vote("crew_transfer","the server") log_debug("The server has called an Autotransfer") - proc/reset() initiator = null time_remaining = 0 diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index a03068371f..ea9fbaec4a 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -36,8 +36,6 @@ var/global/datum/controller/gameticker/ticker var/triai = 0//Global holder for Triumvirate - var/initialtpass = 0 //holder for inital autotransfer vote timer - /datum/controller/gameticker/proc/pregame() login_music = pick(\ /*'sound/music/halloween/skeletons.ogg',\ @@ -63,17 +61,6 @@ var/global/datum/controller/gameticker/ticker current_state = GAME_STATE_SETTING_UP while (!setup()) -/datum/controller/gameticker/proc/votetimer() - var/timerbuffer = 0 - if (initialtpass == 0) - timerbuffer = config.vote_autotransfer_initial - else - timerbuffer = config.vote_autotransfer_interval - spawn(timerbuffer) - vote.autotransfer() - initialtpass = 1 - votetimer() - /datum/controller/gameticker/proc/setup() //Create and announce mode @@ -166,7 +153,6 @@ var/global/datum/controller/gameticker/ticker spawn(3000) statistic_cycle() // Polls population totals regularly and stores them in an SQL DB -- TLE - votetimer() return 1 /datum/controller/gameticker diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm index e98d128559..4dfff4fc4c 100644 --- a/code/game/gamemodes/heist/heist.dm +++ b/code/game/gamemodes/heist/heist.dm @@ -139,10 +139,8 @@ var/global/vox_kills = 0 //Used to check the Inviolate. /datum/game_mode/heist/proc/forge_vox_objectives() - - //Commented out for testing. - /* var/i = 1 - var/max_objectives = pick(2,2,2,3,3) + var/i = 1 + var/max_objectives = pick(2,2,2,2,3,3,3,4) var/list/objs = list() while(i<= max_objectives) var/list/goals = list("kidnap","loot","salvage") @@ -163,13 +161,7 @@ var/global/vox_kills = 0 //Used to check the Inviolate. //-All- vox raids have these two objectives. Failing them loses the game. objs += new /datum/objective/heist/inviolate_crew - objs += new /datum/objective/heist/inviolate_death */ - - raid_objectives += new /datum/objective/heist/kidnap - raid_objectives += new /datum/objective/heist/loot - raid_objectives += new /datum/objective/heist/salvage - raid_objectives += new /datum/objective/heist/inviolate_crew - raid_objectives += new /datum/objective/heist/inviolate_death + objs += new /datum/objective/heist/inviolate_death for(var/datum/objective/heist/O in raid_objectives) O.choose_target() @@ -181,6 +173,7 @@ var/global/vox_kills = 0 //Used to check the Inviolate. raider.current << "\blue The Vox are a race of cunning, sharp-eyed nomadic raiders and traders endemic to Tau Ceti and much of the unexplored galaxy. You and the crew have come to the Exodus for plunder, trade or both." raider.current << "\blue Vox are cowardly and will flee from larger groups, but corner one or find them en masse and they are vicious." raider.current << "\blue Use :V to voxtalk, :H to talk on your encrypted channel, and don't forget to turn on your nitrogen internals!" + raider.current << "\red IF YOU HAVE NOT PLAYED A VOX BEFORE, REVIEW THIS THREAD: http://baystation12.net/forums/viewtopic.php?f=6&t=8657." var/obj_count = 1 for(var/datum/objective/objective in raider.objectives) raider.current << "Objective #[obj_count]: [objective.explanation_text]" @@ -252,6 +245,28 @@ var/global/vox_kills = 0 //Used to check the Inviolate. feedback_add_details("traitor_objective","[objective.type]|FAIL") count++ + var/text = "The vox raiders were:" + + for(var/datum/mind/vox in raiders) + text += "
[vox.key] was [vox.name] (" + var/obj/stack = raiders[vox] + if(get_area(stack) != locate(/area/shuttle/vox/station)) + text += "left behind)" + continue + else if(vox.current) + if(vox.current.stat == DEAD) + text += "died" + else + text += "survived" + if(vox.current.real_name != vox.name) + text += " as [vox.current.real_name]" + else + text += "body destroyed" + text += ")" + + world << text + return 1 + ..() datum/game_mode/proc/auto_declare_completion_heist() diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 1b47d6f9a9..65284a054d 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -115,6 +115,7 @@ cell = C return cell = new(src) + cell.name = "high-capacity power cell" cell.charge = 15000 cell.maxcharge = 15000 diff --git a/code/game/objects/items/weapons/implants/implantfreedom.dm b/code/game/objects/items/weapons/implants/implantfreedom.dm index 0d31eb2e5c..58d73d835a 100644 --- a/code/game/objects/items/weapons/implants/implantfreedom.dm +++ b/code/game/objects/items/weapons/implants/implantfreedom.dm @@ -1,7 +1,7 @@ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 /obj/item/weapon/implant/freedom - name = "freedom" + name = "freedom implant" desc = "Use this to escape from those evil Red Shirts." item_color = "r" var/activation_emote = "chuckle" diff --git a/code/game/objects/items/weapons/mop.dm b/code/game/objects/items/weapons/mop.dm index 27935c4f87..a3e71cd8cd 100644 --- a/code/game/objects/items/weapons/mop.dm +++ b/code/game/objects/items/weapons/mop.dm @@ -21,6 +21,7 @@ obj/item/weapon/mop/proc/clean(turf/simulated/A) if(reagents.has_reagent("water", 1)) A.clean_blood() + A.dirt = 0 for(var/obj/effect/O in A) if(istype(O,/obj/effect/rune) || istype(O,/obj/effect/decal/cleanable) || istype(O,/obj/effect/overlay)) del(O) diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index 6432f1bac7..2598a63244 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -8,7 +8,7 @@ nitrogen = MOLES_N2STANDARD var/to_be_destroyed = 0 //Used for fire, if a melting temperature was reached, it will be destroyed var/max_fire_temperature_sustained = 0 //The max temperature of the fire which it was subjected to - + var/dirt = 0 /turf/simulated/New() ..() levelupdate() @@ -21,18 +21,13 @@ if (istype(A,/mob/living/carbon)) var/mob/living/carbon/M = A if(M.lying) return + dirt++ + if (dirt > 40) + dirt = 0 + if (!locate(/obj/effect/decal/cleanable/dirt, src)) + new/obj/effect/decal/cleanable/dirt(src) if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/H = M - if(istype(H.shoes, /obj/item/clothing/shoes/clown_shoes)) - var/obj/item/clothing/shoes/clown_shoes/O = H.shoes - if(H.m_intent == "run") - if(O.footstep >= 2) - O.footstep = 0 - playsound(src, "clownstep", 50, 1) // this will get annoying very fast. - else - O.footstep++ - else - playsound(src, "clownstep", 20, 1) var/list/bloodDNA = null if(H.shoes) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 606a6e82ff..1158633bf8 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -70,6 +70,8 @@ var/list/admin_verbs_admin = list( /client/proc/man_up, /client/proc/global_man_up, /client/proc/response_team, // Response Teams admin verb + /client/proc/toggle_antagHUD_use, + /client/proc/toggle_antagHUD_restrictions, /client/proc/allow_character_respawn /* Allows a ghost to respawn */ ) var/list/admin_verbs_ban = list( diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 0b6ab51ce3..fa7438e749 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -515,7 +515,7 @@ //Non-Human (Green) counter = 0 jobs += "" - jobs += "" + jobs += "" for(var/jobPos in nonhuman_positions) if(!jobPos) continue var/datum/job/job = job_master.GetJob(jobPos) @@ -533,11 +533,15 @@ counter = 0 //pAI isn't technically a job, but it goes in here. + if(jobban_isbanned(M, "pAI")) jobs += "" else jobs += "" - + if(jobban_isbanned(M, "AntagHUD")) + jobs += "" + else + jobs += "" jobs += "
Non-human Positions
Non-human Positions
pAIpAIAntagHUDAntagHUD
" //Antagonist (Orange) @@ -2603,4 +2607,4 @@ show_player_info(ckey) if("list") PlayerNotesPage(text2num(href_list["index"])) - return \ No newline at end of file + return diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 3447d70e67..1f5b3181bf 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -226,42 +226,120 @@ Allow admins to set players to be able to respawn/bypass 30 min wait, without th Ccomp's first proc. */ -/client/proc/allow_character_respawn() - set category = "Special Verbs" - set name = "Allow player to respawn" - set desc = "Let's the player bypass the 30 minute wait to respawn." - if(!holder) - src << "Only administrators may use this command." - var/any = 0 +/client/proc/get_ghosts(var/notify = 0,var/what = 2) + // what = 1, return ghosts ass list. + // what = 2, return mob list + var/list/mobs = list() var/list/ghosts = list() - var/list/sortmob = sortAtom(mob_list) // get the mob list. - for(var/mob/dead/observer/M in sortmob) - mobs.Add(M) //filter it where it's only ghosts - any = 1 //if no ghosts show up, any will just be 0 + var/list/sortmob = sortAtom(mob_list) // get the mob list. + /var/any=0 + for(var/mob/dead/observer/M in sortmob) + mobs.Add(M) //filter it where it's only ghosts + any = 1 //if no ghosts show up, any will just be 0 if(!any) - src << "There doesn't appear to be any ghosts for you to select." + if(notify) + src << "There doesn't appear to be any ghosts for you to select." return for(var/mob/M in mobs) var/name = M.name - ghosts[name] = M //get the name of the mob for the popup list + ghosts[name] = M //get the name of the mob for the popup list + if(what==1) + return ghosts + else + return mobs + + +/client/proc/allow_character_respawn() + set category = "Special Verbs" + set name = "Allow player to respawn" + set desc = "Let's the player bypass the 30 minute wait to respawn or allow them to re-enter their corpse." + if(!holder) + src << "Only administrators may use this command." + var/list/ghosts= get_ghosts(1,1) var/target = input("Please, select a ghost!", "COME BACK TO LIFE!", null, null) as null|anything in ghosts if(!target) src << "Hrm, appears you didn't select a ghost" // Sanity check, if no ghosts in the list we don't want to edit a null variable and cause a runtime error. return - var/mob/M = ghosts[target] - M.timeofdeath=-19999 /* time of death is checked in /mob/verb/abandon_mob() which is the Respawn verb. + var/mob/dead/observer/G = ghosts[target] + if(G.has_enabled_antagHUD && config.antag_hud_restricted) + var/response = alert(src, "Are you sure you wish to allow this individual to play?","Ghost has used AntagHUD","Yes","No") + if(response == "No") return + G.timeofdeath=-19999 /* time of death is checked in /mob/verb/abandon_mob() which is the Respawn verb. timeofdeath is used for bodies on autopsy but since we're messing with a ghost I'm pretty sure there won't be an autopsy. */ - M:show_message(text("\blue You may now respawn. You should roleplay as if you learned nothing about the round during your time with the dead."), 1) - log_admin("[key_name(usr)] allowed [key_name(M)] to bypass the 30 minute respawn limit") - message_admins("Admin [key_name_admin(usr)] allowed [key_name_admin(M)] to bypass the 30 minute respawn limit", 1) + G.has_enabled_antagHUD = 2 + G.can_reenter_corpse = 1 + + G:show_message(text("\blue You may now respawn. You should roleplay as if you learned nothing about the round during your time with the dead."), 1) + log_admin("[key_name(usr)] allowed [key_name(G)] to bypass the 30 minute respawn limit") + message_admins("Admin [key_name_admin(usr)] allowed [key_name_admin(G)] to bypass the 30 minute respawn limit", 1) +/client/proc/toggle_antagHUD_use() + set category = "Server" + set name = "Toggle antagHUD usage" + set desc = "Toggles antagHUD usage for observers" + + if(!holder) + src << "Only administrators may use this command." + var/action="" + if(config.antag_hud_allowed) + for(var/mob/dead/observer/g in get_ghosts()) + if(!g.client.holder) //Remove the verb from non-admin ghosts + g.verbs -= /mob/dead/observer/verb/toggle_antagHUD + if(g.antagHUD) + g.antagHUD = 0 // Disable it on those that have it enabled + g.has_enabled_antagHUD = 2 // We'll allow them to respawn + g << "\red The Administrator has disabled AntagHUD " + config.antag_hud_allowed = 0 + src << "\red AntagHUD usage has been disabled" + action = "disabled" + else + for(var/mob/dead/observer/g in get_ghosts()) + if(!g.client.holder) // Add the verb back for all non-admin ghosts + g.verbs += /mob/dead/observer/verb/toggle_antagHUD + g << "\blue The Administrator has enabled AntagHUD " // Notify all observers they can now use AntagHUD + config.antag_hud_allowed = 1 + action = "enabled" + src << "\blue AntagHUD usage has been enabled" + + + log_admin("[key_name(usr)] has [action] antagHUD usage for observers") + message_admins("Admin [key_name_admin(usr)] has [action] antagHUD usage for observers", 1) + + + +/client/proc/toggle_antagHUD_restrictions() + set category = "Server" + set name = "Toggle antagHUD Restrictions" + set desc = "Restricts players that have used antagHUD from being able to join this round." + if(!holder) + src << "Only administrators may use this command." + var/action="" + if(config.antag_hud_restricted) + for(var/mob/dead/observer/g in get_ghosts()) + g << "\blue The administrator has lifted restrictions on joining the round if you use AntagHUD" + action = "lifted restrictions" + config.antag_hud_restricted = 0 + src << "\blue AntagHUD restrictions have been lifted" + else + for(var/mob/dead/observer/g in get_ghosts()) + g << "\red The administrator has placed restrictions on joining the round if you use AntagHUD" + g << "\red Your AntagHUD has been disabled, you may choose to re-enabled it but will be under restrictions " + g.antagHUD = 0 + g.has_enabled_antagHUD = 0 + action = "placed restrictions" + config.antag_hud_restricted = 1 + src << "\red AntagHUD restrictions have been enabled" + + log_admin("[key_name(usr)] has [action] on joining the round if they use AntagHUD") + message_admins("Admin [key_name_admin(usr)] has [action] on joining the round if they use AntagHUD", 1) + diff --git a/code/modules/clothing/spacesuits/rig.dm b/code/modules/clothing/spacesuits/rig.dm index a898df5bcc..2e9c5185a6 100644 --- a/code/modules/clothing/spacesuits/rig.dm +++ b/code/modules/clothing/spacesuits/rig.dm @@ -13,7 +13,6 @@ heat_protection = HEAD max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECITON_TEMPERATURE species_restricted = list("exclude","Unathi","Tajaran","Skrell","Diona","Vox") - attack_self(mob/user) if(!isturf(user.loc)) user << "You cannot turn the light on while in this [user.loc]" //To prevent some lighting anomalities. @@ -90,7 +89,7 @@ armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 35, bio = 100, rad = 60) siemens_coefficient = 0.6 var/obj/machinery/camera/camera - + species_restricted = list("exclude","Vox") /obj/item/clothing/head/helmet/space/rig/syndi/attack_self(mob/user) if(camera) ..(user) @@ -116,6 +115,7 @@ armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 60) allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs) siemens_coefficient = 0.6 + species_restricted = list("exclude","Vox") //Wizard Rig diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 98331e8fcc..05bb2a30dd 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -921,3 +921,31 @@ if(istype(A, /obj/item/ammo_magazine)) flick("leamas-reloading",src) ..() + + +///// Custom Items coded by Iamgoofball are Below ///// +/obj/item/weapon/storage/belt/medical/fluff/nashi_belt + name = "rainbow medical belt" + desc = "A somewhat-worn, modified, rainbow belt." + icon = 'icons/obj/custom_items.dmi' + icon_state = "nashi_belt" + item_state = "fluff_rbelt" + + New() + ..() + new /obj/item/weapon/reagent_containers/glass/bottle/fluff/nashi_bottle(src, 14, "Bicaridine") + new /obj/item/weapon/reagent_containers/glass/bottle/fluff/nashi_bottle(src, 15, "Dermaline") + new /obj/item/weapon/reagent_containers/glass/bottle/fluff/nashi_bottle(src, 16, "Dylovene") + new /obj/item/weapon/reagent_containers/glass/bottle/fluff/nashi_bottle(src, 17, "Dexalin Plus") + new /obj/item/weapon/reagent_containers/glass/bottle/fluff/nashi_bottle(src, 18, "Tricordrazine") + new /obj/item/weapon/reagent_containers/syringe/(src) + new /obj/item/device/healthanalyzer(src) + +/obj/item/weapon/reagent_containers/glass/bottle/fluff/nashi_bottle + icon = 'icons/obj/chemical.dmi' + flags = FPRINT | TABLEPASS //Starting them with lids on them. Safety first! + New(loc, var/color, var/labeled) + ..() + name = "[labeled] bottle" + desc = "A small bottle. Contains [labeled]" + icon_state = "bottle[color]" diff --git a/code/modules/customitems/item_spawning.dm b/code/modules/customitems/item_spawning.dm index ffcc19b7b7..8682f6f69e 100644 --- a/code/modules/customitems/item_spawning.dm +++ b/code/modules/customitems/item_spawning.dm @@ -57,6 +57,23 @@ del(C) ok = M.equip_if_possible(I, slot_wear_id, 0) //if 1, last argument deletes on fail break + else if(istype(Item,/obj/item/weapon/storage/belt)) + if(M.ckey == "jakksergal" && M.real_name == "Nashi Ra'hal" && M.mind.role_alt_title && M.mind.role_alt_title != "Nurse" && M.mind.role_alt_title != "Chemist") + ok = 1 + del(Item) + goto skip + var/obj/item/weapon/storage/belt/medical/fluff/nashi_belt/I = Item + if(istype(M.belt,/obj/item/weapon/storage/belt)) + for(var/obj/item/weapon/storage/belt/B in M) + del(B) + M.belt=null + ok = M.equip_if_possible(I, slot_belt, 0) + break + if(istype(M.belt,/obj/item/device/pda)) + for(var/obj/item/device/pda/Pda in M) + M.belt=null + M.equip_if_possible(Pda, slot_l_store, 0) + ok = M.equip_if_possible(I, slot_belt, 0) else if(istype(M.back,/obj/item/weapon/storage) && M.back:contents.len < M.back:storage_slots) // Try to place it in something on the mob's back Item.loc = M.back ok = 1 @@ -70,4 +87,4 @@ skip: if (ok == 0) // Finally, since everything else failed, place it on the ground - Item.loc = get_turf(M.loc) \ No newline at end of file + Item.loc = get_turf(M.loc) diff --git a/code/modules/economy/ATM.dm b/code/modules/economy/ATM.dm index 32dc6cbc9d..398d311c18 100644 --- a/code/modules/economy/ATM.dm +++ b/code/modules/economy/ATM.dm @@ -97,8 +97,6 @@ log transactions user << "\red Artificial unit recognized. Artificial units do not currently receive monetary compensation, as per NanoTrasen regulation #1005." return if(get_dist(src,user) <= 1) - //check to see if the user has low security enabled - scan_user(user) //js replicated from obj/machinery/computer/card var/dat = "

NanoTrasen Automatic Teller Machine

" @@ -223,7 +221,11 @@ log transactions var/new_sec_level = max( min(text2num(href_list["new_security_level"]), 2), 0) authenticated_account.security_level = new_sec_level if("attempt_auth") - if(!ticks_left_locked_down) + + // check if they have low security enabled + scan_user(usr) + + if(!ticks_left_locked_down && held_card) var/tried_account_num = text2num(href_list["account_num"]) if(!tried_account_num) tried_account_num = held_card.associated_account_number @@ -363,3 +365,5 @@ log transactions T.date = current_date_string T.time = worldtime2text() authenticated_account.transaction_log.Add(T) + + view_screen = NO_SCREEN \ No newline at end of file diff --git a/code/modules/events/event_dynamic.dm b/code/modules/events/event_dynamic.dm index 93142e0261..8a5b3b61b2 100644 --- a/code/modules/events/event_dynamic.dm +++ b/code/modules/events/event_dynamic.dm @@ -44,39 +44,39 @@ var/list/event_last_fired = list() //see: // Code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events.dm // Code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events_Mundane.dm - possibleEvents[/datum/event/economic_event] = 200 - possibleEvents[/datum/event/trivial_news] = 300 - possibleEvents[/datum/event/mundane_news] = 200 + possibleEvents[/datum/event/economic_event] = 300 + possibleEvents[/datum/event/trivial_news] = 400 + possibleEvents[/datum/event/mundane_news] = 300 possibleEvents[/datum/event/pda_spam] = max(min(25, player_list.len) * 4, 200) possibleEvents[/datum/event/money_lotto] = max(min(5, player_list.len), 50) if(account_hack_attempted) possibleEvents[/datum/event/money_hacker] = max(min(25, player_list.len) * 4, 200) - possibleEvents[/datum/event/carp_migration] = 50 + 50 * active_with_role["Engineer"] - possibleEvents[/datum/event/brand_intelligence] = 50 + 25 * active_with_role["Janitor"] + possibleEvents[/datum/event/carp_migration] = 20 + 10 * active_with_role["Engineer"] + possibleEvents[/datum/event/brand_intelligence] = 20 + 25 * active_with_role["Janitor"] - possibleEvents[/datum/event/rogue_drone] = 25 + 25 * active_with_role["Engineer"] + 25 * active_with_role["Security"] - possibleEvents[/datum/event/infestation] = 50 + 25 * active_with_role["Janitor"] + possibleEvents[/datum/event/rogue_drone] = 5 + 25 * active_with_role["Engineer"] + 25 * active_with_role["Security"] + possibleEvents[/datum/event/infestation] = 100 + 100 * active_with_role["Janitor"] possibleEvents[/datum/event/communications_blackout] = 50 + 25 * active_with_role["AI"] + active_with_role["Scientist"] * 25 possibleEvents[/datum/event/ionstorm] = active_with_role["AI"] * 25 + active_with_role["Cyborg"] * 25 + active_with_role["Engineer"] * 10 + active_with_role["Scientist"] * 5 - possibleEvents[/datum/event/grid_check] = 25 + 20 * active_with_role["Engineer"] - possibleEvents[/datum/event/electrical_storm] = 10 * active_with_role["Janitor"] + 5 * active_with_role["Engineer"] + possibleEvents[/datum/event/grid_check] = 25 + 10 * active_with_role["Engineer"] + possibleEvents[/datum/event/electrical_storm] = 15 * active_with_role["Janitor"] + 5 * active_with_role["Engineer"] possibleEvents[/datum/event/wallrot] = 30 * active_with_role["Engineer"] + 50 * active_with_role["Botanist"] if(!spacevines_spawned) - possibleEvents[/datum/event/spacevine] = 5 + 5 * active_with_role["Engineer"] + possibleEvents[/datum/event/spacevine] = 10 + 5 * active_with_role["Engineer"] if(minutes_passed >= 30) // Give engineers time to set up engine possibleEvents[/datum/event/meteor_wave] = 10 * active_with_role["Engineer"] - possibleEvents[/datum/event/meteor_shower] = 40 * active_with_role["Engineer"] + possibleEvents[/datum/event/meteor_shower] = 20 * active_with_role["Engineer"] possibleEvents[/datum/event/blob] = 20 * active_with_role["Engineer"] - possibleEvents[/datum/event/viral_infection] = 25 + active_with_role["Medical"] * 100 + possibleEvents[/datum/event/viral_infection] = 25 + active_with_role["Medical"] * 15 if(active_with_role["Medical"] > 0) - possibleEvents[/datum/event/radiation_storm] = active_with_role["Medical"] * 50 - possibleEvents[/datum/event/spontaneous_appendicitis] = active_with_role["Medical"] * 150 - possibleEvents[/datum/event/viral_infection] = active_with_role["Medical"] * 10 + possibleEvents[/datum/event/radiation_storm] = active_with_role["Medical"] * 10 + possibleEvents[/datum/event/spontaneous_appendicitis] = active_with_role["Medical"] * 10 + possibleEvents[/datum/event/viral_infection] = active_with_role["Medical"] * 20 possibleEvents[/datum/event/organ_failure] = active_with_role["Medical"] * 50 possibleEvents[/datum/event/prison_break] = active_with_role["Security"] * 50 diff --git a/code/modules/events/event_manager.dm b/code/modules/events/event_manager.dm index 89347a299d..52fbc8220a 100644 --- a/code/modules/events/event_manager.dm +++ b/code/modules/events/event_manager.dm @@ -2,8 +2,8 @@ var/list/allEvents = typesof(/datum/event) - /datum/event var/list/potentialRandomEvents = typesof(/datum/event) - /datum/event //var/list/potentialRandomEvents = typesof(/datum/event) - /datum/event - /datum/event/spider_infestation - /datum/event/alien_infestation -var/eventTimeLower = 9000 //15 minutes -var/eventTimeUpper = 15000 //25 minutes +var/eventTimeLower = 12000 //20 minutes +var/eventTimeUpper = 24000 //40 minutes var/scheduledEvent = null diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm new file mode 100644 index 0000000000..d55c7e329a --- /dev/null +++ b/code/modules/mining/abandonedcrates.dm @@ -0,0 +1,134 @@ +/obj/structure/closet/crate/secure/loot + name = "abandoned crate" + desc = "What could be inside?" + icon_state = "securecrate" + icon_opened = "securecrateopen" + icon_closed = "securecrate" + var/code = null + var/lastattempt = null + var/attempts = 3 + locked = 1 + var/min = 1 + var/max = 10 + +/obj/structure/closet/crate/secure/loot/New() + ..() + code = rand(min,max) + var/loot = rand(1,30) + switch(loot) + if(1) + new/obj/item/weapon/reagent_containers/food/drinks/bottle/rum(src) + new/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus(src) + new/obj/item/weapon/reagent_containers/food/drinks/bottle/whiskey(src) + new/obj/item/weapon/lighter/zippo(src) + if(2) + new/obj/item/weapon/pickaxe/drill(src) + new/obj/item/device/taperecorder(src) + new/obj/item/clothing/suit/space/rig(src) + new/obj/item/clothing/head/helmet/space/rig(src) + if(3) + for(var/i = 0, i < 12, i++) + new/obj/item/weapon/coin/diamond(src) + if(4) + new/obj/item/weapon/bananapeel(src) + if(5) + for(var/i = 0, i < 6, i++) + new/obj/item/weapon/reagent_containers/food/snacks/sliceable/birthdaycake(src) + new/obj/item/weapon/lighter/zippo(src) + if(7) + new/obj/item/weapon/reagent_containers/glass/beaker/bluespace(src) + if(9 to 10) + for(var/i = 0, i < 10, i++) + new/obj/item/weapon/ore/diamond(src) + if(11) + return + if(12) + new/obj/item/seeds/deathberryseed(src) + new/obj/item/seeds/deathnettleseed(src) + if(13) + new/obj/machinery/hydroponics(src) + if(14) + new/obj/item/seeds/cashseed(src) + if(15) + for(var/i = 0, i < 3, i++) + new/obj/item/weapon/reagent_containers/glass/beaker/noreact(src) + if(16 to 17) + for(var/i = 0, i < 9, i++) + new/obj/item/bluespace_crystal(src) + if(19) + for(var/i = 0, i < 4, i++) + new/obj/item/weapon/melee/classic_baton(src) + if(20) + new/obj/item/weapon/storage/lockbox/clusterbang(src) + if(21) + new/obj/item/weapon/aiModule/robocop(src) + if(22) + new/obj/item/clothing/under/chameleon(src) + for(var/i = 0, i < 7, i++) + new/obj/item/clothing/tie/horrible(src) + if(23) + new/obj/item/clothing/under/shorts(src) + new/obj/item/clothing/under/shorts/red(src) + new/obj/item/clothing/under/shorts/blue(src) + //Dummy crates start here. + if(24 to 29) + return + if(8) + return + if(6) + return + if(18) + return + //Dummy crates end here. + if(30) + for(var/i = 0, i < 4, i++) + new/obj/item/weapon/melee/baton(src) + +/obj/structure/closet/crate/secure/loot/attack_hand(mob/user as mob) + if(locked) + user << "The crate is locked with a Deca-code lock." + var/input = input(usr, "Enter digit from [min] to [max].", "Deca-Code Lock", "") as num + if(in_range(src, user)) + input = Clamp(input, 0, 10) + if (input == code) + user << "The crate unlocks!" + locked = 0 + else if (input == null || input > max || input < min) + user << "You leave the crate alone." + else + user << "A red light flashes." + lastattempt = input + attempts-- + if (attempts == 0) + user << "The crate's anti-tamper system activates!" + var/turf/T = get_turf(src.loc) + explosion(T, 0, 1, 2, 1) + del(src) + return + else + user << "You attempt to interact with the device using a hand gesture, but it appears this crate is from before the DECANECT came out." + return + else + return ..() + +/obj/structure/closet/crate/secure/loot/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(locked) + if (istype(W, /obj/item/weapon/card/emag)) + user << "The crate unlocks!" + locked = 0 + if (istype(W, /obj/item/device/multitool)) + user << "DECA-CODE LOCK REPORT:" + if (attempts == 1) + user << "* Anti-Tamper Bomb will activate on next failed access attempt." + else + user << "* Anti-Tamper Bomb will activate after [src.attempts] failed access attempts." + if (lastattempt == null) + user << " has been made to open the crate thus far." + return + // hot and cold + if (code > lastattempt) + user << "* Last access attempt lower than expected code." + else + user << "* Last access attempt higher than expected code." + else ..() + else ..() diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index 83077154a8..c410a51c00 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -486,7 +486,11 @@ commented out in r5061, I left it because of the shroom thingies var/turf/simulated/floor/plating/airless/asteroid/N = ChangeTurf(/turf/simulated/floor/plating/airless/asteroid) N.fullUpdateMineralOverlays() - + var/crate = rand(1,30) + switch(crate) + if(1) + visible_message("After digging, you find an old dusty crate buried within!") + new/obj/structure/closet/crate/secure/loot(src) return /turf/simulated/mineral/proc/excavate_find(var/prob_clean = 0, var/datum/find/F) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index ae544c43d5..aad87026b2 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -16,6 +16,8 @@ var/started_as_observer //This variable is set to 1 when you enter the game as an observer. //If you died in the game and are a ghsot - this will remain as null. //Note that this is not a reliable way to determine if admins started as observers, since they change mobs a lot. + var/has_enabled_antagHUD = 0 + var/antagHUD = 0 universal_speak = 1 var/atom/movable/following = null /mob/dead/observer/New(mob/body) @@ -23,6 +25,7 @@ see_invisible = SEE_INVISIBLE_OBSERVER see_in_dark = 100 verbs += /mob/dead/observer/proc/dead_tele + stat = DEAD var/turf/T @@ -63,6 +66,23 @@ real_name = name ..() + +/mob/dead/attackby(obj/item/W, mob/user) + if(istype(W,/obj/item/weapon/tome)) + var/mob/dead/M = src + if(src.invisibility != 0) + M.invisibility = 0 + user.visible_message( \ + "\red [user] drags ghost, [M], to our plan of reality!", \ + "\red You drag [M] to our plan of reality!" \ + ) + else + user.visible_message ( \ + "\red [user] just tried to smash his book into that ghost! It's not very effective", \ + "\red You get the feeling that the ghost can't become any more visible." \ + ) + + /mob/dead/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) return 1 /* @@ -70,12 +90,68 @@ Transfer_mind is there to check if mob is being deleted/not going to have a body Works together with spawning an observer, noted above. */ +/mob/dead/observer/Life() + ..() + if(!loc) return + if(!client) return 0 + + + if(client.images.len) + for(var/image/hud in client.images) + if(copytext(hud.icon_state,1,4) == "hud") + client.images.Remove(hud) + if(antagHUD) + var/list/target_list = list() + for(var/mob/living/target in oview(src)) + if( target.mind&&(target.mind.special_role||issilicon(target)) ) + target_list += target + if(target_list.len) + assess_targets(target_list, src) + + + +/mob/dead/proc/assess_targets(list/target_list, mob/dead/observer/U) + var/icon/tempHud = 'icons/mob/hud.dmi' + for(var/mob/living/target in target_list) + if(iscarbon(target)) + switch(target.mind.special_role) + if("traitor","Syndicate") + U.client.images += image(tempHud,target,"hudsyndicate") + if("Revolutionary") + U.client.images += image(tempHud,target,"hudrevolutionary") + if("Head Revolutionary") + U.client.images += image(tempHud,target,"hudheadrevolutionary") + if("Cultist") + U.client.images += image(tempHud,target,"hudcultist") + if("Changeling") + U.client.images += image(tempHud,target,"hudchangeling") + if("Wizard","Fake Wizard") + U.client.images += image(tempHud,target,"hudwizard") + if("Hunter","Sentinel","Drone","Queen") + U.client.images += image(tempHud,target,"hudalien") + if("Death Commando") + U.client.images += image(tempHud,target,"huddeathsquad") + if("Ninja") + U.client.images += image(tempHud,target,"hudninja") + else//If we don't know what role they have but they have one. + U.client.images += image(tempHud,target,"hudunknown1") + else//If the silicon mob has no law datum, no inherent laws, or a law zero, add them to the hud. + var/mob/living/silicon/silicon_target = target + if(!silicon_target.laws||(silicon_target.laws&&(silicon_target.laws.zeroth||!silicon_target.laws.inherent.len))||silicon_target.mind.special_role=="traitor") + if(isrobot(silicon_target))//Different icons for robutts and AI. + U.client.images += image(tempHud,silicon_target,"hudmalborg") + else + U.client.images += image(tempHud,silicon_target,"hudmalai") + return 1 + /mob/proc/ghostize(var/can_reenter_corpse = 1) if(key) var/mob/dead/observer/ghost = new(src) //Transfer safety to observer spawning proc. ghost.can_reenter_corpse = can_reenter_corpse ghost.timeofdeath = src.timeofdeath //BS12 EDIT ghost.key = key + if(!ghost.client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed. + ghost.verbs -= /mob/dead/observer/verb/toggle_antagHUD // Poor guys, don't know what they are missing! return ghost /* @@ -153,7 +229,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(mind.current.key && copytext(mind.current.key,1,2)!="@") //makes sure we don't accidentally kick any clients usr << "Another consciousness is in your body...It is resisting you." return - if(mind.current.ajourn && mind.current.stat != DEAD) //check if the corpse is astral-journeying (it's client ghosted using a cultist rune). + if(mind.current.ajourn && mind.current.stat != DEAD) //check if the corpse is astral-journeying (it's client ghosted using a cultist rune). var/obj/effect/rune/R = locate() in mind.current.loc //whilst corpse is alive, we can only reenter the body if it's on the rune if(!(R && R.word1 == cultwords["hell"] && R.word2 == cultwords["travel"] && R.word3 == cultwords["self"])) //astral journeying rune usr << "The astral cord that ties your body and your spirit has been severed. You are likely to wander the realm beyond until your body is finally dead and thus reunited with you." @@ -162,6 +238,32 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp mind.current.key = key return 1 +/mob/dead/observer/verb/toggle_antagHUD() + set category = "Ghost" + set name = "Toggle AntagHUD" + set desc = "Toggles AntagHUD allowing you to see who is the antagonist" + if(!config.antag_hud_allowed && !client.holder) + src << "\red Admins have disabled this for this round." + return + if(!client) + return + var/mob/dead/observer/M = src + if(jobban_isbanned(M, "AntagHUD")) + src << "\red You have been banned from using this feature" + return + if(config.antag_hud_restricted && !M.has_enabled_antagHUD &&!client.holder) + var/response = alert(src, "If you turn this on, you will not be able to take any part in the round.","Are you sure you want to turn this feature on?","Yes","No") + if(response == "No") return + M.can_reenter_corpse = 0 + if(!M.has_enabled_antagHUD && !client.holder) + M.has_enabled_antagHUD = 1 + if(M.antagHUD) + M.antagHUD = 0 + src << "\blue AntagHUD Disabled" + else + M.antagHUD = 1 + src << "\blue AntagHUD Enabled" + /mob/dead/observer/proc/dead_tele() set category = "Ghost" set name = "Teleport" diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm index f8c014278c..fa02150ab3 100644 --- a/code/modules/mob/living/carbon/brain/posibrain.dm +++ b/code/modules/mob/living/carbon/brain/posibrain.dm @@ -27,6 +27,8 @@ proc/request_player() for(var/mob/dead/observer/O in player_list) + if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted) + continue if(jobban_isbanned(O, "pAI")) continue if(O.client) diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 6b597920ff..40db476eba 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -251,15 +251,4 @@ This function restores all organs. H.drop_item() W.loc = src - else if(istype(used_weapon,/obj/item/projectile)) //We don't want to use the actual projectile item, so we spawn some shrapnel. - - var/obj/item/projectile/P = used_weapon - if(prob(75) && P.embed) - var/obj/item/weapon/shard/shrapnel/S = new() - S.name = "[P.name] shrapnel" - S.desc = "[S.desc] It looks like it was fired from [P.shot_from]." - S.loc = src - organ.implants += S - visible_message("The projectile sticks in the wound!") - S.add_blood(src) return 1 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 2d06c5fee7..16a4733b27 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -88,6 +88,18 @@ emp_act return //END TASER NERF + var/datum/organ/external/organ = get_organ(check_zone(def_zone)) + + var/armor = checkarmor(organ, "bullet") + + if((P.embed && prob(20 + max(P.damage - armor, -10))) && P.damage_type == BRUTE) + var/obj/item/weapon/shard/shrapnel/SP = new() + (SP.name) = "[P.name] shrapnel" + (SP.desc) = "[SP.desc] It looks like it was fired from [P.shot_from]." + (SP.loc) = organ + organ.implants += SP + visible_message("The projectile sticks in the wound!") + SP.add_blood(src) return (..(P , def_zone)) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index d9354dccd6..957ed014d4 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -242,7 +242,7 @@ var/rads = radiation/25 radiation -= rads nutrition += rads - heal_overall_damage(rads,rads) + adjustBruteLoss(-(rads)) adjustOxyLoss(-(rads)) adjustToxLoss(-(rads)) updatehealth() @@ -887,8 +887,8 @@ if(nutrition > 500) nutrition = 500 - if(light_amount > 2) //if there's enough light, heal - heal_overall_damage(1,1) + if(light_amount > 5) //if there's enough light, heal + adjustBruteLoss(-1) adjustToxLoss(-1) adjustOxyLoss(-1) if(dna && dna.mutantrace == "shadow") diff --git a/code/modules/mob/living/carbon/monkey/diona.dm b/code/modules/mob/living/carbon/monkey/diona.dm index 1d80763fdc..442d33e2ac 100644 --- a/code/modules/mob/living/carbon/monkey/diona.dm +++ b/code/modules/mob/living/carbon/monkey/diona.dm @@ -68,7 +68,7 @@ src << "You are not yet ready for your growth..." return - if(reagents.get_reagent_amount("nutriment") < 5) + if(nutrition < 400) src << "You have not yet consumed enough to grow..." return diff --git a/code/modules/mob/living/silicon/pai/recruit.dm b/code/modules/mob/living/silicon/pai/recruit.dm index 93271aadaf..270e2ba763 100644 --- a/code/modules/mob/living/silicon/pai/recruit.dm +++ b/code/modules/mob/living/silicon/pai/recruit.dm @@ -191,6 +191,8 @@ var/datum/paiController/paiController // Global handler for pAI candidates proc/requestRecruits() for(var/mob/dead/observer/O in player_list) + if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted) + continue if(jobban_isbanned(O, "pAI")) continue if(asked.Find(O.key)) diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index 54431d86f7..0141d9c5c1 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -27,7 +27,6 @@ regenerate_icons() /mob/living/simple_animal/corgi/show_inv(mob/user as mob) - /* If you're turning this back on, scroll down and uncomment target_updated user.set_machine(src) if(user.stat) return @@ -43,7 +42,6 @@ user << browse(dat, text("window=mob[];size=325x500", name)) onclose(user, "mob[real_name]") - */ return /mob/living/simple_animal/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 0d4455b578..66f7d58bbc 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -351,6 +351,10 @@ var/list/slot_equipment_priority = list( \ return else var/deathtime = world.time - src.timeofdeath + var/mob/dead/observer/G = src + if(G.has_enabled_antagHUD == 1 && config.antag_hud_restricted) + usr << "\blue Upon using the antagHUD you forfeighted the ability to join the round." + return var/deathtimeminutes = round(deathtime / 600) var/pluralcheck = "minute" if(deathtimeminutes == 0) @@ -361,6 +365,7 @@ var/list/slot_equipment_priority = list( \ pluralcheck = " [deathtimeminutes] minutes and" var/deathtimeseconds = round((deathtime - deathtimeminutes * 600) / 10,1) usr << "You have been dead for[pluralcheck] [deathtimeseconds] seconds." + if (deathtime < 18000) usr << "You must wait 30 minutes to respawn!" return diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index e63ea883a6..380a6dfe9a 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -114,6 +114,7 @@ spawning = 1 src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS cant last forever yo + observer.started_as_observer = 1 close_spawn_windows() var/obj/O = locate("landmark*Observer-Start") @@ -129,8 +130,11 @@ client.prefs.real_name = random_name(client.prefs.gender) observer.real_name = client.prefs.real_name observer.name = observer.real_name + if(!client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed. + observer.verbs -= /mob/dead/observer/verb/toggle_antagHUD // Poor guys, don't know what they are missing! observer.key = key del(src) + return 1 if(href_list["late_join"]) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 97fa5b1dbd..d8ff676708 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -49,7 +49,6 @@ var/eyeblur = 0 var/drowsy = 0 var/agony = 0 - var/embed = 0 // whether or not the projectile can embed itself in the mob proc/on_hit(var/atom/target, var/blocked = 0) @@ -87,15 +86,14 @@ loc = A.loc return 0// nope.avi - //Lower accurancy/longer range tradeoff. Distance matters a lot here, so at - // close distance, actually RAISE the chance to hit. var/distance = get_dist(starting,loc) var/miss_modifier = -30 + if (istype(shot_from,/obj/item/weapon/gun)) //If you aim at someone beforehead, it'll hit more often. var/obj/item/weapon/gun/daddy = shot_from //Kinda balanced by fact you need like 2 seconds to aim if (daddy.target && original in daddy.target) //As opposed to no-delay pew pew miss_modifier += -30 - def_zone = get_zone_with_miss_chance(def_zone, M, -30 + 8*distance) + def_zone = get_zone_with_miss_chance(def_zone, M, miss_modifier + 15*distance) if(!def_zone) visible_message("\blue \The [src] misses [M] narrowly!") diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index bf29dc863f..e512da7d59 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -1681,7 +1681,7 @@ datum var/mob/living/carbon/human/H = M if(H.dna) if(H.species.flags & IS_PLANT) //plantmen take a LOT of damage - H.adjustToxLoss(10) + H.adjustToxLoss(50) toxin/stoxin name = "Sleep Toxin" @@ -2177,12 +2177,13 @@ datum on_mob_life(var/mob/living/M as mob) M.nutrition += nutriment_factor - if(istype(M, /mob/living/carbon/human) && M.job in list("Security Officer", "Head of Security", "Detective", "Warden")) + /*if(istype(M, /mob/living/carbon/human) && M.job in list("Security Officer", "Head of Security", "Detective", "Warden")) if(!M) M = holder.my_atom M.heal_organ_damage(1,1) M.nutrition += nutriment_factor ..() return + */ ..() /* //removed because of meta bullshit. this is why we can't have nice things. diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index e861826e0f..b9d25c2677 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -1341,6 +1341,43 @@ datum/design/nanopaste materials = list("$metal" = 7000, "$glass" = 7000) build_path = "/obj/item/stack/nanopaste" +datum/design/implant_loyal + name = "loyalty implant" + desc = "Makes you loyal or such." + id = "implant_loyal" + req_tech = list("materials" = 2, "biotech" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 7000, "$glass" = 7000) + build_path = "/obj/item/weapon/implant/loyalty" + +datum/design/implant_chem + name = "chemical implant" + desc = "Injects things." + id = "implant_chem" + req_tech = list("materials" = 2, "biotech" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/implant/chem" + +datum/design/implant_free + name = "freedom implant" + desc = "Use this to escape from those evil Red Shirts." + id = "implant_free" + req_tech = list("syndicate" = 2, "biotech" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/implant/freedom" + +datum/design/chameleon + name = "Chameleon Jumpsuit" + desc = "It's a plain jumpsuit. It seems to have a small dial on the wrist." + id = "chameleon" + req_tech = list("syndicate" = 2) + build_type = PROTOLATHE + materials = list("$metal" = 500) + build_path = "/obj/item/clothing/under/chameleon" + + datum/design/bluespacebeaker name = "bluespace beaker" desc = "A bluespace beaker, powered by experimental bluespace technology and Element Cuban combined with the Compound Pete. Can hold up to 300 units." @@ -1350,7 +1387,6 @@ datum/design/bluespacebeaker materials = list("$metal" = 3000, "$plasma" = 3000, "$diamond" = 500) reliability_base = 76 build_path = "/obj/item/weapon/reagent_containers/glass/beaker/bluespace" - category = "Misc" datum/design/noreactbeaker name = "cryostasis beaker" @@ -1406,17 +1442,17 @@ datum/design/decloner materials = list("$gold" = 5000,"$uranium" = 10000, "mutagen" = 40) build_path = "/obj/item/weapon/gun/energy/decloner" locked = 1 -/* + datum/design/chemsprayer name = "Chem Sprayer" desc = "An advanced chem spraying device." id = "chemsprayer" - req_tech = list("combat" = 3, "materials" = 3, "engineering" = 3, "biotech" = 2) + req_tech = list("materials" = 3, "engineering" = 3, "biotech" = 2) build_type = PROTOLATHE materials = list("$metal" = 5000, "$glass" = 1000) reliability_base = 100 build_path = "/obj/item/weapon/chemsprayer" -*/ + datum/design/rapidsyringe name = "Rapid Syringe Gun" desc = "A gun that fires many syringes." @@ -1575,6 +1611,16 @@ datum/design/bag_holding reliability_base = 80 build_path = "/obj/item/weapon/storage/backpack/holding" +datum/design/bluespace_crystal + name = "Artificial Bluespace Crystal" + desc = "A small blue crystal with mystical properties." + id = "bluespace_crystal" + req_tech = list("bluespace" = 5, "materials" = 7) + build_type = PROTOLATHE + materials = list("$gold" = 1500, "$diamond" = 3000, "$plasma" = 1500) + reliability_base = 100 + build_path = "/obj/item/bluespace_crystal/artificial" + ///////////////////////////////////////// /////////////////HUDs//////////////////// ///////////////////////////////////////// @@ -1642,3 +1688,167 @@ datum/design/borg_syndicate_module req_tech = list("combat" = 4, "syndicate" = 3) build_path = "/obj/item/borg/upgrade/syndicate" category = "Cyborg Upgrade Modules" + +///////////////////////////////////////// +/////////////PDA and Radio stuff///////// +///////////////////////////////////////// +datum/design/binaryencrypt + name = "Binary Encrpytion Key" + desc = "An encyption key for a radio headset. Contains cypherkeys." + id = "binaryencrypt" + req_tech = list("syndicate" = 2) + build_type = PROTOLATHE + materials = list("$metal" = 300, "$glass" = 300) + build_path = "/obj/item/device/encryptionkey/binary" +datum/design/pda + name = "PDA" + desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge." + id = "pda" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/device/pda" +datum/design/cart_basic + name = "Generic Cartridge" + desc = "A data cartridge for portable microcomputers." + id = "cart_basic" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/cartridge" +datum/design/cart_engineering + name = "Power-ON Cartridge" + desc = "A data cartridge for portable microcomputers." + id = "cart_engineering" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/cartridge/engineering" +datum/design/cart_atmos + name = "BreatheDeep Cartridge" + desc = "A data cartridge for portable microcomputers." + id = "cart_atmos" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/cartridge/atmos" +datum/design/cart_medical + name = "Med-U Cartridge" + desc = "A data cartridge for portable microcomputers." + id = "cart_medical" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/cartridge/medical" +datum/design/cart_chemistry + name = "ChemWhiz Cartridge" + desc = "A data cartridge for portable microcomputers." + id = "cart_chemistry" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/cartridge/chemistry" +datum/design/cart_security + name = "R.O.B.U.S.T. Cartridge" + desc = "A data cartridge for portable microcomputers." + id = "cart_security" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/cartridge/security" + locked = 1 +datum/design/cart_janitor + name = "CustodiPRO Cartridge" + desc = "A data cartridge for portable microcomputers." + id = "cart_janitor" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/cartridge/janitor" +datum/design/cart_clown + name = "Honkworks 5.0 Cartridge" + desc = "A data cartridge for portable microcomputers." + id = "cart_clown" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/cartridge/clown" +datum/design/cart_mime + name = "Gestur-O 1000 Cartridge" + desc = "A data cartridge for portable microcomputers." + id = "cart_mime" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/cartridge/mime" +datum/design/cart_toxins + name = "Signal Ace 2 Cartridge" + desc = "A data cartridge for portable microcomputers." + id = "cart_toxins" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/cartridge/toxins" +datum/design/cart_quartermaster + name = "Space Parts & Space Vendors Cartridge" + desc = "A data cartridge for portable microcomputers." + id = "cart_quartermaster" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/cartridge/quartermaster" + locked = 1 +datum/design/cart_hop + name = "Human Resources 9001 Cartridge" + desc = "A data cartridge for portable microcomputers." + id = "cart_hop" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/cartridge/hop" + locked = 1 +datum/design/cart_hos + name = "R.O.B.U.S.T. DELUXE Cartridge" + desc = "A data cartridge for portable microcomputers." + id = "cart_hos" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/cartridge/hos" + locked = 1 +datum/design/cart_ce + name = "Power-On DELUXE Cartridge" + desc = "A data cartridge for portable microcomputers." + id = "cart_ce" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/cartridge/ce" + locked = 1 +datum/design/cart_cmo + name = "Med-U DELUXE Cartridge" + desc = "A data cartridge for portable microcomputers." + id = "cart_cmo" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/cartridge/cmo" + locked = 1 +datum/design/cart_rd + name = "Signal Ace DELUXE Cartridge" + desc = "A data cartridge for portable microcomputers." + id = "cart_rd" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/cartridge/rd" + locked = 1 +datum/design/cart_captain + name = "Value-PAK Cartridge" + desc = "A data cartridge for portable microcomputers." + id = "cart_captain" + req_tech = list("engineering" = 2, "powerstorage" = 3) + build_type = PROTOLATHE + materials = list("$metal" = 50, "$glass" = 50) + build_path = "/obj/item/weapon/cartridge/captain" + locked = 1 diff --git a/code/modules/telesci/bscrystal.dm b/code/modules/telesci/bscrystal.dm new file mode 100644 index 0000000000..d9e968f4da --- /dev/null +++ b/code/modules/telesci/bscrystal.dm @@ -0,0 +1,38 @@ +// Bluespace crystals, used in telescience and when crushed it will blink you to a random turf. + +/obj/item/bluespace_crystal + name = "bluespace crystal" + desc = "A glowing bluespace crystal, not much is known about how they work. It looks very delicate." + icon = 'icons/obj/telescience.dmi' + icon_state = "bluespace_crystal" + w_class = 1 + origin_tech = "bluespace=4;materials=3" + var/blink_range = 8 // The teleport range when crushed/thrown at someone. + +/obj/item/bluespace_crystal/New() + ..() + pixel_x = rand(-5, 5) + pixel_y = rand(-5, 5) + +/obj/item/bluespace_crystal/attack_self(var/mob/user) + blink_mob(user) + user.drop_item() + user.visible_message("[user] crushes the [src]!") + del(src) + +/obj/item/bluespace_crystal/proc/blink_mob(var/mob/living/L) + do_teleport(L, get_turf(L), blink_range, asoundin = 'sound/effects/phasein.ogg') + +/obj/item/bluespace_crystal/throw_impact(atom/hit_atom) + ..() + if(isliving(hit_atom)) + blink_mob(hit_atom) + del(src) + +// Artifical bluespace crystal, doesn't give you much research. + +/obj/item/bluespace_crystal/artificial + name = "artificial bluespace crystal" + desc = "An artificially made bluespace crystal, it looks delicate." + origin_tech = "bluespace=2" + blink_range = 4 // Not as good as the organic stuff! \ No newline at end of file diff --git a/code/modules/telesci/gps.dm b/code/modules/telesci/gps.dm index 79897c7e6e..3850d439d2 100644 --- a/code/modules/telesci/gps.dm +++ b/code/modules/telesci/gps.dm @@ -1,5 +1,6 @@ +var/list/GPS_list = list() /obj/item/device/gps - name = "Global Positioning System" + name = "global positioning system" desc = "Helping lost spacemen find their way through the planets since 2016." icon = 'icons/obj/telescience.dmi' icon_state = "gps-c" @@ -11,9 +12,15 @@ var/emped = 0 /obj/item/device/gps/New() - name = "Global Positioning System ([gpstag])" + ..() + GPS_list.Add(src) + name = "global positioning system ([gpstag])" overlays += "working" +/obj/item/device/gps/Del() + GPS_list.Remove(src) + ..() + /obj/item/device/gps/emp_act(severity) emped = 1 overlays -= "working" @@ -24,6 +31,7 @@ overlays += "working" /obj/item/device/gps/attack_self(mob/user as mob) + var/obj/item/device/gps/t = "" if(emped) t += "ERROR" @@ -31,7 +39,7 @@ t += "
Set Tag " t += "
Tag: [gpstag]" - for(var/obj/item/device/gps/G in world) + for(var/obj/item/device/gps/G in GPS_list) var/turf/pos = get_turf(G) var/area/gps_area = get_area(G) var/tracked_gpstag = G.gpstag @@ -46,16 +54,14 @@ popup.open() /obj/item/device/gps/Topic(href, href_list) + ..() if(href_list["tag"] ) var/a = input("Please enter desired tag.", name, gpstag) as text - a = copytext(sanitize(a), 1, 20) - if(length(a) != 4) - usr << "\blue The tag must be four letters long!" - return - else + a = uppertext(copytext(sanitize(a), 1, 5)) + if(src.loc == usr) gpstag = a - name = "Global Positioning System ([gpstag])" - return + name = "global positioning system ([gpstag])" + attack_self(usr) /obj/item/device/gps/science icon_state = "gps-s" diff --git a/code/modules/telesci/telepad.dm b/code/modules/telesci/telepad.dm index 1ebc1a3572..c54d079afd 100644 --- a/code/modules/telesci/telepad.dm +++ b/code/modules/telesci/telepad.dm @@ -8,10 +8,6 @@ use_power = 1 idle_power_usage = 200 active_power_usage = 5000 -/obj/machinery/telepad/New() - ..() -/obj/machinery/telepad/Del() - ..() //CARGO TELEPAD// /obj/machinery/telepad_cargo name = "cargo telepad" @@ -23,39 +19,35 @@ idle_power_usage = 20 active_power_usage = 500 var/stage = 0 -/obj/machinery/telepad_cargo/New() - ..() -/obj/machinery/telepad_cargo/Del() - ..() /obj/machinery/telepad_cargo/attackby(obj/item/weapon/W as obj, mob/user as mob) if(istype(W, /obj/item/weapon/wrench)) anchored = 0 playsound(src, 'sound/items/Ratchet.ogg', 50, 1) if(anchored) anchored = 0 - user << "\blue The [src] can now be moved." + user << " The [src] can now be moved." else if(!anchored) anchored = 1 - user << "\blue The [src] is now secured." + user << " The [src] is now secured." if(istype(W, /obj/item/weapon/screwdriver)) if(stage == 0) playsound(src, 'sound/items/Screwdriver.ogg', 50, 1) - user << "\blue You unscrew the telepad's tracking beacon." + user << " You unscrew the telepad's tracking beacon." stage = 1 else if(stage == 1) playsound(src, 'sound/items/Screwdriver.ogg', 50, 1) - user << "\blue You screw in the telepad's tracking beacon." + user << " You screw in the telepad's tracking beacon." stage = 0 if(istype(W, /obj/item/weapon/weldingtool) && stage == 1) playsound(src, 'sound/items/Welder.ogg', 50, 1) - user << "\blue You disassemble the telepad." + user << " You disassemble the telepad." new /obj/item/stack/sheet/metal(get_turf(src)) new /obj/item/stack/sheet/glass(get_turf(src)) del(src) ///TELEPAD CALLER/// /obj/item/device/telepad_beacon - name = "Telepad Beacon" + name = "telepad beacon" desc = "Use to warp in a cargo telepad." icon = 'icons/obj/radio.dmi' icon_state = "beacon" @@ -64,7 +56,7 @@ /obj/item/device/telepad_beacon/attack_self(mob/user as mob) if(user) - user << "\blue Locked In" + user << " Locked In" new /obj/machinery/telepad_cargo(user.loc) playsound(src, 'sound/effects/pop.ogg', 100, 1, 1) del(src) @@ -76,9 +68,6 @@ desc = "Use this to send crates and closets to cargo telepads." icon = 'icons/obj/telescience.dmi' icon_state = "rcs" - opacity = 0 - density = 0 - anchored = 0.0 flags = FPRINT | TABLEPASS| CONDUCT force = 10.0 throwforce = 10.0 @@ -94,18 +83,20 @@ var/teleporting = 0 /obj/item/weapon/rcs/New() + ..() processing_objects.Add(src) +/obj/item/weapon/rcs/examine() desc = "Use this to send crates and closets to cargo telepads. There are [rcharges] charges left." + ..() /obj/item/weapon/rcs/Del() processing_objects.Remove(src) - + ..() /obj/item/weapon/rcs/process() if(rcharges > 10) rcharges = 10 if(last_charge == 0) rcharges++ - desc = "Use this to send crates and closets to cargo telepads. There are [rcharges] charges left." last_charge = 30 else last_charge-- @@ -115,11 +106,11 @@ if(mode == 0) mode = 1 playsound(src.loc, 'sound/effects/pop.ogg', 50, 0) - user << "\red The telepad locator has become uncalibrated." + user << " The telepad locator has become uncalibrated." else mode = 0 playsound(src.loc, 'sound/effects/pop.ogg', 50, 0) - user << "\blue You calibrate the telepad locator." + user << " You calibrate the telepad locator." /obj/item/weapon/rcs/attackby(obj/item/W, mob/user) if(istype(W, /obj/item/weapon/card/emag) && emagged == 0) @@ -127,5 +118,5 @@ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread s.set_up(5, 1, src) s.start() - user << "\red You emag the RCS. Click on it to toggle between modes." + user << " You emag the RCS. Click on it to toggle between modes." return \ No newline at end of file diff --git a/code/modules/telesci/telesci_computer.dm b/code/modules/telesci/telesci_computer.dm index 471473ed2e..85232a4106 100644 --- a/code/modules/telesci/telesci_computer.dm +++ b/code/modules/telesci/telesci_computer.dm @@ -1,20 +1,52 @@ /obj/machinery/computer/telescience - name = "Telepad Control Console" + name = "\improper Telepad Control Console" desc = "Used to teleport objects to and from the telescience telepad." icon_state = "teleport" + var/sending = 1 + var/obj/machinery/telepad/telepad = null + var/temp_msg = "Telescience control console initialized.
Welcome." // VARIABLES // var/teles_left // How many teleports left until it becomes uncalibrated - var/x_off // X offset - var/y_off // Y offset - var/x_co // X coordinate - var/y_co // Y coordinate - var/z_co // Z coordinate + var/datum/projectile_data/last_tele_data = null + var/z_co = 1 + var/power_off + var/rotation_off + var/angle_off + + var/rotation = 0 + var/angle = 45 + var/power + + // Based on the power used + var/teleport_cooldown = 0 + var/list/power_options = list(5, 10, 20, 25, 30, 40, 50, 80, 100) // every index requires a bluespace crystal + var/teleporting = 0 + var/starting_crystals = 3 + var/list/crystals = list() /obj/machinery/computer/telescience/New() - teles_left = rand(8,12) - x_off = rand(-10,10) - y_off = rand(-10,10) + ..() + link_telepad() + recalibrate() + +/obj/machinery/computer/telescience/Del() + eject() + ..() + +/obj/machinery/computer/telescience/examine() + ..() + usr << "There are [crystals.len] bluespace crystals in the crystal ports." + +/obj/machinery/computer/telescience/initialize() + ..() + link_telepad() + for(var/i = 1; i <= starting_crystals; i++) + crystals += new /obj/item/bluespace_crystal/artificial(null) // starting crystals + power = power_options[1] + +/obj/machinery/computer/telescience/proc/link_telepad() + telepad = locate() in range(src, 7) /obj/machinery/computer/telescience/update_icon() if(stat & BROKEN) @@ -28,267 +60,250 @@ stat &= ~NOPOWER /obj/machinery/computer/telescience/attack_paw(mob/user) - usr << "You are too primitive to use this computer." + user << "You are too primitive to use this computer." return +/obj/machinery/computer/telescience/attackby(obj/item/W, mob/user) + if(istype(W, /obj/item/bluespace_crystal)) + if(crystals.len >= power_options.len) + user << "There are not enough crystal ports." + return + user.drop_item() + crystals += W + W.loc = null + user.visible_message("[user] inserts a [W] into the [src]'s crystal port.") + else + ..() + /obj/machinery/computer/telescience/attack_ai(mob/user) - src.attack_hand() + src.attack_hand(user) /obj/machinery/computer/telescience/attack_hand(mob/user) if(..()) return - if(stat & (NOPOWER|BROKEN)) - return - var/t = "" - t += "Set X" - t += "Set Y" - t += "Set Z" - t += "

Current set coordinates:" - t += "([x_co], [y_co], [z_co])" - t += "

Send" + interact(user) + +/obj/machinery/computer/telescience/interact(mob/user) + + var/t = "
[temp_msg]

" + t += "Set Bearing" + t += "
[rotation]°
" + t += "Set Elevation" + t += "
[angle]°
" + t += "Set Power" + t += "
" + + for(var/i = 1; i <= power_options.len; i++) + if(crystals.len < i) + t += "[power_options[i]]" + continue + if(power == power_options[i]) + t += "[power_options[i]]" + continue + t += "[power_options[i]]" + + t += "
" + t += "Set Sector" + t += "
[z_co ? z_co : "NULL"]
" + + t += "
Send" t += " Receive" - t += "

Recalibrate" - var/datum/browser/popup = new(user, "telesci", name, 640, 480) + t += "
Recalibrate Crystals Eject Crystals" + + // Information about the last teleport + t += "
" + if(!last_tele_data) + t += "No teleport data found." + else + t += "Source Location: ([last_tele_data.src_x], [last_tele_data.src_y])
" + //t += "Distance: [round(last_tele_data.distance, 0.1)]m
" + t += "Time: [round(last_tele_data.time, 0.1)] secs
" + t += "
" + + var/datum/browser/popup = new(user, "telesci", name, 300, 500) popup.set_content(t) popup.open() return + /obj/machinery/computer/telescience/proc/sparks() - for(var/obj/machinery/telepad/E in machines) - var/L = get_turf(E) + if(telepad) var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, L) + s.set_up(5, 1, get_turf(telepad)) s.start() + else + return + /obj/machinery/computer/telescience/proc/telefail() - if(prob(95)) - sparks() - for(var/mob/O in hearers(src, null)) - O.show_message("\red The telepad weakly fizzles.", 2) + sparks() + visible_message("The telepad weakly fizzles.") + return + +/obj/machinery/computer/telescience/proc/doteleport(mob/user) + + if(teleport_cooldown > world.time) + temp_msg = "Telepad is recharging power.
Please wait [round((teleport_cooldown - world.time) / 10)] seconds." return - if(prob(5)) - // Irradiate everyone in telescience! - for(var/obj/machinery/telepad/E in machines) - var/L = get_turf(E) - sparks() - for(var/mob/living/carbon/human/M in viewers(L, null)) - M.apply_effect((rand(10, 20)), IRRADIATE, 0) - M << "\red You feel strange." + + if(teleporting) + temp_msg = "Telepad is in use.
Please wait." return - if(prob(1)) - // AI CALL SHUTTLE I SAW RUNE, SUPER LOW CHANCE, CAN HARDLY HAPPEN - for(var/mob/living/carbon/O in viewers(src, null)) - var/datum/game_mode/cult/temp = new - O.show_message("\red The telepad flashes with a strange light, and you have a sudden surge of allegiance toward the true dark one!", 2) - O.mind.make_Cultist() - temp.grant_runeword(O) - sparks() - return - if(prob(1)) - // VIVA LA FUCKING REVOLUTION BITCHES, SUPER LOW CHANCE, CAN HARDLY HAPPEN - for(var/mob/living/carbon/O in viewers(src, null)) - O.show_message("\red The telepad flashes with a strange light, and you see all kind of images flash through your mind, of murderous things Nanotrasen has done, and you decide to rebel!", 2) - O.mind.make_Rev() - sparks() - return - if(prob(1)) - // The OH SHIT FUCK GOD DAMN IT LYNCH THE SCIENTISTS event. - for(var/mob/living/carbon/O in viewers(src, null)) - O.show_message("\red The telepad changes colors rapidly, and opens a portal, and you see what your mind seems to think is the very threads that hold the pattern of the universe together, and a eerie sense of paranoia creeps into you.", 2) - spacevine_infestation() - sparks() - return - if(prob(5)) - // HOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONK - for(var/mob/living/carbon/M in hearers(src, null)) - M << sound('sound/items/AirHorn.ogg') - if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - if(istype(H.l_ear, /obj/item/clothing/ears/earmuffs) || istype(H.r_ear, /obj/item/clothing/ears/earmuffs)) - continue - M << "HONK" - M.sleeping = 0 - M.stuttering += 20 - M.ear_deaf += 30 - M.Weaken(3) - if(prob(30)) - M.Stun(10) - M.Paralyse(4) + + if(telepad) + + var/truePower = Clamp(power + power_off, 1, 1000) + var/trueRotation = rotation + rotation_off + var/trueAngle = Clamp(angle + angle_off, 1, 90) + + var/datum/projectile_data/proj_data = projectile_trajectory(telepad.x, telepad.y, trueRotation, trueAngle, truePower) + last_tele_data = proj_data + + var/trueX = Clamp(round(proj_data.dest_x, 1), 1, world.maxx) + var/trueY = Clamp(round(proj_data.dest_y, 1), 1, world.maxy) + var/spawn_time = round(proj_data.time) * 10 + + var/turf/target = locate(trueX, trueY, z_co) + var/area/A = get_area(target) + flick("pad-beam", telepad) + + if(spawn_time > 15) // 1.5 seconds + playsound(telepad.loc, 'sound/weapons/flash.ogg', 25, 1) + // Wait depending on the time the projectile took to get there + teleporting = 1 + temp_msg = "Powering up bluespace crystals.
Please wait." + + + spawn(round(proj_data.time) * 10) // in seconds + if(!telepad) + return + if(telepad.stat & NOPOWER) + return + teleporting = 0 + teleport_cooldown = world.time + (power * 2) + teles_left -= 1 + + // use a lot of power + use_power(power * 10) + + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, get_turf(telepad)) + s.start() + + temp_msg = "Teleport successful.
" + if(teles_left < 10) + temp_msg += "
Calibration required soon." else - M.make_jittery(500) - sparks() - return - if(prob(1)) - // They did the mash! (They did the monster mash!) The monster mash! (It was a graveyard smash!) - sparks() - for(var/obj/machinery/telepad/E in machines) - var/L = get_turf(E) - var/blocked = list(/mob/living/simple_animal/hostile, - /mob/living/simple_animal/hostile/alien/queen/large, - /mob/living/simple_animal/hostile/retaliate, - /mob/living/simple_animal/hostile/retaliate/clown, - /mob/living/simple_animal/hostile/giant_spider/nurse) - var/list/hostiles = typesof(/mob/living/simple_animal/hostile) - blocked - playsound(L, 'sound/effects/phasein.ogg', 100, 1) - for(var/mob/living/carbon/human/M in viewers(L, null)) - flick("e_flash", M.flash) - var/chosen = pick(hostiles) - var/mob/living/simple_animal/hostile/H = new chosen - H.loc = L - return - return - return + temp_msg += "Data printed below." + investigate_log("[key_name(usr)]/[user] has teleported with Telescience at [trueX],[trueY],[z_co], in [A ? A.name : "null area"].","telesci") -/obj/machinery/computer/telescience/proc/dosend() - var/trueX = (x_co + x_off) - var/trueY = (y_co + y_off) - for(var/obj/machinery/telepad/E in machines) - var/L = get_turf(E) - var/target = locate(trueX, trueY, z_co) - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, L) - s.start() - flick("pad-beam", E) - usr << "\blue Teleport successful." - var/sparks = get_turf(target) - var/datum/effect/effect/system/spark_spread/y = new /datum/effect/effect/system/spark_spread - y.set_up(5, 1, sparks) - y.start() - for(var/obj/item/OI in L) - do_teleport(OI, target, 0) - for(var/obj/structure/closet/OC in L) - do_teleport(OC, target, 0) - for(var/mob/living/carbon/MO in L) - do_teleport(MO, target, 0) - for(var/mob/living/simple_animal/SA in L) - do_teleport(SA, target, 0) - return - return + var/sparks = get_turf(target) + var/datum/effect/effect/system/spark_spread/y = new /datum/effect/effect/system/spark_spread + y.set_up(5, 1, sparks) + y.start() -/obj/machinery/computer/telescience/proc/doreceive() - var/trueX = (x_co + x_off) - var/trueY = (y_co + y_off) - for(var/obj/machinery/telepad/E in machines) - var/L = get_turf(E) - var/T = locate(trueX, trueY, z_co) - var/G = get_turf(T) - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, L) - s.start() - flick("pad-beam", E) - usr << "\blue Teleport successful." - var/sparks = get_turf(T) - var/datum/effect/effect/system/spark_spread/y = new /datum/effect/effect/system/spark_spread - y.set_up(5, 1, sparks) - y.start() - for(var/obj/item/ROI in G) - do_teleport(ROI, E, 0) - for(var/obj/structure/closet/ROC in G) - do_teleport(ROC, E, 0) - for(var/mob/living/carbon/RMO in G) - do_teleport(RMO, E, 0) - for(var/mob/living/simple_animal/RSA in G) - do_teleport(RSA, E, 0) - return - return + var/turf/source = target + var/turf/dest = get_turf(telepad) + if(sending) + source = dest + dest = target -/obj/machinery/computer/telescience/proc/telesend() - if(x_co == "") - usr << "\red Error: set coordinates." + flick("pad-beam", telepad) + playsound(telepad.loc, 'sound/weapons/emitter2.ogg', 25, 1) + for(var/atom/movable/ROI in source) + // if is anchored, don't let through + if(ROI.anchored) + if(isliving(ROI)) + var/mob/living/L = ROI + if(L.buckled) + // TP people on office chairs + if(L.buckled.anchored) + continue + else + continue + else if(!isobserver(ROI)) + continue + do_teleport(ROI, dest) + updateDialog() + +/obj/machinery/computer/telescience/proc/teleport(mob/user) + if(rotation == null || angle == null || z_co == null) + temp_msg = "ERROR!
Set a angle, rotation and sector." return - if(y_co == "") - usr << "\red Error: set coordinates." - return - if(z_co == "") - usr << "\red Error: set coordinates." - return - if(x_co < 1 || x_co > 255) + if(power <= 0) telefail() - usr << "\red Error: X is less than 11 or greater than 245." + temp_msg = "ERROR!
No power selected!" return - if(y_co < 1 || y_co > 255) + if(angle < 1 || angle > 90) telefail() - usr << "\red Error: Y is less than 11 or greater than 245." + temp_msg = "ERROR!
Elevation is less than 1 or greater than 90." return if(z_co == 2 || z_co < 1 || z_co > 6) telefail() - usr << "\red Error: Z is less than 1, greater than 6, or equal to 2." + temp_msg = "ERROR! Sector is less than 1,
greater than 6, or equal to 2." return if(teles_left > 0) - teles_left -= 1 - dosend() + doteleport(user) else - dosend() + telefail() + temp_msg = "ERROR!
Calibration required." return return -/obj/machinery/computer/telescience/proc/telereceive() - // basically the same thing - if(x_co == "") - usr << "\red Error: set coordinates." - return - if(y_co == "") - usr << "\red Error: set coordinates." - return - if(z_co == "") - usr << "\red Error: set coordinates." - return - if(x_co < 1 || x_co > 255) - telefail() - usr << "\red Error: X is less than 11 or greater than 200." - return - if(y_co < 1 || y_co > 255) - telefail() - usr << "\red Error: Y is less than 11 or greater than 200." - return - if(z_co == 2 || z_co < 1 || z_co > 6) - telefail() - usr << "\red Error: Z is less than 1, greater than 6, or equal to 2." - return - if(teles_left > 0) - teles_left -= 1 - doreceive() - else - if(prob(35)) - doreceive() - else - telefail() - return - return +/obj/machinery/computer/telescience/proc/eject() + for(var/obj/item/I in crystals) + I.loc = src.loc + crystals -= I + power = 0 /obj/machinery/computer/telescience/Topic(href, href_list) if(..()) return - if(href_list["setx"]) - var/a = input("Please input desired X coordinate.", name, x_co) as num - a = copytext(sanitize(a), 1, 20) - x_co = a - x_co = text2num(x_co) - return - if(href_list["sety"]) - var/b = input("Please input desired Y coordinate.", name, y_co) as num - b = copytext(sanitize(b), 1, 20) - y_co = b - y_co = text2num(y_co) - return + if(href_list["setrotation"]) + var/new_rot = input("Please input desired bearing in degrees.", name, rotation) as num + if(..()) // Check after we input a value, as they could've moved after they entered something + return + rotation = Clamp(new_rot, -900, 900) + rotation = round(rotation, 0.01) + + if(href_list["setangle"]) + var/new_angle = input("Please input desired elevation in degrees.", name, angle) as num + if(..()) + return + angle = Clamp(round(new_angle, 0.1), 1, 9999) + + if(href_list["setpower"]) + var/index = href_list["setpower"] + index = text2num(index) + if(index != null && power_options[index]) + if(crystals.len >= index) + power = power_options[index] + if(href_list["setz"]) - var/c = input("Please input desired Z coordinate.", name, z_co) as num - c = copytext(sanitize(c), 1, 20) - z_co = c - z_co = text2num(z_co) - return + var/new_z = input("Please input desired sector.", name, z_co) as num + if(..()) + return + z_co = Clamp(round(new_z), 1, 10) + if(href_list["send"]) - telesend() - return + sending = 1 + teleport(usr) + if(href_list["receive"]) - telereceive() - return + sending = 0 + teleport(usr) + if(href_list["recal"]) - teles_left = rand(9,12) - x_off = rand(-10,10) - y_off = rand(-10,10) - for(var/obj/machinery/telepad/E in machines) - var/L = get_turf(E) - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, L) - s.start() - usr << "\blue Calibration successful." - return \ No newline at end of file + recalibrate() + sparks() + temp_msg = "NOTICE:
Calibration successful." + + if(href_list["eject"]) + eject() + temp_msg = "NOTICE:
Bluespace crystals ejected." + + updateDialog() + +/obj/machinery/computer/telescience/proc/recalibrate() + teles_left = rand(30, 40) + angle_off = rand(-25, 25) + power_off = rand(-4, 0) + rotation_off = rand(-10, 10) \ No newline at end of file diff --git a/config/.gitignore b/config/.gitignore new file mode 100644 index 0000000000..ec7ed9b452 --- /dev/null +++ b/config/.gitignore @@ -0,0 +1,3 @@ +#ignore everything here, except subdirectories. +* +!*/ diff --git a/config/example/config.txt b/config/example/config.txt index db1702b67c..fb320da581 100644 --- a/config/example/config.txt +++ b/config/example/config.txt @@ -121,6 +121,12 @@ VOTE_AUTOTRANSFER_INTERVAL 36000 ## players' votes default to "No vote" (otherwise, default to "No change") DEFAULT_NO_VOTE +## Allow ghosts to see antagonist through AntagHUD +ALLOW_ANTAG_HUD + +## If ghosts use antagHUD they are no longer allowed to join the round. +ANTAG_HUD_RESTRICTED + ## allow AI job ALLOW_AI diff --git a/icons/mob/belt_mirror.dmi b/icons/mob/belt_mirror.dmi index 3639285555..9358ba3cd9 100644 Binary files a/icons/mob/belt_mirror.dmi and b/icons/mob/belt_mirror.dmi differ diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index b13b296cf1..0502c01147 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/icons/obj/custom_items.dmi b/icons/obj/custom_items.dmi index 0b82c58bcc..5cc07c12b3 100644 Binary files a/icons/obj/custom_items.dmi and b/icons/obj/custom_items.dmi differ diff --git a/icons/obj/telescience.dmi b/icons/obj/telescience.dmi index 1f3344f2e4..4e8251beac 100644 Binary files a/icons/obj/telescience.dmi and b/icons/obj/telescience.dmi differ