Merge branch 'master' into cargo-bugfixes

This commit is contained in:
qweq12yt
2021-04-08 19:15:55 -03:00
committed by GitHub
215 changed files with 303587 additions and 303356 deletions
+7 -4
View File
@@ -308,10 +308,10 @@
var/list/areas_with_LS = list()
var/list/areas_with_intercom = list()
var/list/areas_with_camera = list()
var/list/station_areas_blacklist = typecacheof(list(/area/holodeck/rec_center, /area/shuttle, /area/engine/supermatter, /area/science/test_area, /area/space, /area/solar, /area/mine, /area/ruin, /area/asteroid))
var/list/station_areas_blacklist = typecacheof(list(/area/holodeck/rec_center, /area/shuttle, /area/engineering/supermatter, /area/science/test_area, /area/space, /area/solars, /area/mine, /area/ruin, /area/asteroid))
if(SSticker.current_state == GAME_STATE_STARTUP)
to_chat(usr, "Game still loading, please hold!")
to_chat(usr, "Game still loading, please hold!", confidential = TRUE)
return
var/log_message
@@ -326,8 +326,11 @@
for(var/area/A in world)
if(on_station)
var/turf/picked = safepick(get_area_turfs(A.type))
if(picked && is_station_level(picked.z))
var/list/area_turfs = get_area_turfs(A.type)
if (!length(area_turfs))
continue
var/turf/picked = pick(area_turfs)
if(is_station_level(picked.z))
if(!(A.type in areas_all) && !is_type_in_typecache(A, station_areas_blacklist))
areas_all.Add(A.type)
else if(!(A.type in areas_all))
+2
View File
@@ -48,6 +48,8 @@
if(C.prefs.toggles & SOUND_PRAYERS)
if(usr.job == "Chaplain")
SEND_SOUND(C, sound('sound/effects/pray.ogg'))
else
SEND_SOUND(C, sound('sound/effects/ding.ogg'))
to_chat(usr, "<span class='info'>You pray to the gods: \"[msg_tmp]\"</span>", confidential = TRUE)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Prayer") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+1 -1
View File
@@ -349,7 +349,7 @@
return
SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Egalitarian Station"))
for(var/obj/machinery/door/airlock/W in GLOB.machines)
if(is_station_level(W.z) && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison))
if(is_station_level(W.z) && !istype(get_area(W), /area/command) && !istype(get_area(W), /area/commons) && !istype(get_area(W), /area/service) && !istype(get_area(W), /area/command/heads_quarters) && !istype(get_area(W), /area/security/prison))
W.req_access = list()
message_admins("[key_name_admin(holder)] activated Egalitarian Station mode")
priority_announce("CentCom airlock control override activated. Please take this time to get acquainted with your coworkers.", null, "commandreport")
@@ -88,7 +88,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
/mob/camera/blob/proc/is_valid_turf(turf/T)
var/area/A = get_area(T)
if((A && !A.blob_allowed) || !T || !is_station_level(T.z) || isspaceturf(T))
if((A && !(A.area_flags & BLOBS_ALLOWED)) || !T || !is_station_level(T.z) || isspaceturf(T))
return FALSE
return TRUE
@@ -131,7 +131,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
var/area/Ablob = get_area(T)
if(!Ablob.blob_allowed)
if(!(Ablob.area_flags & BLOBS_ALLOWED))
continue
if(!(ROLE_BLOB in L.faction))
@@ -144,7 +144,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
for(var/area/A in GLOB.sortedAreas)
if(!(A.type in GLOB.the_station_areas))
continue
if(!A.blob_allowed)
if(!(A.area_flags & BLOBS_ALLOWED))
continue
A.color = blobstrain.color
A.name = "blob"
+1 -1
View File
@@ -211,7 +211,7 @@
to_chat(src, "<span class='userdanger'>You have no core and are about to die! May you rest in peace.</span>")
return
var/area/A = get_area(T)
if(isspaceturf(T) || A && !A.blob_allowed)
if(isspaceturf(T) || A && !(A.area_flags & BLOBS_ALLOWED))
to_chat(src, "<span class='warning'>You cannot relocate your core here!</span>")
return
if(!can_buy(80))
@@ -25,7 +25,7 @@
if(owner_overmind)
overmind = owner_overmind
var/area/Ablob = get_area(src)
if(Ablob.blob_allowed) //Is this area allowed for winning as blob?
if(Ablob.area_flags & BLOBS_ALLOWED) //Is this area allowed for winning as blob?
overmind.blobs_legit += src
GLOB.blobs += src //Keep track of the blob in the normal list either way
setDir(pick(GLOB.cardinals))
@@ -37,7 +37,7 @@
lastWarning = world.time
to_chat(src, "<span class='warning'>This turf is consecrated and can't be crossed!</span>")
return
if(istype(get_area(T), /area/chapel))
if(istype(get_area(T), /area/service/chapel))
if((world.time - lastWarning) >= 30)
lastWarning = world.time
to_chat(src, "<span class='warning'>The Chapel is hallowed ground under a heretical deity, and can't be accessed!</span>")
@@ -24,7 +24,8 @@
/datum/clockwork_scripture/create_object/stargazer/check_special_requirements()
var/area/A = get_area(invoker)
if(A.outdoors || A.map_name == "Space" || !A.blob_allowed)
var/turf/T = get_turf(invoker)
if(!is_station_level(invoker.z) || isspaceturf(T) || !(A.area_flags & VALID_TERRITORY))
to_chat(invoker, "<span class='danger'>Stargazers can't be built off-station.</span>")
return
return ..()
@@ -34,7 +34,7 @@
return FALSE
var/area/A = get_area(invoker)
var/turf/T = get_turf(invoker)
if(!T || !is_station_level(T.z) || istype(A, /area/shuttle) || !A.blob_allowed)
if(!is_station_level(T.z) || isspaceturf(T) || !(A.area_flags & VALID_TERRITORY) || isshuttleturf(T))
to_chat(invoker, "<span class='warning'>You must be on the station to activate the Ark!</span>")
return FALSE
if(GLOB.clockwork_gateway_activated)
@@ -87,7 +87,7 @@
if(!M || !M.current)
continue
if(ishuman(M.current))
M.current.add_overlay(mutable_appearance('icons/effects/genetics.dmi', "servitude", -MUTATIONS_LAYER))
M.current.add_overlay(mutable_appearance('icons/effects/genetics.dmi', "servitude", -ANTAG_LAYER))
var/turf/T = get_turf(src)
var/list/open_turfs = list()
for(var/turf/open/OT in orange(1, T))
@@ -52,7 +52,7 @@
break
if(has_starlight && anchored)
var/area/A = get_area(src)
if(A.outdoors || A.map_name == "Space" || !A.blob_allowed)
if(A.outdoors || A.map_name == "Space" || !(A.area_flags & VALID_TERRITORY))
has_starlight = FALSE
if(old_status != has_starlight)
if(has_starlight)
@@ -139,7 +139,7 @@
current.throw_alert("clockinfo", /obj/screen/alert/clockwork/infodump)
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
if(G && G.active && ishuman(current))
current.add_overlay(mutable_appearance('icons/effects/genetics.dmi', "servitude", -MUTATIONS_LAYER))
current.add_overlay(mutable_appearance('icons/effects/genetics.dmi', "servitude", -ANTAG_LAYER))
/datum/antagonist/clockcult/remove_innate_effects(mob/living/mob_override)
var/mob/living/current = owner.current
+2 -2
View File
@@ -332,7 +332,7 @@
var/mob/living/carbon/human/H = cultist
new /obj/effect/temp_visual/cult/sparks(get_turf(H), H.dir)
var/istate = pick("halo1","halo2","halo3","halo4","halo5","halo6")
H.add_overlay(mutable_appearance('icons/effects/32x64.dmi', istate, -BODY_FRONT_LAYER))
H.add_overlay(mutable_appearance('icons/effects/32x64.dmi', istate, -ANTAG_LAYER))
/datum/team/cult/proc/setup_objectives()
//SAC OBJECTIVE , todo: move this to objective internals
@@ -419,7 +419,7 @@
var/sanity = 0
while(summon_spots.len < SUMMON_POSSIBILITIES && sanity < 100)
var/area/summon = pick(GLOB.sortedAreas - summon_spots)
if(summon && is_station_level(summon.z) && summon.valid_territory)
if(summon && is_station_level(summon.z) && !(summon.area_flags & VALID_TERRITORY))
summon_spots += summon
sanity++
update_explanation_text()
+1 -1
View File
@@ -148,7 +148,7 @@ This file contains the cult dagger and rune list code
to_chat(user, "<span class='cult'>There is already a rune here.</span>")
return FALSE
var/area/A = get_area(T)
if((!is_station_level(T.z) && !is_mining_level(T.z)) || (A && !A.blob_allowed))
if((!is_station_level(T.z) && !is_mining_level(T.z)) || !(A?.area_flags & VALID_TERRITORY))
to_chat(user, "<span class='warning'>The veil is not weak enough here.</span>")
return FALSE
return TRUE
+47 -31
View File
@@ -261,19 +261,26 @@
S.DisIntegrate(src)
return TRUE
/obj/machinery/door/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
var/isonshuttle = istype(get_area(src), /area/shuttle)
for(var/turf/T in range(1, src))
var/area/A = get_area(T)
if(isspaceturf(T) || (!isonshuttle && (istype(A, /area/shuttle) || istype(A, /area/space))) || (isonshuttle && !istype(A, /area/shuttle)))
to_chat(S, "<span class='warning'>Destroying this object has the potential to cause a hull breach. Aborting.</span>")
S.target = null
/obj/machinery/door/swarmer_act(mob/living/simple_animal/hostile/swarmer/actor)
var/is_on_shuttle = istype(get_area(src), /area/shuttle)
for(var/turf/turf_in_range in range(1, src))
var/area/turf_area = get_area(turf_in_range)
//Check for dangerous pressure differences
// if (turf_in_range.return_turf_delta_p() > DANGEROUS_DELTA_P)
// to_chat(actor, "<span class='warning'>Destroying this object has the potential to cause an explosive pressure release. Aborting.</span>")
// actor.target = null
// return TRUE
//Check if breaking this door will expose the station to space/planetary atmos
if(isspaceturf(turf_in_range) || (!is_on_shuttle && (istype(turf_area, /area/shuttle) || istype(turf_area, /area/space))) || (is_on_shuttle && !istype(turf_area, /area/shuttle)))
to_chat(actor, "<span class='warning'>Destroying this object has the potential to cause a hull breach. Aborting.</span>")
actor.target = null
return FALSE
else if(istype(A, /area/engine/supermatter))
to_chat(S, "<span class='warning'>Disrupting the containment of a supermatter crystal would not be to our benefit. Aborting.</span>")
S.target = null
//Check if this door is important in supermatter containment
else if(istype(turf_area, /area/engineering/supermatter))
to_chat(actor, "<span class='warning'>Disrupting the containment of a supermatter crystal would not be to our benefit. Aborting.</span>")
actor.target = null
return FALSE
S.DisIntegrate(src)
actor.DisIntegrate(src)
return TRUE
/obj/machinery/camera/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
@@ -342,31 +349,40 @@
to_chat(S, "<span class='warning'>This bluespace source will be important to us later. Aborting.</span>")
return FALSE
/turf/closed/wall/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
var/isonshuttle = istype(loc, /area/shuttle)
for(var/turf/T in range(1, src))
var/area/A = get_area(T)
if(isspaceturf(T) || (!isonshuttle && (istype(A, /area/shuttle) || istype(A, /area/space))) || (isonshuttle && !istype(A, /area/shuttle)))
to_chat(S, "<span class='warning'>Destroying this object has the potential to cause a hull breach. Aborting.</span>")
S.target = null
/turf/closed/wall/swarmer_act(mob/living/simple_animal/hostile/swarmer/actor)
var/is_on_shuttle = istype(loc, /area/shuttle)
for(var/turf/turf_in_range in range(1, src))
var/area/turf_area = get_area(turf_in_range)
// if (turf_in_range.return_turf_delta_p() > DANGEROUS_DELTA_P)
// to_chat(actor, "<span class='warning'>Destroying this object has the potential to cause an explosive pressure release. Aborting.</span>")
// actor.target = null
// return TRUE
if(isspaceturf(turf_in_range) || (!is_on_shuttle && (istype(turf_area, /area/shuttle) || istype(turf_area, /area/space))) || (is_on_shuttle && !istype(turf_area, /area/shuttle)))
to_chat(actor, "<span class='warning'>Destroying this object has the potential to cause a hull breach. Aborting.</span>")
actor.target = null
return TRUE
else if(istype(A, /area/engine/supermatter))
to_chat(S, "<span class='warning'>Disrupting the containment of a supermatter crystal would not be to our benefit. Aborting.</span>")
S.target = null
else if(istype(turf_area, /area/engineering/supermatter))
to_chat(actor, "<span class='warning'>Disrupting the containment of a supermatter crystal would not be to our benefit. Aborting.</span>")
actor.target = null
return TRUE
return ..()
/obj/structure/window/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
var/isonshuttle = istype(get_area(src), /area/shuttle)
for(var/turf/T in range(1, src))
var/area/A = get_area(T)
if(isspaceturf(T) || (!isonshuttle && (istype(A, /area/shuttle) || istype(A, /area/space))) || (isonshuttle && !istype(A, /area/shuttle)))
to_chat(S, "<span class='warning'>Destroying this object has the potential to cause a hull breach. Aborting.</span>")
S.target = null
/obj/structure/window/swarmer_act(mob/living/simple_animal/hostile/swarmer/actor)
var/is_on_shuttle = istype(get_area(src), /area/shuttle)
for(var/t in RANGE_TURFS(1, src))
var/turf/turf_in_range = t
var/area/turf_area = get_area(turf_in_range)
// if (turf_in_range.return_turf_delta_p() > DANGEROUS_DELTA_P)
// to_chat(actor, "<span class='warning'>Destroying this object has the potential to cause an explosive pressure release. Aborting.</span>")
// actor.target = null
// return TRUE
if(isspaceturf(turf_in_range) || (!is_on_shuttle && (istype(turf_area, /area/shuttle) || istype(turf_area, /area/space))) || (is_on_shuttle && !istype(turf_area, /area/shuttle)))
to_chat(actor, "<span class='warning'>Destroying this object has the potential to cause a hull breach. Aborting.</span>")
actor.target = null
return TRUE
else if(istype(A, /area/engine/supermatter))
to_chat(S, "<span class='warning'>Disrupting the containment of a supermatter crystal would not be to our benefit. Aborting.</span>")
S.target = null
else if(istype(turf_area, /area/engineering/supermatter))
to_chat(actor, "<span class='warning'>Disrupting the containment of a supermatter crystal would not be to our benefit. Aborting.</span>")
actor.target = null
return TRUE
return ..()
@@ -385,14 +385,10 @@
/obj/item/warpwhistle/attack_self(mob/living/carbon/user)
if(!istype(user) || on_cooldown)
return
var/turf/T = get_turf(user)
var/area/A = get_area(user)
if(!T || !A || A.noteleport)
to_chat(user, "<span class='warning'>You play \the [src], yet no sound comes out of it... Looks like it won't work here.</span>")
return
on_cooldown = TRUE
last_user = user
playsound(T,'sound/magic/warpwhistle.ogg', 200, 1)
var/turf/T = get_turf(user)
playsound(T,'sound/magic/warpwhistle.ogg', 200, TRUE)
ADD_TRAIT(user, TRAIT_MOBILITY_NOMOVE, src)
ADD_TRAIT(user, TRAIT_MOBILITY_NOUSE, src)
ADD_TRAIT(user, TRAIT_MOBILITY_NOPICKUP, src)
@@ -400,6 +396,10 @@
new /obj/effect/temp_visual/tornado(T)
sleep(20)
if(interrupted(user))
REMOVE_TRAIT(user, TRAIT_MOBILITY_NOMOVE, src)
REMOVE_TRAIT(user, TRAIT_MOBILITY_NOUSE, src)
REMOVE_TRAIT(user, TRAIT_MOBILITY_NOPICKUP, src)
user.update_mobility()
return
user.invisibility = INVISIBILITY_MAXIMUM
user.status_flags |= GODMODE
@@ -427,8 +427,7 @@
if(interrupted(user))
return
on_cooldown = 2
sleep(40)
on_cooldown = 0
addtimer(VARSET_CALLBACK(src, on_cooldown, 0), 4 SECONDS)
/obj/item/warpwhistle/Destroy()
if(on_cooldown == 1 && last_user) //Flute got dunked somewhere in the teleport
-23
View File
@@ -213,29 +213,6 @@
for(var/obj/item/organ/genital/G in internal_organs)
if(!CHECK_BITFIELD(G.genital_flags, CAN_CLIMAX_WITH)) //Skip things like wombs and testicles
continue
var/mob/living/partner
var/check_target
var/list/worn_stuff = get_equipped_items()
if(G.is_exposed(worn_stuff))
if(pulling) //Are we pulling someone? Priority target, we can't be making option menus for this, has to be quick
if(isliving(pulling)) //Don't fuck objects
check_target = pulling
if(pulledby && !check_target) //prioritise pulled over pulledby
if(isliving(pulledby))
check_target = pulledby
//Now we should have a partner, or else we have to come alone
if(check_target)
if(iscarbon(check_target)) //carbons can have clothes
var/mob/living/carbon/C = check_target
if(C.exposed_genitals.len || C.is_groin_exposed() || C.is_chest_exposed()) //Are they naked enough?
partner = C
else //A cat is fine too
partner = check_target
if(partner) //Did they pass the clothing checks?
mob_climax_partner(G, partner, mb_time = 0) //Instant climax due to forced
continue //You've climaxed once with this organ, continue on
//not exposed OR if no partner was found while exposed, climax alone
mob_climax_outside(G, mb_time = 0) //removed climax timer for sudden, forced orgasms
//Now all genitals that could climax, have.
//Since this was a forced climax, we do not need to continue with the other stuff
+3 -3
View File
@@ -20,7 +20,7 @@
var/printed_beacons = 0 //number of beacons printed. Used to determine beacon names.
var/list/meme_pack_data
var/obj/item/supplypod_beacon/beacon //the linked supplypod beacon
var/area/landingzone = /area/quartermaster/storage //where we droppin boys
var/area/landingzone = /area/cargo/storage //where we droppin boys
var/podType = /obj/structure/closet/supplypod
var/cooldown = 0 //cooldown to prevent printing supplypod beacon spam
var/locked = TRUE //is the console locked? unlock with ID
@@ -177,9 +177,9 @@
LZ = get_turf(beacon)
beacon.update_status(SP_LAUNCH)
else if (!usingBeacon)//find a suitable supplypod landing zone in cargobay
landingzone = GLOB.areas_by_type[/area/quartermaster/storage]
landingzone = GLOB.areas_by_type[/area/cargo/storage]
if (!landingzone)
WARNING("[src] couldnt find a Quartermaster/Storage (aka cargobay) area on the station, and as such it has set the supplypod landingzone to the area it resides in.")
WARNING("[src] couldnt find \"/area/cargo/storage\" (aka cargobay) area on the station, and as such it has set the supplypod landingzone to the area it resides in.")
landingzone = get_area(src)
for(var/turf/open/floor/T in landingzone.contents)//uses default landing zone
if(is_blocked_turf(T))
+4 -16
View File
@@ -55,10 +55,10 @@
cost = 150 // five times their export
contains = list(/obj/item/stack/sheet/mineral/sandstone/thirty)
/datum/supply_pack/materials/wood50
crate_type = /obj/structure/closet/secure_closet/goodies
name = "50 Wood Planks"
desc = "Turn cargo's boring metal groundwork into beautiful panelled flooring and much more with fifty wooden planks!"
/datum/supply_pack/materials/wood20
goody = PACK_GOODY_PUBLIC
name = "20 Wood Planks"
desc = "Turn cargo's boring metal groundwork into beautiful panelled flooring and much more with twenty wooden planks!"
cost = 400 // 6-7 planks shy from having equal import/export prices
contains = list(/obj/item/stack/sheet/mineral/wood/twenty)
@@ -69,18 +69,6 @@
cost = 600
contains = list(/obj/item/rcd_ammo/large)
/datum/supply_pack/materials/rawlumber
name = "50 Towercap Logs"
desc = "Raw logs from towercaps. Contains fifty logs."
cost = 1000
contains = list(/obj/item/grown/log)
crate_name = "lumber crate"
/datum/supply_pack/materials/rawlumber/generate()
. = ..()
for(var/i in 1 to 49)
new /obj/item/grown/log(.)
//////////////////////////////////////////////////////////////////////////////
///////////////////////////// Canisters //////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
+9 -6
View File
@@ -19,18 +19,21 @@
var/list/safe_area_types = typecacheof(list(
/area/ai_monitored/turret_protected/ai,
/area/ai_monitored/turret_protected/ai_upload,
/area/engine,
/area/solar,
/area/engineering,
/area/solars,
/area/holodeck,
/area/shuttle)
/area/shuttle,
/area/maintenance,
/area/science/test_area)
)
//Subtypes from the above that actually should explode.
var/list/unsafe_area_subtypes = typecacheof(list(/area/engine/break_room))
var/list/unsafe_area_subtypes = typecacheof(list(/area/engineering/break_room))
allowed_areas = make_associative(GLOB.the_station_areas) - safe_area_types + unsafe_area_subtypes
return safepick(typecache_filter_list(GLOB.sortedAreas,allowed_areas))
var/list/possible_areas = typecache_filter_list(GLOB.sortedAreas,allowed_areas)
if (length(possible_areas))
return pick(possible_areas)
/datum/round_event/anomaly/setup()
impact_area = findEventArea()
+68 -59
View File
@@ -7,6 +7,10 @@
earliest_start = 30 MINUTES
gamemode_blacklist = list("nuclear")
#define PIRATES_ROGUES "Rogues"
// #define PIRATES_SILVERSCALES "Silverscales"
// #define PIRATES_DUTCHMAN "Flying Dutchman"
/datum/round_event_control/pirates/preRunEvent()
if (!SSmapping.empty_space)
return EVENT_CANT_RUN
@@ -15,31 +19,54 @@
/datum/round_event/pirates
startWhen = 60 //2 minutes to answer
var/datum/comm_message/threat_message
var/datum/comm_message/threat_msg
var/payoff = 0
var/payoff_min = 20000
var/paid_off = FALSE
var/pirate_type
var/ship_template
var/ship_name = "Space Privateers Association"
var/shuttle_spawned = FALSE
/datum/round_event/pirates/setup()
ship_name = pick(strings(PIRATE_NAMES_FILE, "ship_names"))
pirate_type = PIRATES_ROGUES //pick(PIRATES_ROGUES, PIRATES_SILVERSCALES, PIRATES_DUTCHMAN)
switch(pirate_type)
if(PIRATES_ROGUES)
ship_name = pick(strings(PIRATE_NAMES_FILE, "rogue_names"))
// if(PIRATES_SILVERSCALES)
// ship_name = pick(strings(PIRATE_NAMES_FILE, "silverscale_names"))
// if(PIRATES_DUTCHMAN)
// ship_name = "Flying Dutchman"
/datum/round_event/pirates/announce(fake)
priority_announce("A business proposition has been downloaded and printed out at all communication consoles.", "Incoming Business Proposition", "commandreport")
priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", "commandreport")
if(fake)
return
threat_message = new
threat_msg = new
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR)
if(D)
payoff = round(D.account_balance * 0.80)
threat_message.title = "Business proposition"
threat_message.content = "This is [ship_name]. Pay up [payoff] credits or you'll walk the plank."
threat_message.possible_answers = list("We'll pay.","No way.")
threat_message.answer_callback = CALLBACK(src,.proc/answered)
SScommunications.send_message(threat_message,unique = TRUE)
payoff = max(payoff_min, FLOOR(D.account_balance * 0.80, 1000))
switch(pirate_type)
if(PIRATES_ROGUES)
ship_template = /datum/map_template/shuttle/pirate/default
threat_msg.title = "Sector protection offer"
threat_msg.content = "Hey, pal, this is the [ship_name]. Can't help but notice you're rocking a wild and crazy shuttle there with NO INSURANCE! Crazy. What if something happened to it, huh?! We've done a quick evaluation on your rates in this sector and we're offering [payoff] to cover for your shuttle in case of any disaster."
threat_msg.possible_answers = list("Purchase Insurance.","Reject Offer.")
// if(PIRATES_SILVERSCALES)
// ship_template = /datum/map_template/shuttle/pirate/silverscale
// threat_msg.title = "Tribute to high society"
// threat_msg.content = "This is the [ship_name]. The Silver Scales wish for some tribute from your plebeian lizards. [payoff] credits should do the trick."
// threat_msg.possible_answers = list("We'll pay.","Tribute? Really? Go away.")
// if(PIRATES_DUTCHMAN)
// ship_template = /datum/map_template/shuttle/pirate/dutchman
// threat_msg.title = "Business proposition"
// threat_msg.content = "Ahoy! This be the [ship_name]. Cough up [payoff] credits or you'll walk the plank."
// threat_msg.possible_answers = list("We'll pay.","We will not be extorted.")
threat_msg.answer_callback = CALLBACK(src,.proc/answered)
SScommunications.send_message(threat_msg,unique = TRUE)
/datum/round_event/pirates/proc/answered()
if(threat_message && threat_message.answered == 1)
if(threat_msg && threat_msg.answered == 1)
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR)
if(D)
if(D.adjust_money(-payoff))
@@ -49,10 +76,14 @@
else
priority_announce("Trying to cheat us? You'll regret this!",sender_override = ship_name)
if(!shuttle_spawned)
priority_announce("You won't listen to reason? Then we'll take what's yours or die trying!",sender_override = ship_name)
spawn_shuttle()
else
priority_announce("Too late to beg for mercy!",sender_override = ship_name)
/datum/round_event/pirates/start()
if(threat_msg && !threat_msg.answered)
threat_msg.possible_answers = list("Too late")
threat_msg.answered = 1
if(!paid_off && !shuttle_spawned)
spawn_shuttle()
@@ -62,10 +93,7 @@
var/list/candidates = pollGhostCandidates("Do you wish to be considered for pirate crew?", ROLE_TRAITOR)
shuffle_inplace(candidates)
if(!SSmapping.empty_space)
SSmapping.empty_space = SSmapping.add_new_zlevel("Empty Area For Pirates", list(ZTRAIT_LINKAGE = SELFLOOPING))
var/datum/map_template/shuttle/pirate/default/ship = new
var/datum/map_template/shuttle/pirate/ship = new ship_template
var/x = rand(TRANSITIONEDGE,world.maxx - TRANSITIONEDGE - ship.width)
var/y = rand(TRANSITIONEDGE,world.maxy - TRANSITIONEDGE - ship.height)
var/z = SSmapping.empty_space.z_value
@@ -75,6 +103,7 @@
if(!ship.load(T))
CRASH("Loading pirate ship failed!")
for(var/turf/A in ship.get_affected_turfs(T))
for(var/obj/effect/mob_spawn/human/pirate/spawner in A)
if(candidates.len > 0)
@@ -84,7 +113,8 @@
announce_to_ghosts(M)
else
announce_to_ghosts(spawner)
priority_announce("Unidentified ship detected near the station.")
priority_announce("Unidentified armed ship detected near the station.")
//Shuttle equipment
@@ -145,7 +175,7 @@
new /obj/effect/temp_visual/emp(get_turf(S))
/obj/machinery/shuttle_scrambler/proc/dump_loot(mob/user)
if(credits_stored) // Prevents spamming empty holochips
if(credits_stored) // Prevents spamming empty holochips
new /obj/item/holochip(drop_location(), credits_stored)
to_chat(user,"<span class='notice'>You retrieve the siphoned credits!</span>")
credits_stored = 0
@@ -161,10 +191,8 @@
STOP_PROCESSING(SSobj,src)
/obj/machinery/shuttle_scrambler/update_icon_state()
if(active)
icon_state = "dominator-blue"
else
icon_state = "dominator"
icon_state = active ? "dominator-blue" : "dominator"
return ..()
/obj/machinery/shuttle_scrambler/Destroy()
toggle_off()
@@ -175,7 +203,6 @@
shuttleId = "pirateship"
icon_screen = "syndishuttle"
icon_keyboard = "syndie_key"
resistance_flags = INDESTRUCTIBLE
light_color = LIGHT_COLOR_RED
possible_destinations = "pirateship_away;pirateship_home;pirateship_custom"
@@ -183,7 +210,6 @@
name = "pirate shuttle navigation computer"
desc = "Used to designate a precise transit location for the pirate shuttle."
shuttleId = "pirateship"
resistance_flags = INDESTRUCTIBLE
lock_override = CAMERA_LOCK_STATION
shuttlePortId = "pirateship_custom"
x_offset = 9
@@ -193,41 +219,20 @@
/obj/docking_port/mobile/pirate
name = "pirate shuttle"
id = "pirateship"
var/engines_cooling = FALSE
var/engine_cooldown = 3 MINUTES
/obj/docking_port/mobile/pirate/getStatusText()
. = ..()
if(engines_cooling)
return "[.] - Engines cooling."
/obj/docking_port/mobile/pirate/initiate_docking(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
. = ..()
if(. == DOCKING_SUCCESS && !is_reserved_level(new_dock.z))
engines_cooling = TRUE
addtimer(CALLBACK(src,.proc/reset_cooldown),engine_cooldown,TIMER_UNIQUE)
/obj/docking_port/mobile/pirate/proc/reset_cooldown()
engines_cooling = FALSE
/obj/docking_port/mobile/pirate/canMove()
if(engines_cooling)
return FALSE
return ..()
rechargeTime = 3 MINUTES
/obj/machinery/suit_storage_unit/pirate
suit_type = /obj/item/clothing/suit/space
helmet_type = /obj/item/clothing/head/helmet/space
mask_type = /obj/item/clothing/mask/breath
storage_type = /obj/item/tank/jetpack/void
// storage_type = /obj/item/tank/internals/oxygen
/obj/machinery/loot_locator
name = "Booty Locator"
desc = "This sophisticated machine scans the nearby space for items of value."
icon = 'icons/obj/machines/research.dmi'
icon_state = "tdoppler"
resistance_flags = INDESTRUCTIBLE
density = TRUE
var/cooldown = 300
var/next_use = 0
@@ -261,23 +266,20 @@
name = "cargo hold pad"
icon = 'icons/obj/telescience.dmi'
icon_state = "lpad-idle-o"
resistance_flags = INDESTRUCTIBLE
var/idle_state = "lpad-idle-o"
var/warmup_state = "lpad-idle"
var/sending_state = "lpad-beam"
var/cargo_hold_id
/obj/machinery/piratepad/multitool_act(mob/living/user, obj/item/I)
if(I.tool_behaviour == TOOL_MULTITOOL)
/obj/machinery/piratepad/multitool_act(mob/living/user, obj/item/multitool/I)
. = ..()
if (istype(I))
to_chat(user, "<span class='notice'>You register [src] in [I]s buffer.</span>")
I.buffer = src
return TRUE
/obj/machinery/computer/piratepad_control
name = "cargo hold control terminal"
resistance_flags = INDESTRUCTIBLE
ui_x = 600
ui_y = 230
var/status_report = "Ready for delivery."
var/obj/machinery/piratepad/pad
var/warmup_time = 100
@@ -291,8 +293,9 @@
..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/computer/piratepad_control/multitool_act(mob/living/user, obj/item/I)
if(I.tool_behaviour == TOOL_MULTITOOL && istype(I.buffer,/obj/machinery/piratepad))
/obj/machinery/computer/piratepad_control/multitool_act(mob/living/user, obj/item/multitool/I)
. = ..()
if (istype(I) && istype(I.buffer,/obj/machinery/piratepad))
to_chat(user, "<span class='notice'>You link [src] with [I.buffer] in [I] buffer.</span>")
pad = I.buffer
return TRUE
@@ -322,7 +325,8 @@
return data
/obj/machinery/computer/piratepad_control/ui_act(action, params)
if(..())
. = ..()
if(.)
return
if(!pad)
return
@@ -341,6 +345,7 @@
/obj/machinery/computer/piratepad_control/proc/recalc()
if(sending)
return
status_report = "Predicted value: "
var/value = 0
var/datum/export_report/ex = new
@@ -386,11 +391,13 @@
for(var/datum/export/E in ex.total_amount)
total_report.total_amount[E] += ex.total_amount[E]
total_report.total_value[E] += ex.total_value[E]
// playsound(loc, 'sound/machines/wewewew.ogg', 70, TRUE)
points += value
if(!value)
status_report += "Nothing"
pad.visible_message("<span class='notice'>[pad] activates!</span>")
flick(pad.sending_state,pad)
pad.icon_state = pad.idle_state
@@ -400,16 +407,18 @@
if(sending)
return
sending = TRUE
status_report = "Sending..."
status_report = "Sending... "
pad.visible_message("<span class='notice'>[pad] starts charging up.</span>")
pad.icon_state = pad.warmup_state
sending_timer = addtimer(CALLBACK(src,.proc/send),warmup_time, TIMER_STOPPABLE)
/obj/machinery/computer/piratepad_control/proc/stop_sending()
/obj/machinery/computer/piratepad_control/proc/stop_sending(custom_report)
if(!sending)
return
sending = FALSE
status_report = "Idle"
status_report = "Ready for delivery."
if(custom_report)
status_report = custom_report
pad.icon_state = pad.idle_state
deltimer(sending_timer)
+3 -4
View File
@@ -8,15 +8,14 @@
announceWhen = 50
endWhen = 20
var/list/area/areasToOpen = list()
var/list/potential_areas = list(/area/bridge,
/area/engine,
var/list/potential_areas = list(/area/command,
/area/engineering,
/area/medical,
/area/security,
/area/quartermaster,
/area/cargo,
/area/science)
var/severity = 1
/datum/round_event/grey_tide/setup()
announceWhen = rand(50, 60)
endWhen = rand(20, 30)
+2 -2
View File
@@ -71,12 +71,12 @@
var/list/safe_area_types = typecacheof(list(
/area/ai_monitored/turret_protected/ai,
/area/ai_monitored/turret_protected/ai_upload,
/area/engine,
/area/engineering,
/area/shuttle)
)
///Subtypes from the above that actually should explode.
var/list/unsafe_area_subtypes = typecacheof(list(/area/engine/break_room))
var/list/unsafe_area_subtypes = typecacheof(list(/area/engineering/break_room))
allowed_areas = make_associative(GLOB.the_station_areas) - safe_area_types + unsafe_area_subtypes
var/list/possible_areas = typecache_filter_list(GLOB.sortedAreas,allowed_areas)
if (length(possible_areas))
+1
View File
@@ -118,6 +118,7 @@
genes = list(/datum/plant_gene/trait/repeated_harvest)
mutatelist = list(/obj/item/seeds/replicapod)
reagents_add = list(/datum/reagent/consumable/nutriment/vitamin = 0.04, /datum/reagent/consumable/nutriment = 0.1)
seed_flags = null
/obj/item/reagent_containers/food/snacks/grown/cabbage
seed = /obj/item/seeds/cabbage
+1
View File
@@ -12,6 +12,7 @@
default_priority = 90
icon_state = "eal"
chooseable_roundstart = TRUE
/datum/language/machine/get_random_name()
if(prob(70))
+1
View File
@@ -6,6 +6,7 @@
exclaim_verb = "poofs loudly"
whisper_verb = "puffs quietly"
key = "y"
flags = TONGUELESS_SPEECH
sentence_chance = 0
default_priority = 80
syllables = list("poof", "pff", "pFfF", "piff", "puff", "pooof", "pfffff", "piffpiff", "puffpuff", "poofpoof", "pifpafpofpuf")
+1
View File
@@ -6,6 +6,7 @@
ask_verb = "inquires"
exclaim_verb = "declares"
key = "h"
flags = TONGUELESS_SPEECH
space_chance = 20
syllables = list(
"fii", "sii", "rii", "rel", "maa", "ala", "san", "tol", "tok", "dia", "eres",
@@ -5,7 +5,8 @@
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
requires_power = FALSE
has_gravity = STANDARD_GRAVITY
valid_territory = FALSE
area_flags = BLOBS_ALLOWED | UNIQUE_AREA
flags_1 = CAN_BE_DIRTY_1
//Survival Capsule
/obj/item/survivalcapsule
@@ -981,7 +981,18 @@
switch(random)
if(1)
to_chat(user, "<span class='danger'>Your appearance morphs to that of a very small humanoid ash dragon! You get to look like a freak without the cool abilities.</span>")
H.dna.features = list("mcolor" = "A02720", "tail_lizard" = "Dark Tiger", "tail_human" = "None", "snout" = "Sharp", "horns" = "Curled", "ears" = "None", "wings" = "None", "frills" = "None", "spines" = "Long", "body_markings" = "Dark Tiger Body", "legs" = "Digitigrade")
H.dna.features["mcolor"] = "A02720"
H.dna.features["tail_lizard"] = "Dark Tiger"
H.dna.features["tail_human"] = "None"
H.dna.features["mam_snout"] = "Sharp"
H.dna.features["horns"] = "Curled"
H.dna.features["ears"] = "None"
H.dna.features["wings"] = "None"
H.dna.features["frills"] = "None"
H.dna.features["spines"] = "Long"
H.dna.features["body_markings"] = "Dark Tiger Body"
H.dna.features["legs"] = "Digitigrade"
H.dna.features["taur_body"] = "None"
H.left_eye_color = "fee5a3"
H.right_eye_color = "fee5a3"
H.set_species(/datum/species/lizard)
+107 -40
View File
@@ -16,29 +16,36 @@
singular_name = "ore chunk"
var/points = 0 //How many points this ore gets you from the ore redemption machine
var/refined_type = null //What this ore defaults to being refined into
var/mine_experience = 5 //How much experience do you get for mining this ore?
novariants = TRUE // Ore stacks handle their icon updates themselves to keep the illusion that there's more going
var/list/stack_overlays
var/scan_state = "" //Used by mineral turfs for their scan overlay.
var/spreadChance = 0 //Also used by mineral turfs for spreading veins
/obj/item/stack/ore/update_overlays()
. = ..()
var/difference = min(ORESTACK_OVERLAYS_MAX, amount) - (LAZYLEN(stack_overlays)+1)
if(difference == 0)
if(!difference)
return
else if(difference < 0 && LAZYLEN(stack_overlays)) //amount < stack_overlays, remove excess.
if (LAZYLEN(stack_overlays)-difference <= 0)
if(difference < 0 && LAZYLEN(stack_overlays)) //amount < stack_overlays, remove excess.
if(LAZYLEN(stack_overlays)-difference <= 0)
stack_overlays = null
else
stack_overlays.len += difference
else if(difference > 0) //amount > stack_overlays, add some.
return
stack_overlays.len += difference
else //amount > stack_overlays, add some.
for(var/i in 1 to difference)
var/mutable_appearance/newore = mutable_appearance(icon, icon_state)
newore.pixel_x = rand(-8,8)
newore.pixel_y = rand(-8,8)
LAZYADD(stack_overlays, newore)
if (stack_overlays)
if(stack_overlays)
. += stack_overlays
/obj/item/stack/ore/welder_act(mob/living/user, obj/item/I)
..()
if(!refined_type)
return TRUE
@@ -65,11 +72,16 @@
/obj/item/stack/ore/uranium
name = "uranium ore"
icon_state = "Uranium ore"
item_state = "Uranium ore"
// inhand_icon_state = "Uranium ore"
singular_name = "uranium ore chunk"
points = 30
// material_flags = MATERIAL_NO_EFFECTS
custom_materials = list(/datum/material/uranium=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/mineral/uranium
mine_experience = 6
scan_state = "rock_Uranium"
spreadChance = 5
// merge_type = /obj/item/stack/ore/uranium
/obj/item/stack/ore/iron
name = "iron ore"
@@ -79,6 +91,10 @@
points = 1
custom_materials = list(/datum/material/iron=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/metal
mine_experience = 1
scan_state = "rock_Iron"
spreadChance = 20
// merge_type = /obj/item/stack/ore/metal
/obj/item/stack/ore/glass
name = "sand pile"
@@ -89,10 +105,13 @@
custom_materials = list(/datum/material/glass=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/glass
w_class = WEIGHT_CLASS_TINY
mine_experience = 0 //its sand
// merge_type = /obj/item/stack/ore/glass
GLOBAL_LIST_INIT(sand_recipes, list(\
new/datum/stack_recipe("sandstone", /obj/item/stack/sheet/mineral/sandstone, 1, 1, 50),\
))
new /datum/stack_recipe("sandstone", /obj/item/stack/sheet/mineral/sandstone, 1, 1, 50)
))
/obj/item/stack/ore/glass/get_main_recipes()
. = ..()
@@ -111,7 +130,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
return ..()
var/mob/living/carbon/human/poorsod = M
visible_message("<span class='danger'>[user] throws the sand at [poorsod]'s face!</span>")
if(ishuman(user))
if(ishuman(user) && prob(80))
var/mob/living/carbon/human/sayer = user
sayer.forcesay("POCKET SAAND!!")
eyesand(poorsod)
@@ -133,7 +152,6 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
C.forcesay("*scream")
qdel(src)
/obj/item/stack/ore/glass/ex_act(severity, target)
if (severity == EXPLODE_NONE)
return
@@ -144,15 +162,21 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
icon_state = "volcanic_sand"
icon_state = "volcanic_sand"
singular_name = "volcanic ash pile"
mine_experience = 0
// merge_type = /obj/item/stack/ore/glass/basalt
/obj/item/stack/ore/plasma
name = "plasma ore"
icon_state = "Plasma ore"
item_state = "Plasma ore"
icon_state = "Plasma ore"
singular_name = "plasma ore chunk"
points = 15
custom_materials = list(/datum/material/plasma=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/mineral/plasma
mine_experience = 5
scan_state = "rock_Plasma"
spreadChance = 8
// merge_type = /obj/item/stack/ore/plasma
/obj/item/stack/ore/plasma/welder_act(mob/living/user, obj/item/I)
to_chat(user, "<span class='warning'>You can't hit a high enough temperature to smelt [src] properly!</span>")
@@ -164,8 +188,12 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
item_state = "Silver ore"
singular_name = "silver ore chunk"
points = 16
mine_experience = 3
custom_materials = list(/datum/material/silver=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/mineral/silver
scan_state = "rock_Silver"
spreadChance = 5
// merge_type = /obj/item/stack/ore/silver
/obj/item/stack/ore/gold
name = "gold ore"
@@ -173,8 +201,12 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
icon_state = "Gold ore"
singular_name = "gold ore chunk"
points = 18
mine_experience = 5
custom_materials = list(/datum/material/gold=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/mineral/gold
scan_state = "rock_Gold"
spreadChance = 5
// merge_type = /obj/item/stack/ore/gold
/obj/item/stack/ore/diamond
name = "diamond ore"
@@ -184,6 +216,9 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
points = 50
custom_materials = list(/datum/material/diamond=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/mineral/diamond
mine_experience = 10
scan_state = "rock_Diamond"
// merge_type = /obj/item/stack/ore/diamond
/obj/item/stack/ore/bananium
name = "bananium ore"
@@ -193,6 +228,9 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
points = 60
custom_materials = list(/datum/material/bananium=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/mineral/bananium
mine_experience = 15
scan_state = "rock_Bananium"
// merge_type = /obj/item/stack/ore/bananium
/obj/item/stack/ore/titanium
name = "titanium ore"
@@ -202,6 +240,10 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
points = 50
custom_materials = list(/datum/material/titanium=MINERAL_MATERIAL_AMOUNT)
refined_type = /obj/item/stack/sheet/mineral/titanium
mine_experience = 3
scan_state = "rock_Titanium"
spreadChance = 5
// merge_type = /obj/item/stack/ore/titanium
/obj/item/stack/ore/slag
name = "slag"
@@ -209,6 +251,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
icon_state = "slag"
item_state = "slag"
singular_name = "slag chunk"
// merge_type = /obj/item/stack/ore/slag
/obj/item/gibtonite
name = "gibtonite ore"
@@ -235,7 +278,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
/obj/item/gibtonite/attackby(obj/item/I, mob/user, params)
if(!wires && istype(I, /obj/item/assembly/igniter))
user.visible_message("[user] attaches [I] to [src].", "<span class='notice'>You attach [I] to [src].</span>")
user.visible_message("<span class='notice'>[user] attaches [I] to [src].</span>", "<span class='notice'>You attach [I] to [src].</span>")
wires = new /datum/wires/explosive/gibtonite(src)
attacher = key_name(user)
qdel(I)
@@ -255,7 +298,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
primed = FALSE
if(det_timer)
deltimer(det_timer)
user.visible_message("The chain reaction was stopped! ...The ore's quality looks diminished.", "<span class='notice'>You stopped the chain reaction. ...The ore's quality looks diminished.</span>")
user.visible_message("<span class='notice'>The chain reaction stopped! ...The ore's quality looks diminished.</span>", "<span class='notice'>You stopped the chain reaction. ...The ore's quality looks diminished.</span>")
icon_state = "Gibtonite ore"
quality = GIBTONITE_QUALITY_LOW
return
@@ -269,34 +312,29 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
/obj/item/gibtonite/bullet_act(obj/item/projectile/P)
GibtoniteReaction(P.firer)
return ..()
. = ..()
/obj/item/gibtonite/ex_act()
GibtoniteReaction(null, 1)
/obj/item/gibtonite/proc/GibtoniteReaction(mob/user, triggered_by = 0)
if(!primed)
primed = TRUE
playsound(src,'sound/effects/hit_on_shattered_glass.ogg',50,1)
playsound(src,'sound/effects/hit_on_shattered_glass.ogg',50,TRUE)
icon_state = "Gibtonite active"
var/turf/bombturf = get_turf(src)
var/notify_admins = 0
var/notify_admins = FALSE
if(z != 5)//Only annoy the admins ingame if we're triggered off the mining zlevel
notify_admins = 1
notify_admins = TRUE
if(notify_admins)
if(triggered_by == 1)
message_admins("An explosion has triggered a [name] to detonate at [ADMIN_VERBOSEJMP(bombturf)].")
else if(triggered_by == 2)
message_admins("A signal has triggered a [name] to detonate at [ADMIN_VERBOSEJMP(bombturf)]. Igniter attacher: [ADMIN_LOOKUPFLW(attacher)]")
else
message_admins("[ADMIN_LOOKUPFLW(attacher)] has triggered a [name] to detonate at [ADMIN_VERBOSEJMP(bombturf)].")
if(triggered_by == 1)
log_game("An explosion has primed a [name] for detonation at [AREACOORD(bombturf)]")
message_admins("An explosion has triggered a [name] to detonate at [ADMIN_VERBOSEJMP(bombturf)].")
else if(triggered_by == 2)
log_game("A signal has primed a [name] for detonation at [AREACOORD(bombturf)]. Igniter attacher: [key_name(attacher)].")
if(notify_admins)
message_admins("A signal has triggered a [name] to detonate at [ADMIN_VERBOSEJMP(bombturf)]. Igniter attacher: [ADMIN_LOOKUPFLW(attacher)]")
var/bomb_message = "A signal has primed a [name] for detonation at [AREACOORD(bombturf)]. Igniter attacher: [key_name(attacher)]."
log_game(bomb_message)
GLOB.bombers += bomb_message
else
user.visible_message("<span class='warning'>[user] strikes \the [src], causing a chain reaction!</span>", "<span class='danger'>You strike \the [src], causing a chain reaction.</span>")
log_game("[key_name(user)] has primed a [name] for detonation at [AREACOORD(bombturf)]")
@@ -313,10 +351,10 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
explosion(src,0,1,3,adminlog = notify_admins)
qdel(src)
/obj/item/stack/ore/Initialize()
/obj/item/stack/ore/Initialize(mapload, new_amount, merge = TRUE)
. = ..()
pixel_x = rand(0,16)-8
pixel_y = rand(0,8)-8
pixel_x = initial(pixel_x) + rand(0, 16) - 8
pixel_y = initial(pixel_y) + rand(0, 8) - 8
/obj/item/stack/ore/ex_act(severity, target)
if (!severity || severity >= 2)
@@ -350,8 +388,8 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
. = ..()
coinflip = pick(sideslist)
icon_state = "coin_[coinflip]"
pixel_x = rand(0,16)-8
pixel_y = rand(0,8)-8
pixel_x = initial(pixel_x) + rand(0, 16) - 8
pixel_y = initial(pixel_y) + rand(0, 8) - 8
/obj/item/coin/set_custom_materials(list/materials, multiplier = 1)
. = ..()
@@ -377,6 +415,8 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
user.visible_message("<span class='suicide'>\the [src] lands on [coinflip]! [user] promptly falls over, dead!</span>")
user.adjustOxyLoss(200)
user.death(0)
// user.set_suicide(TRUE)
user.suicide_log()
else
user.visible_message("<span class='suicide'>\the [src] lands on [coinflip]! [user] keeps on living!</span>")
@@ -386,11 +426,12 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
/obj/item/coin/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/CC = W
if(string_attached)
to_chat(user, "<span class='warning'>There already is a string attached to this coin!</span>")
return
if (W.use_tool(src, user, 0, 1, skill_gain_mult = BARE_USE_TOOL_MULT))
if (CC.use(1))
add_overlay("coin_string_overlay")
string_attached = 1
to_chat(user, "<span class='notice'>You attach a string to the coin.</span>")
@@ -412,6 +453,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
..()
/obj/item/coin/wirecutter_act(mob/living/user, obj/item/I)
..()
if(!string_attached)
return TRUE
@@ -430,13 +472,13 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
flick("coin_[coinflip]_flip", src)
coinflip = pick(sideslist)
icon_state = "coin_[coinflip]"
playsound(user.loc, 'sound/items/coinflip.ogg', 50, 1)
playsound(user.loc, 'sound/items/coinflip.ogg', 50, TRUE)
var/oldloc = loc
sleep(15)
if(loc == oldloc && user && !user.incapacitated())
user.visible_message("[user] has flipped [src]. It lands on [coinflip].", \
"<span class='notice'>You flip [src]. It lands on [coinflip].</span>", \
"<span class='italics'>You hear the clattering of loose change.</span>")
user.visible_message("<span class='notice'>[user] flips [src]. It lands on [coinflip].</span>", \
"<span class='notice'>You flip [src]. It lands on [coinflip].</span>", \
"<span class='hear'>You hear the clattering of loose change.</span>")
return TRUE//did the coin flip? useful for suicide_act
/obj/item/coin/gold
@@ -486,4 +528,29 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
/obj/item/coin/iron
/obj/item/coin/gold/debug
custom_materials = list(/datum/material/gold = 400)
desc = "If you got this somehow, be aware that it will dust you. Almost certainly."
/obj/item/coin/gold/debug/attack_self(mob/user)
if(cooldown < world.time)
if(string_attached) //does the coin have a wire attached
to_chat(user, "<span class='warning'>The coin won't flip very well with something attached!</span>" )
return FALSE//do not flip the coin
cooldown = world.time + 15
flick("coin_[coinflip]_flip", src)
coinflip = pick(sideslist)
icon_state = "coin_[coinflip]"
playsound(user.loc, 'sound/items/coinflip.ogg', 50, TRUE)
var/oldloc = loc
sleep(15)
if(loc == oldloc && user && !user.incapacitated())
user.visible_message("<span class='notice'>[user] flips [src]. It lands on [coinflip].</span>", \
"<span class='notice'>You flip [src]. It lands on [coinflip].</span>", \
"<span class='hear'>You hear the clattering of loose change.</span>")
SSeconomy.fire()
// to_chat(user,"<span class='bounty'>[SSeconomy.inflation_value()] is the inflation value.</span>")
to_chat(user, "<span class='bounty'>Luckily, economical inflation is not yet included. So no, you cannot predict the market with this.</span>")
return TRUE//did the coin flip? useful for suicide_act
#undef ORESTACK_OVERLAYS_MAX
@@ -905,6 +905,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
mob_eye.observers |= src
mob_eye.hud_used.show_hud(mob_eye.hud_used.hud_version, src)
observetarget = mob_eye
mob_eye.investigate_log("was observed by [src] as a ghost.", INVESTIGATE_GHOST)
/mob/dead/observer/verb/register_pai_candidate()
set category = "Ghost"
@@ -47,6 +47,7 @@
owner.cut_overlays() //we dont show our normal sprite, we show a puddle sprite
var/obj/effect/puddle_effect = new puddle_into_effect(get_turf(owner), owner.dir)
puddle_effect.color = mutcolor
puddle_effect.transform = H.transform //copy mob size for consistent meltdown appearance
H.Stun(in_transformation_duration, ignore_canstun = TRUE) //cant move while transforming
//series of traits that make up the puddle behaviour
@@ -75,6 +76,7 @@
puddle_overlay.color = mutcolor
tracked_overlay = puddle_overlay
owner.add_overlay(puddle_overlay)
owner.update_antag_overlays()
transforming = FALSE
UpdateButtonIcon()
@@ -89,6 +91,7 @@
H.cut_overlay(tracked_overlay)
var/obj/effect/puddle_effect = new puddle_from_effect(get_turf(owner), owner.dir)
puddle_effect.color = tracked_overlay.color
puddle_effect.transform = H.transform //copy mob size for consistent transform size
H.Stun(out_transformation_duration, ignore_canstun = TRUE)
sleep(out_transformation_duration)
REMOVE_TRAIT(H, TRAIT_PARALYSIS_L_ARM, SLIMEPUDDLE_TRAIT)
@@ -106,5 +109,6 @@
is_puddle = FALSE
if(squeak)
squeak.RemoveComponent()
H.regenerate_icons()
transforming = FALSE
UpdateButtonIcon()
@@ -62,9 +62,12 @@
if((C.dna.features["spines"] != "None" ) && (C.dna.features["tail_lizard"] == "None")) //tbh, it's kinda ugly for them not to have a tail yet have floating spines
C.dna.features["tail_lizard"] = "Smooth"
C.update_body()
if(C.dna.features["legs"] != "digitigrade")
C.dna.features["legs"] = "digitigrade"
if(C.dna.features["legs"] != "Digitigrade")
C.dna.features["legs"] = "Digitigrade"
for(var/obj/item/bodypart/leggie in C.bodyparts)
if(leggie.body_zone == BODY_ZONE_L_LEG || leggie.body_zone == BODY_ZONE_R_LEG)
leggie.update_limb(FALSE, C)
if(C.dna.features["mam_snouts"] != "Sharp")
C.dna.features["mam_snouts"] = "Sharp"
C.update_body()
return ..()
@@ -59,7 +59,7 @@
C.dust(FALSE, TRUE)
var/area/A = get_area(C)
if(istype(A, /area/chapel) && C.mind?.assigned_role != "Chaplain")
if(istype(A, /area/service/chapel) && C.mind?.assigned_role != "Chaplain")
to_chat(C, "<span class='danger'>You don't belong here!</span>")
C.adjustFireLoss(5)
C.adjust_fire_stacks(6)
@@ -100,10 +100,29 @@ There are several things that need to be remembered:
update_mutations_overlay()
//damage overlays
update_damage_overlays()
//antagonism
update_antag_overlays()
/* --------------------------------------- */
//vvvvvv UPDATE_INV PROCS vvvvvv
/mob/living/carbon/human/update_antag_overlays()
remove_overlay(ANTAG_LAYER)
var/datum/antagonist/cult/D = src?.mind?.has_antag_datum(/datum/antagonist/cult) //check for cultism
if(D && D.cult_team?.cult_ascendent == TRUE)
var/istate = pick("halo1","halo2","halo3","halo4","halo5","halo6")
var/mutable_appearance/new_cult_overlay = mutable_appearance('icons/effects/32x64.dmi', istate, -ANTAG_LAYER)
overlays_standing[ANTAG_LAYER] = new_cult_overlay
var/datum/antagonist/clockcult/C = src?.mind?.has_antag_datum(/datum/antagonist/clockcult) //check for clockcultism - surely one can't be both cult and clockie, right?
if(C)
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
if(G && G.active && ishuman(src))
var/mutable_appearance/new_cult_overlay = mutable_appearance('icons/effects/genetics.dmi', "servitude", -ANTAG_LAYER)
overlays_standing[ANTAG_LAYER] = new_cult_overlay
apply_overlay(ANTAG_LAYER)
/mob/living/carbon/human/update_inv_w_uniform()
if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER))
remove_overlay(UNIFORM_LAYER)
@@ -92,12 +92,9 @@
name = "ai_multicam_room"
icon_state = "ai_camera_room"
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
valid_territory = FALSE
ambientsounds = list()
blob_allowed = FALSE
noteleport = TRUE
hidden = TRUE
safe = TRUE
area_flags = NOTELEPORT | HIDDEN_AREA | UNIQUE_AREA
ambientsounds = null
flags_1 = NONE
GLOBAL_DATUM(ai_camera_room_landmark, /obj/effect/landmark/ai_multicam_room)
@@ -29,7 +29,7 @@
verb_yell = "buzzes intensely"
emote_see = list("buzzes.", "makes a loud buzz.", "rolls several times.", "buzzes happily.")
speak_chance = 1
unique_name = TRUE
unique_name = FALSE
/mob/living/simple_animal/pet/bumbles/Initialize()
. = ..()
+3
View File
@@ -69,3 +69,6 @@
/mob/proc/update_inv_ears()
return
/mob/proc/update_antag_overlays()
return
@@ -25,9 +25,15 @@
/obj/item/modular_computer/laptop/examine(mob/user)
. = ..()
. += "<span class='notice'>Drag it in your hand to pick it up.</span>"
if(screen_on)
. += "<span class='notice'>Alt-click to close it.</span>"
. += "<span class='notice'>Drag it in your hand or on yourself to pick it up.</span>"
. += "<span class='notice'>Ctrl+Shift-click to [screen_on ? "close" : "open"] it.</span>"
var/obj/item/computer_hardware/card_slot/card_slot = all_components[MC_CARD]
var/obj/item/computer_hardware/card_slot/card_slot2 = all_components[MC_CARD2]
if(card_slot || card_slot2)
if(card_slot.stored_card)
. += "<span class='notice'>\The [src] has \a [card_slot] with an id inside, Alt-click to remove the id.</span>"
if(card_slot2.stored_card)
. += "<span class='notice'>\The [src] has \a [card_slot2] with an id inside, Alt-click to remove the id.</span>"
/obj/item/modular_computer/laptop/Initialize()
. = ..()
@@ -62,14 +68,14 @@
try_toggle_open(usr)
/obj/item/modular_computer/laptop/MouseDrop(obj/over_object, src_location, over_location)
. = ..()
if(over_object == usr || over_object == src)
try_toggle_open(usr)
return
if(istype(over_object, /obj/screen/inventory/hand))
if(istype(over_object, /obj/screen/inventory/hand) || over_object == usr)
var/obj/screen/inventory/hand/H = over_object
var/mob/M = usr
if(!istype(over_object, /obj/screen/inventory/hand))
M.put_in_active_hand(src)
return
if(M.stat != CONSCIOUS || M.restrained())
return
if(!isturf(loc) || !Adjacent(M))
@@ -77,11 +83,9 @@
M.put_in_hand(src, H.held_index)
/obj/item/modular_computer/laptop/on_attack_hand(mob/user)
. = ..()
if(!.)
return
if(screen_on && isturf(loc))
return attack_self(user)
..()
/obj/item/modular_computer/laptop/proc/try_toggle_open(mob/living/user)
if(issilicon(user))
@@ -94,11 +98,8 @@
toggle_open(user)
/obj/item/modular_computer/laptop/AltClick(mob/user)
if(screen_on) // Close it.
try_toggle_open(user)
else
return ..()
/obj/item/modular_computer/laptop/CtrlShiftClick(mob/user)
try_toggle_open(user)
/obj/item/modular_computer/laptop/proc/toggle_open(mob/living/user=null)
if(screen_on)
@@ -1,4 +1,4 @@
/area/engine/engineering/poweralert(state, source)
/area/engineering/main/poweralert(state, source)
if (state != poweralm)
investigate_log("has a power alarm!", INVESTIGATE_SINGULO)
..()
@@ -139,9 +139,12 @@
/obj/machinery/computer/pandemic/proc/eject_beaker()
if(beaker)
var/obj/item/reagent_containers/B = beaker
beaker.forceMove(drop_location())
beaker = null
update_icon()
return B
return null
/obj/machinery/computer/pandemic/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
@@ -237,14 +240,17 @@
. = TRUE //no afterattack
if(stat & (NOPOWER|BROKEN))
return
var/obj/item/reagent_containers/B
if(beaker)
to_chat(user, "<span class='warning'>A container is already loaded into [src]!</span>")
return
B = eject_beaker() //now with 100% more swapping
if(!user.transferItemToLoc(I, src))
return
if(B)
if(user && Adjacent(user) && user.can_hold_items())
user.put_in_hands(B)
beaker = I
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
if(B) to_chat(user, "<span class='notice'>You remove [B] and insert [I] into [src].</span>")
else to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
update_icon()
else
return ..()
@@ -330,7 +330,7 @@
name = "Hollow Water"
description = "An ubiquitous chemical substance that is composed of hydrogen and oxygen, but it looks kinda hollow."
color = "#88878777"
taste_description = "emptyiness"
taste_description = "emptiness"
/datum/reagent/water/holywater
@@ -329,9 +329,7 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337)
icon_state = "hilbertshotel"
requires_power = FALSE
has_gravity = TRUE
noteleport = TRUE
hidden = TRUE
unique = FALSE
area_flags = NOTELEPORT | HIDDEN_AREA
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
ambientsounds = list('sound/ambience/servicebell.ogg')
var/roomnumber = 0
@@ -408,8 +406,7 @@ GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337)
icon_state = "hilbertshotel"
requires_power = FALSE
has_gravity = TRUE
noteleport = TRUE
hidden = TRUE
area_flags = NOTELEPORT | HIDDEN_AREA
/obj/item/abstracthotelstorage
anchored = TRUE
@@ -21,10 +21,12 @@
/obj/effect/proc_holder/spell/targeted/area_teleport/before_cast(list/targets)
var/area/U = get_area(usr)
if(U.noteleport && !istype(U, /area/wizard_station)) // Wizard den special check for those complaining about being unable to tele on station.
if((U.area_flags & NOTELEPORT) && !istype(U, /area/wizard_station)) // Wizard den special check for those complaining about being unable to tele on station.
to_chat(usr, "<span class='warning'>Unseen forces prevent you from casting this spell in this area</span>")
return
var/A
var/A = null
if(!randomise_selection)
A = input("Area to teleport to", "Teleport", A) as null|anything in GLOB.teleportlocs
else
+17 -13
View File
@@ -4,7 +4,7 @@
return TRUE
//Dismember a limb
/obj/item/bodypart/proc/dismember(dam_type = BRUTE, silent=TRUE)
/obj/item/bodypart/proc/dismember(dam_type = BRUTE, silent=TRUE, harmless=FALSE)
if(!owner)
return FALSE
var/mob/living/carbon/C = owner
@@ -14,24 +14,28 @@
return FALSE
if(HAS_TRAIT(C, TRAIT_NODISMEMBER))
return FALSE
var/obj/item/bodypart/affecting = C.get_bodypart(BODY_ZONE_CHEST)
affecting.receive_damage(clamp(brute_dam/2 * affecting.body_damage_coeff, 15, 50), clamp(burn_dam/2 * affecting.body_damage_coeff, 0, 50), wound_bonus=CANT_WOUND) //Damage the chest based on limb's existing damage
if(!harmless)
var/obj/item/bodypart/affecting = C.get_bodypart(BODY_ZONE_CHEST)
affecting.receive_damage(clamp(brute_dam/2 * affecting.body_damage_coeff, 15, 50), clamp(burn_dam/2 * affecting.body_damage_coeff, 0, 50), wound_bonus=CANT_WOUND) //Damage the chest based on limb's existing damage
if(!silent)
C.visible_message("<span class='danger'><B>[C]'s [name] is violently dismembered!</B></span>")
C.emote("scream")
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "dismembered", /datum/mood_event/dismembered)
if(!harmless)
C.emote("scream")
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "dismembered", /datum/mood_event/dismembered)
else C.emote("pain")
drop_limb()
C.update_equipment_speed_mods() // Update in case speed affecting item unequipped by dismemberment
C.bleed(40)
if(!harmless) C.bleed(40)
if(QDELETED(src)) //Could have dropped into lava/explosion/chasm/whatever
return TRUE
if(dam_type == BURN)
burn()
return TRUE
add_mob_blood(C)
C.bleed(rand(20, 40))
if(!harmless)
if(dam_type == BURN)
burn()
return TRUE
add_mob_blood(C)
C.bleed(rand(20, 40))
var/direction = pick(GLOB.cardinals)
var/t_range = rand(2,max(throw_range/2, 2))
var/turf/target_turf = get_turf(src)
@@ -45,12 +49,12 @@
throw_at(target_turf, throw_range, throw_speed)
return TRUE
/obj/item/bodypart/head/dismember()
/obj/item/bodypart/head/dismember(dam_type = BRUTE, silent=TRUE, harmless=FALSE)
if(HAS_TRAIT(owner, TRAIT_NODECAP))
return FALSE
..()
/obj/item/bodypart/chest/dismember()
/obj/item/bodypart/chest/dismember(dam_type = BRUTE, silent=TRUE, harmless=FALSE)
if(!owner)
return FALSE
var/mob/living/carbon/C = owner
+7 -1
View File
@@ -8,7 +8,7 @@
target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list(BODY_ZONE_CHEST)
requires_bodypart_type = BODYPART_ORGANIC
requires_bodypart_type = NONE
replaced_by = /datum/surgery
ignore_clothes = TRUE
var/healing_step_type
@@ -21,6 +21,12 @@
healing_step_type, //hehe cheeky
/datum/surgery_step/close)
/datum/surgery/healing/can_start(mob/user, mob/living/carbon/target, obj/item/tool)
for(var/obj/item/bodypart/B in target.bodyparts)
if(B.is_organic_limb(TRUE))
return ..()
/datum/surgery_step/heal
name = "repair body"
implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 65, /obj/item/pen = 55)
@@ -7,6 +7,12 @@
When adding new entries to the file, please keep them sorted by category.
*/
/datum/uplink_item/stealthy_weapons/telescopicbat
name = "Telescopic Baseball Bat"
desc = "A robust telescopic baseball bat that hits like a truck and can be consealed when collapsed."
item = /obj/item/melee/baseball_bat/telescopic
cost = 2
/datum/uplink_item/stealthy_weapons/combatglovesplus
name = "Combat Gloves Plus"
desc = "A pair of gloves that are fireproof and shock resistant, however unlike the regular Combat Gloves this one uses nanotechnology \
+3 -3
View File
@@ -29,9 +29,9 @@
/obj/item/clothing/under/misc/poly_tanktop/female = 3,
/obj/item/autosurgeon/penis = 3,
/obj/item/autosurgeon/testicles = 3,
/obj/item/storage/pill_bottle/penis_enlargement = 5,
/obj/item/storage/pill_bottle/breast_enlargement = 5,
/obj/item/reagent_containers/glass/bottle/crocin = 5,
/obj/item/storage/pill_bottle/penis_enlargement = 10,
/obj/item/storage/pill_bottle/breast_enlargement = 10,
/obj/item/reagent_containers/glass/bottle/crocin = 10,
/obj/item/reagent_containers/glass/bottle/camphor = 5,
/obj/item/storage/daki = 4
)