mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-23 03:57:13 +01:00
Merge remote-tracking branch 'ParadiseSS13/master' into toml-config
This commit is contained in:
+9
-1
@@ -1072,7 +1072,7 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
Returning TRUE here will override the above proc's result.
|
||||
*/
|
||||
/atom/proc/CanAStarPassTo(ID, dir, obj/destination)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/** Call this when you want to present a renaming prompt to the user.
|
||||
|
||||
@@ -1139,3 +1139,11 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
else
|
||||
name = "[prefix][t]"
|
||||
return t
|
||||
|
||||
/atom/proc/set_angle(degrees)
|
||||
var/matrix/M = matrix()
|
||||
M.Turn(degrees)
|
||||
// If we aint 0, make it NN transform
|
||||
if(degrees)
|
||||
appearance_flags |= PIXEL_SCALE
|
||||
transform = M
|
||||
|
||||
@@ -90,6 +90,8 @@
|
||||
/mob/living/carbon/proc/has_virus()
|
||||
for(var/thing in viruses)
|
||||
var/datum/disease/D = thing
|
||||
if(!D.discovered) // Early-stage viruses should not show up on med HUD (though health analywers can still pick them up)
|
||||
continue
|
||||
if((!(D.visibility_flags & HIDDEN_SCANNER)) && (D.severity != NONTHREAT))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
activation_messages = list("You feel smarter.")
|
||||
deactivation_messages = list("You feel dumber.")
|
||||
instability = GENE_INSTABILITY_MAJOR
|
||||
traits_to_add = list(TRAIT_TELEKINESIS)
|
||||
activation_prob = 15
|
||||
|
||||
/datum/mutation/tk/New()
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
traitorcount += 1
|
||||
continue
|
||||
if(ishuman(player) || isAI(player))
|
||||
if((ROLE_TRAITOR in player.client.prefs.be_special) && !player.client.skip_antag && !jobban_isbanned(player, ROLE_TRAITOR) && !jobban_isbanned(player, "Syndicate"))
|
||||
if((ROLE_TRAITOR in player.client.prefs.be_special) && !player.client.skip_antag && !jobban_isbanned(player, ROLE_TRAITOR) && !jobban_isbanned(player, ROLE_SYNDICATE))
|
||||
possible_traitors += player.mind
|
||||
for(var/datum/mind/player in possible_traitors)
|
||||
for(var/job in restricted_jobs)
|
||||
@@ -144,7 +144,7 @@
|
||||
if(SSshuttle.emergency.mode >= SHUTTLE_ESCAPE)
|
||||
return
|
||||
//message_admins("Late Join Check")
|
||||
if(character.client && (ROLE_TRAITOR in character.client.prefs.be_special) && !character.client.skip_antag && !jobban_isbanned(character, ROLE_TRAITOR) && !jobban_isbanned(character, "Syndicate"))
|
||||
if(character.client && (ROLE_TRAITOR in character.client.prefs.be_special) && !character.client.skip_antag && !jobban_isbanned(character, ROLE_TRAITOR) && !jobban_isbanned(character, ROLE_SYNDICATE))
|
||||
//message_admins("Late Joiner has Be Syndicate")
|
||||
//message_admins("Checking number of players")
|
||||
var/playercount = 0
|
||||
|
||||
@@ -57,7 +57,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
/datum/game_mode/blob/proc/get_blob_candidates()
|
||||
var/list/candidates = list()
|
||||
for(var/mob/living/carbon/human/player in GLOB.player_list)
|
||||
if(!player.stat && player.mind && !player.client.skip_antag && !player.mind.special_role && !jobban_isbanned(player, "Syndicate") && (ROLE_BLOB in player.client.prefs.be_special))
|
||||
if(!player.stat && player.mind && !player.client.skip_antag && !player.mind.special_role && !jobban_isbanned(player, ROLE_SYNDICATE) && (ROLE_BLOB in player.client.prefs.be_special))
|
||||
candidates += player
|
||||
return candidates
|
||||
|
||||
|
||||
@@ -93,5 +93,7 @@ the same goes for Remove(). if you override Remove(), call parent or else your p
|
||||
/datum/action/changeling/proc/transform_dna(mob/living/carbon/human/H, datum/dna/D)
|
||||
if(!D)
|
||||
return
|
||||
|
||||
H.change_dna(D, TRUE)
|
||||
var/changesSpecies = TRUE
|
||||
if (H.dna.species.name == D.species.name)
|
||||
changesSpecies = FALSE
|
||||
H.change_dna(D, changesSpecies)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/datum/action/changeling/digitalcamo
|
||||
name = "Digital Camouflage"
|
||||
desc = "By evolving the ability to distort our form and proprotions, we defeat common altgorithms used to detect lifeforms on cameras."
|
||||
helptext = "We cannot be tracked by camera while using this skill. However, humans looking at us will find us... uncanny."
|
||||
helptext = "We cannot be tracked by camera while using this skill."
|
||||
button_icon_state = "digital_camo"
|
||||
dna_cost = 1
|
||||
|
||||
//Prevents AIs tracking you but makes you easily detectable to the human-eye.
|
||||
//Prevents AIs tracking you.
|
||||
/datum/action/changeling/digitalcamo/sting_action(mob/user)
|
||||
|
||||
if(user.digitalcamo)
|
||||
|
||||
@@ -243,7 +243,6 @@
|
||||
damage_type = BRUTE
|
||||
range = 8
|
||||
hitsound = 'sound/weapons/thudswoosh.ogg'
|
||||
var/chain
|
||||
var/obj/item/ammo_casing/magic/tentacle/source //the item that shot it
|
||||
|
||||
/obj/item/projectile/tentacle/New(obj/item/ammo_casing/magic/tentacle/tentacle_casing)
|
||||
|
||||
@@ -7,51 +7,7 @@
|
||||
|
||||
//Revive from regenerative stasis
|
||||
/datum/action/changeling/revive/sting_action(mob/living/carbon/user)
|
||||
user.setToxLoss(0, FALSE)
|
||||
user.setOxyLoss(0, FALSE)
|
||||
user.setCloneLoss(0, FALSE)
|
||||
user.setBrainLoss(0, FALSE)
|
||||
user.SetParalysis(0, FALSE)
|
||||
user.SetStunned(0, FALSE)
|
||||
user.SetWeakened(0, FALSE)
|
||||
user.radiation = 0
|
||||
user.SetEyeBlind(0, FALSE)
|
||||
user.SetEyeBlurry(0, FALSE)
|
||||
user.RestoreEars()
|
||||
user.heal_overall_damage(user.getBruteLoss(), user.getFireLoss(), updating_health = FALSE)
|
||||
user.cure_blind(null, FALSE)
|
||||
user.CureDeaf()
|
||||
user.cure_nearsighted(null, FALSE)
|
||||
user.reagents.clear_reagents()
|
||||
user.germ_level = 0
|
||||
user.timeofdeath = 0
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.restore_blood()
|
||||
H.next_pain_time = 0
|
||||
H.dna.species.create_organs(H)
|
||||
// Now that recreating all organs is necessary, the rest of this organ stuff probably
|
||||
// isn't, but I don't want to remove it, just in case.
|
||||
for(var/organ_name in H.bodyparts_by_name)
|
||||
var/obj/item/organ/external/O = H.bodyparts_by_name[organ_name]
|
||||
if(!O)
|
||||
continue
|
||||
O.brute_dam = 0
|
||||
O.burn_dam = 0
|
||||
O.damage_state = "00"
|
||||
O.germ_level = 0
|
||||
QDEL_NULL(O.hidden)
|
||||
O.open = 0
|
||||
O.internal_bleeding = FALSE
|
||||
O.perma_injury = 0
|
||||
O.status = 0
|
||||
O.trace_chemicals.Cut()
|
||||
for(var/obj/item/organ/internal/IO in H.internal_organs)
|
||||
IO.rejuvenate()
|
||||
IO.trace_chemicals.Cut()
|
||||
H.remove_all_embedded_objects()
|
||||
for(var/datum/disease/critical/C in user.viruses)
|
||||
C.cure()
|
||||
user.revive()
|
||||
REMOVE_TRAIT(user, TRAIT_FAKEDEATH, "changeling")
|
||||
user.updatehealth("revive sting")
|
||||
user.update_blind_effects()
|
||||
|
||||
@@ -848,8 +848,12 @@
|
||||
uses += max(1, temp)
|
||||
|
||||
/obj/item/melee/blood_magic/manipulator/attack_self(mob/living/user)
|
||||
var/list/options = list("Blood Orb (50)", "Blood Recharge (75)", "Blood Spear (150)", "Blood Bolt Barrage (300)")
|
||||
var/choice = input(user, "Choose a greater blood rite...", "Greater Blood Rites") as null|anything in options
|
||||
var/list/options = list("Blood Orb (50)" = image(icon = 'icons/obj/cult.dmi', icon_state = "summoning_orb"),
|
||||
"Blood Recharge (75)" = image(icon = 'icons/mob/actions/actions_cult.dmi', icon_state = "blood_charge"),
|
||||
"Blood Spear (150)" = image(icon = 'icons/mob/actions/actions_cult.dmi', icon_state = "bloodspear"),
|
||||
"Blood Bolt Barrage (300)" = image(icon = 'icons/mob/actions/actions_cult.dmi', icon_state = "blood_barrage"))
|
||||
var/choice = show_radial_menu(user, src, options)
|
||||
|
||||
switch(choice)
|
||||
if("Blood Orb (50)")
|
||||
if(uses < BLOOD_ORB_COST)
|
||||
|
||||
@@ -195,6 +195,7 @@
|
||||
GLOBAL_LIST_INIT(blacklisted_pylon_turfs, typecacheof(list(
|
||||
/turf/simulated/floor/engine/cult,
|
||||
/turf/space,
|
||||
/turf/simulated/wall/indestructible,
|
||||
/turf/simulated/floor/plating/lava,
|
||||
/turf/simulated/floor/chasm,
|
||||
/turf/simulated/wall/cult,
|
||||
|
||||
@@ -130,6 +130,9 @@ To draw a rune, use a ritual dagger.
|
||||
visible_message("<span class='danger'>[src] suddenly appears!</span>")
|
||||
alpha = initial(alpha)
|
||||
|
||||
/obj/effect/rune/is_cleanable()
|
||||
return TRUE
|
||||
|
||||
|
||||
/*
|
||||
There are a few different procs each rune runs through when a cultist activates it.
|
||||
@@ -991,6 +994,9 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
/obj/effect/rune/narsie/cult_conceal() //can't hide this, and you wouldn't want to
|
||||
return
|
||||
|
||||
/obj/effect/rune/narsie/is_cleanable() //No, you can't just yeet a cleaning grenade to remove it.
|
||||
return FALSE
|
||||
|
||||
/obj/effect/rune/narsie/invoke(list/invokers)
|
||||
if(used)
|
||||
return
|
||||
|
||||
@@ -238,7 +238,7 @@
|
||||
// Assemble a list of active players without jobbans.
|
||||
for(var/mob/new_player/player in GLOB.player_list)
|
||||
if(player.client && player.ready && player.has_valid_preferences())
|
||||
if(!jobban_isbanned(player, "Syndicate") && !jobban_isbanned(player, roletext))
|
||||
if(!jobban_isbanned(player, ROLE_SYNDICATE) && !jobban_isbanned(player, roletext))
|
||||
if(player_old_enough_antag(player.client,role))
|
||||
players += player
|
||||
|
||||
|
||||
@@ -128,8 +128,8 @@
|
||||
if(cannotPossess(user))
|
||||
to_chat(user, "<span class='boldnotice'>Upon using the antagHUD you forfeited the ability to join the round.</span>")
|
||||
return
|
||||
if(jobban_isbanned(user, "Syndicate"))
|
||||
to_chat(user, "<span class='warning'>You are banned from antagonists!</span>")
|
||||
if(jobban_isbanned(user, ROLE_SYNDICATE) || jobban_isbanned(user, ROLE_BORER))
|
||||
to_chat(user, "<span class='warning'>You are banned from playing this antagonist!</span>")
|
||||
return
|
||||
if(key)
|
||||
return
|
||||
|
||||
@@ -332,6 +332,14 @@
|
||||
to_chat(S, "<span class='warning'>An inhospitable area may be created as a result of destroying this object. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/structure/fans/tiny/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>An inhospitable area may be created as a result of destroying this object. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/structure/holosign/barrier/atmos/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>An inhospitable area may be created as a result of destroying this object. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/tcomms/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
to_chat(S, "<span class='warning'>This communications relay should be preserved, it will be a useful resource to our masters in the future. Aborting.</span>")
|
||||
return FALSE
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 10
|
||||
damage_transfer = 0.9
|
||||
can_strip = TRUE
|
||||
projectiletype = /obj/item/projectile/guardian
|
||||
ranged_cooldown_time = 5 //fast!
|
||||
projectilesound = 'sound/effects/hit_on_shattered_glass.ogg'
|
||||
@@ -35,6 +36,7 @@
|
||||
alpha = 255
|
||||
range = 13
|
||||
incorporeal_move = 0
|
||||
can_strip = TRUE
|
||||
to_chat(src, "<span class='danger'>You switch to combat mode.</span>")
|
||||
toggle = FALSE
|
||||
else
|
||||
@@ -46,6 +48,7 @@
|
||||
alpha = 60
|
||||
range = 255
|
||||
incorporeal_move = 1
|
||||
can_strip = FALSE //spiritual pickpocketting is forbidden
|
||||
to_chat(src, "<span class='danger'>You switch to scout mode.</span>")
|
||||
toggle = TRUE
|
||||
else
|
||||
|
||||
@@ -188,6 +188,9 @@
|
||||
M.regenerate_icons()
|
||||
M.update_body()
|
||||
|
||||
if(!the_bomb)
|
||||
the_bomb = locate(/obj/machinery/nuclearbomb/syndicate) in GLOB.poi_list
|
||||
|
||||
if(the_bomb)
|
||||
synd_mind.store_memory("<B>Syndicate [the_bomb.name] Code</B>: [the_bomb.r_code]")
|
||||
to_chat(synd_mind.current, "The code for \the [the_bomb.name] is: <B>[the_bomb.r_code]</B>")
|
||||
@@ -436,54 +439,55 @@
|
||||
return newname
|
||||
|
||||
|
||||
/datum/game_mode/nuclear/set_scoreboard_gvars()
|
||||
/datum/game_mode/nuclear/set_scoreboard_vars()
|
||||
var/datum/scoreboard/scoreboard = SSticker.score
|
||||
var/foecount = 0
|
||||
|
||||
for(var/datum/mind/M in SSticker.mode.syndicates)
|
||||
foecount++
|
||||
if(!M || !M.current)
|
||||
GLOB.score_opkilled++
|
||||
scoreboard.score_ops_killed++
|
||||
continue
|
||||
|
||||
if(M.current.stat == DEAD)
|
||||
GLOB.score_opkilled++
|
||||
scoreboard.score_ops_killed++
|
||||
|
||||
else if(M.current.restrained())
|
||||
GLOB.score_arrested++
|
||||
scoreboard.score_arrested++
|
||||
|
||||
if(foecount == GLOB.score_arrested)
|
||||
GLOB.score_allarrested = 1
|
||||
if(foecount == scoreboard.score_arrested)
|
||||
scoreboard.all_arrested = TRUE // how the hell did they manage that
|
||||
|
||||
for(var/obj/machinery/nuclearbomb/nuke in GLOB.machines)
|
||||
if(nuke.r_code == "Nope") continue
|
||||
var/obj/machinery/nuclearbomb/syndicate/nuke = locate() in GLOB.poi_list
|
||||
if(nuke?.r_code != "Nope")
|
||||
var/area/A = get_area(nuke)
|
||||
|
||||
var/list/thousand_penalty = list(/area/solar)
|
||||
var/list/fiftythousand_penalty = list(/area/security/main, /area/security/brig, /area/security/armoury, /area/security/checkpoint2)
|
||||
|
||||
if(is_type_in_list(A, thousand_penalty))
|
||||
GLOB.score_nuked_penalty = 1000
|
||||
scoreboard.nuked_penalty = 1000
|
||||
|
||||
else if(is_type_in_list(A, fiftythousand_penalty))
|
||||
GLOB.score_nuked_penalty = 50000
|
||||
scoreboard.nuked_penalty = 50000
|
||||
|
||||
else if(istype(A, /area/engine))
|
||||
GLOB.score_nuked_penalty = 100000
|
||||
scoreboard.nuked_penalty = 100000
|
||||
|
||||
else
|
||||
GLOB.score_nuked_penalty = 10000
|
||||
scoreboard.nuked_penalty = 10000
|
||||
|
||||
break
|
||||
|
||||
var/killpoints = GLOB.score_opkilled * 250
|
||||
var/arrestpoints = GLOB.score_arrested * 1000
|
||||
GLOB.score_crewscore += killpoints
|
||||
GLOB.score_crewscore += arrestpoints
|
||||
if(GLOB.score_nuked)
|
||||
GLOB.score_crewscore -= GLOB.score_nuked_penalty
|
||||
var/killpoints = scoreboard.score_ops_killed * 250
|
||||
var/arrestpoints = scoreboard.score_arrested * 1000
|
||||
scoreboard.crewscore += killpoints
|
||||
scoreboard.crewscore += arrestpoints
|
||||
if(scoreboard.nuked)
|
||||
scoreboard.crewscore -= scoreboard.nuked_penalty
|
||||
|
||||
|
||||
|
||||
/datum/game_mode/nuclear/get_scoreboard_stats()
|
||||
var/datum/scoreboard/scoreboard = SSticker.score
|
||||
var/foecount = 0
|
||||
var/crewcount = 0
|
||||
|
||||
@@ -530,11 +534,11 @@
|
||||
|
||||
dat += "<br>"
|
||||
|
||||
dat += "<b>Operatives Arrested:</b> [GLOB.score_arrested] ([GLOB.score_arrested * 1000] Points)<br>"
|
||||
dat += "<b>All Operatives Arrested:</b> [GLOB.score_allarrested ? "Yes" : "No"] (Score tripled)<br>"
|
||||
dat += "<b>Operatives Arrested:</b> [scoreboard.score_arrested] ([scoreboard.score_arrested * 1000] Points)<br>"
|
||||
dat += "<b>All Operatives Arrested:</b> [scoreboard.all_arrested ? "Yes" : "No"] (Score tripled)<br>"
|
||||
|
||||
dat += "<b>Operatives Killed:</b> [GLOB.score_opkilled] ([GLOB.score_opkilled * 1000] Points)<br>"
|
||||
dat += "<b>Station Destroyed:</b> [GLOB.score_nuked ? "Yes" : "No"] (-[GLOB.score_nuked_penalty] Points)<br>"
|
||||
dat += "<b>Operatives Killed:</b> [scoreboard.score_ops_killed] ([scoreboard.score_ops_killed * 1000] Points)<br>"
|
||||
dat += "<b>Station Destroyed:</b> [scoreboard.nuked ? "Yes" : "No"] (-[scoreboard.nuked_penalty] Points)<br>"
|
||||
dat += "<hr>"
|
||||
|
||||
return dat
|
||||
|
||||
@@ -370,44 +370,45 @@
|
||||
text += "<br>"
|
||||
to_chat(world, text)
|
||||
|
||||
/datum/game_mode/revolution/set_scoreboard_gvars()
|
||||
/datum/game_mode/revolution/set_scoreboard_vars()
|
||||
var/datum/scoreboard/scoreboard = SSticker.score
|
||||
var/foecount = 0
|
||||
|
||||
for(var/datum/mind/M in SSticker.mode.head_revolutionaries)
|
||||
foecount++
|
||||
if(!M || !M.current)
|
||||
GLOB.score_opkilled++
|
||||
scoreboard.score_ops_killed++
|
||||
continue
|
||||
|
||||
if(M.current.stat == DEAD)
|
||||
GLOB.score_opkilled++
|
||||
scoreboard.score_ops_killed++
|
||||
|
||||
else if(M.current.restrained())
|
||||
GLOB.score_arrested++
|
||||
scoreboard.score_arrested++
|
||||
|
||||
if(foecount == GLOB.score_arrested)
|
||||
GLOB.score_allarrested = 1
|
||||
if(foecount == scoreboard.score_arrested)
|
||||
scoreboard.all_arrested = TRUE
|
||||
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/player = thing
|
||||
if(player.mind)
|
||||
var/role = player.mind.assigned_role
|
||||
if(role in list("Captain", "Head of Security", "Head of Personnel", "Chief Engineer", "Research Director"))
|
||||
if(player.stat == DEAD)
|
||||
GLOB.score_deadcommand++
|
||||
for(var/I in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = I
|
||||
if(H.stat == DEAD && H.mind?.assigned_role)
|
||||
if(H.mind.assigned_role in list("Captain", "Head of Security", "Head of Personnel", "Chief Engineer", "Research Director"))
|
||||
scoreboard.score_dead_command++
|
||||
|
||||
|
||||
var/arrestpoints = GLOB.score_arrested * 1000
|
||||
var/killpoints = GLOB.score_opkilled * 500
|
||||
var/comdeadpts = GLOB.score_deadcommand * 500
|
||||
if(GLOB.score_traitorswon)
|
||||
GLOB.score_crewscore -= 10000
|
||||
var/arrestpoints = scoreboard.score_arrested * 1000
|
||||
var/killpoints = scoreboard.score_ops_killed * 500
|
||||
var/comdeadpts = scoreboard.score_dead_command * 500
|
||||
if(scoreboard.score_greentext)
|
||||
scoreboard.crewscore -= 10000
|
||||
|
||||
GLOB.score_crewscore += arrestpoints
|
||||
GLOB.score_crewscore += killpoints
|
||||
GLOB.score_crewscore -= comdeadpts
|
||||
scoreboard.crewscore += arrestpoints
|
||||
scoreboard.crewscore += killpoints
|
||||
scoreboard.crewscore -= comdeadpts
|
||||
|
||||
|
||||
/datum/game_mode/revolution/get_scoreboard_stats()
|
||||
var/datum/scoreboard/scoreboard = SSticker.score
|
||||
var/foecount = 0
|
||||
var/comcount = 0
|
||||
var/revcount = 0
|
||||
@@ -444,12 +445,12 @@
|
||||
dat += "<b>Number of Surviving Loyal Crew:</b> [loycount]<br>"
|
||||
|
||||
dat += "<br>"
|
||||
dat += "<b>Revolution Heads Arrested:</b> [GLOB.score_arrested] ([GLOB.score_arrested * 1000] Points)<br>"
|
||||
dat += "<b>All Revolution Heads Arrested:</b> [GLOB.score_allarrested ? "Yes" : "No"] (Score tripled)<br>"
|
||||
dat += "<b>Revolution Heads Arrested:</b> [scoreboard.score_arrested] ([scoreboard.score_arrested * 1000] Points)<br>"
|
||||
dat += "<b>All Revolution Heads Arrested:</b> [scoreboard.all_arrested ? "Yes" : "No"] (Score tripled)<br>"
|
||||
|
||||
dat += "<b>Revolution Heads Slain:</b> [GLOB.score_opkilled] ([GLOB.score_opkilled * 500] Points)<br>"
|
||||
dat += "<b>Command Staff Slain:</b> [GLOB.score_deadcommand] (-[GLOB.score_deadcommand * 500] Points)<br>"
|
||||
dat += "<b>Revolution Successful:</b> [GLOB.score_traitorswon ? "Yes" : "No"] (-[GLOB.score_traitorswon * 10000] Points)<br>"
|
||||
dat += "<b>Revolution Heads Slain:</b> [scoreboard.score_ops_killed] ([scoreboard.score_ops_killed * 500] Points)<br>"
|
||||
dat += "<b>Command Staff Slain:</b> [scoreboard.score_dead_command] (-[scoreboard.score_dead_command * 500] Points)<br>"
|
||||
dat += "<b>Revolution Successful:</b> [scoreboard.score_greentext ? "Yes" : "No"] (-[scoreboard.score_greentext * 10000] Points)<br>"
|
||||
dat += "<HR>"
|
||||
|
||||
return dat
|
||||
|
||||
+237
-163
@@ -1,3 +1,5 @@
|
||||
GLOBAL_VAR(scoreboard) // Variable to save the scoreboard string once it's been generated
|
||||
|
||||
//Thresholds for Score Ratings
|
||||
#define SINGULARITY_DESERVES_BETTER -3500
|
||||
#define SINGULARITY_FODDER -3000
|
||||
@@ -14,190 +16,275 @@
|
||||
#define PRIDE_OF_SCIENCE 4000
|
||||
#define NANOTRANSEN_FINEST 5000
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/scoreboard()
|
||||
//Print a list of antagonists to the server log
|
||||
/datum/scoreboard
|
||||
/// Overall combined score for the whole round.
|
||||
var/crewscore = 0
|
||||
/// How many useful items have cargo shipped out?
|
||||
var/score_things_shipped = 0
|
||||
/// How many harvests have hydroponics done?
|
||||
var/score_things_harvested = 0
|
||||
/// How much ore has been mined on the mining z level?
|
||||
var/score_ore_mined = 0
|
||||
/// How much research was done by science?
|
||||
var/score_research_done = 0
|
||||
/// How many random events did the station survive?
|
||||
var/score_events_endured = 0
|
||||
/// How many APCs have poor charge?
|
||||
var/score_power_loss = 0
|
||||
/// How many people got out alive?
|
||||
var/score_escapees = 0
|
||||
/// How many people /didn't/ get out alive?
|
||||
var/score_dead_crew = 0
|
||||
/// How much blood, puke, stains etc went uncleaned?
|
||||
var/score_mess = 0
|
||||
/// How many meals were made?
|
||||
var/score_meals = 0
|
||||
/// How many rampant, uncured diseases are on board the station?
|
||||
var/score_disease = 0
|
||||
/// How many command members died? (Revolution)
|
||||
var/score_dead_command = 0
|
||||
/// How many antagonists are alive in the brig? (Nuke ops & Revolution)
|
||||
var/score_arrested = 0
|
||||
/// How many operatives were killed? (Nuke ops & Revolution)
|
||||
var/score_ops_killed = 0
|
||||
/// How much noms were had by the crew?
|
||||
var/score_food_eaten = 0
|
||||
/// How many times was the clown punched, struck, or otherwise maligned?
|
||||
var/score_clown_abuse = 0
|
||||
|
||||
// Booleans //
|
||||
/// Were the antagonists successful?
|
||||
var/score_greentext = FALSE
|
||||
/// Did the crew catch all of the antags alive?
|
||||
var/all_arrested = FALSE
|
||||
/// Is the NAD safe and secure?
|
||||
var/disc_secure = FALSE
|
||||
|
||||
// Points penalties/bonuses //
|
||||
/// If all APCs on the station are running optimally, big bonus.
|
||||
var/power_bonus = FALSE
|
||||
/// If there are no messes on the station anywhere, huge bonus.
|
||||
var/mess_bonus = FALSE
|
||||
/// If the AI is dead, big points penalty.
|
||||
var/dead_ai = FALSE
|
||||
/// Was the station blown into little bits?
|
||||
var/nuked = FALSE
|
||||
/// Points penalty for being blown to little bits.
|
||||
var/nuked_penalty = 0
|
||||
|
||||
// Player Stats //
|
||||
/// What was the name of the richest person on the shuttle?
|
||||
var/richest_name = ""
|
||||
/// What was the ckey of the richest person on the shuttle?
|
||||
var/richest_key = ""
|
||||
/// What was the job of the richest person on the shuttle?
|
||||
var/richest_job = ""
|
||||
/// How much money did the richest person on the shuttle have?
|
||||
var/richest_cash = 0
|
||||
|
||||
/// What was the name of the most injured person on the shuttle?
|
||||
var/damaged_name
|
||||
/// What was the ckey of the most injured person on the shuttle?
|
||||
var/damaged_key
|
||||
/// What was the job of the most injured person on the shuttle?
|
||||
var/damaged_job
|
||||
/// How damaged was the most injured person on the shuttle?
|
||||
var/damaged_health
|
||||
|
||||
|
||||
/datum/scoreboard/proc/scoreboard()
|
||||
// Print a list of antagonists to the server log.
|
||||
log_antags()
|
||||
|
||||
for(var/_I in GLOB.mob_list)
|
||||
var/mob/M = _I
|
||||
if(is_station_level(M.z))
|
||||
check_station_player(M)
|
||||
else if(SSshuttle.emergency.mode >= SHUTTLE_ENDGAME && istype(get_area(M), SSshuttle.emergency.areaInstance))
|
||||
check_shuttle_player(M)
|
||||
|
||||
check_apc_power()
|
||||
check_cleanables()
|
||||
|
||||
generate_scoreboard()
|
||||
|
||||
/datum/scoreboard/proc/log_antags()
|
||||
var/list/total_antagonists = list()
|
||||
//Look into all mobs in world, dead or alive
|
||||
for(var/datum/mind/Mind in SSticker.minds)
|
||||
var/temprole = Mind.special_role
|
||||
if(temprole) //if they are an antagonist of some sort.
|
||||
if(temprole in total_antagonists) //If the role exists already, add the name to it
|
||||
total_antagonists[temprole] += ", [Mind.name]([Mind.key])"
|
||||
else
|
||||
total_antagonists.Add(temprole) //If the role doesnt exist in the list, create it and add the mob
|
||||
total_antagonists[temprole] += ": [Mind.name]([Mind.key])"
|
||||
// Look into all mobs in the world, dead or alive
|
||||
for(var/mind in SSticker.minds)
|
||||
var/datum/mind/M = mind
|
||||
var/role = M.special_role
|
||||
|
||||
//Now print them all into the log!
|
||||
// If they're an antagonist of some sort.
|
||||
if(role)
|
||||
if(total_antagonists[role]) // If the role exists already, add the name to it.
|
||||
total_antagonists[role] += ", [M.name]([M.key])"
|
||||
else // If the role doesn't exist in the list, create it and add the mob
|
||||
total_antagonists[role] += ": [M.name]([M.key])"
|
||||
|
||||
// Now print them all into the log!
|
||||
log_game("Antagonists at round end were...")
|
||||
for(var/i in total_antagonists)
|
||||
log_game("[i]s[total_antagonists[i]].")
|
||||
|
||||
// Score Calculation and Display
|
||||
|
||||
// Who is alive/dead, who escaped
|
||||
for(var/mob/living/silicon/ai/I in GLOB.mob_list)
|
||||
if(I.stat == DEAD && is_station_level(I.z))
|
||||
GLOB.score_deadaipenalty++
|
||||
GLOB.score_deadcrew++
|
||||
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/I = thing
|
||||
if(I.stat == DEAD && is_station_level(I.z))
|
||||
GLOB.score_deadcrew++
|
||||
|
||||
if(SSshuttle.emergency.mode >= SHUTTLE_ENDGAME)
|
||||
for(var/mob/living/player in GLOB.mob_list)
|
||||
if(player.client)
|
||||
if(player.stat != DEAD)
|
||||
var/turf/location = get_turf(player.loc)
|
||||
var/area/escape_zone = locate(/area/shuttle/escape)
|
||||
if(location in escape_zone)
|
||||
GLOB.score_escapees++
|
||||
for(var/I in total_antagonists)
|
||||
log_game("[I]s[total_antagonists[I]].")
|
||||
|
||||
|
||||
/datum/scoreboard/proc/check_station_player(mob/M)
|
||||
if(!is_station_level(M.z) || M.stat < DEAD)
|
||||
return
|
||||
if(isAI(M))
|
||||
dead_ai = TRUE
|
||||
score_dead_crew++
|
||||
else if(ishuman(M))
|
||||
score_dead_crew++
|
||||
|
||||
var/cash_score = 0
|
||||
var/dmg_score = 0
|
||||
/datum/scoreboard/proc/check_shuttle_player(mob/M)
|
||||
if(!M.mind || M.stat == DEAD || !ishuman(M))
|
||||
return
|
||||
var/mob/living/carbon/human/H = M
|
||||
|
||||
if(SSshuttle.emergency.mode >= SHUTTLE_ENDGAME)
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/E = thing
|
||||
cash_score = 0
|
||||
dmg_score = 0
|
||||
var/turf/location = get_turf(E.loc)
|
||||
var/area/escape_zone = SSshuttle.emergency.areaInstance
|
||||
score_escapees++
|
||||
|
||||
if(E.stat != DEAD && (location in escape_zone)) // Escapee Scores
|
||||
cash_score = get_score_container_worth(E)
|
||||
var/cash_score = get_score_container_worth(H)
|
||||
if(cash_score > richest_cash)
|
||||
richest_cash = cash_score
|
||||
richest_name = H.real_name
|
||||
richest_job = H.job
|
||||
richest_key = H.key
|
||||
|
||||
if(cash_score > GLOB.score_richestcash)
|
||||
GLOB.score_richestcash = cash_score
|
||||
GLOB.score_richestname = E.real_name
|
||||
GLOB.score_richestjob = E.job
|
||||
GLOB.score_richestkey = E.key
|
||||
var/damage_score = H.getBruteLoss() + H.getFireLoss() + H.getToxLoss() + H.getOxyLoss()
|
||||
if(damage_score > damaged_health)
|
||||
damaged_health = damage_score
|
||||
damaged_name = H.real_name
|
||||
damaged_job = H.job
|
||||
damaged_key = H.key
|
||||
|
||||
dmg_score = E.getBruteLoss() + E.getFireLoss() + E.getToxLoss() + E.getOxyLoss()
|
||||
if(dmg_score > GLOB.score_dmgestdamage)
|
||||
GLOB.score_dmgestdamage = dmg_score
|
||||
GLOB.score_dmgestname = E.real_name
|
||||
GLOB.score_dmgestjob = E.job
|
||||
GLOB.score_dmgestkey = E.key
|
||||
// A recursive function to properly determine the wealthiest escapee
|
||||
/datum/scoreboard/proc/get_score_container_worth(atom/C, level = 0)
|
||||
. = 0
|
||||
if(level >= 5)
|
||||
// in case the containers recurse or something
|
||||
return 0
|
||||
|
||||
if(SSticker && SSticker.mode)
|
||||
SSticker.mode.set_scoreboard_gvars()
|
||||
for(var/obj/item/card/id/id in C.contents)
|
||||
var/datum/money_account/A = get_money_account(id.associated_account_number)
|
||||
// has an account?
|
||||
if(A)
|
||||
. += A.money
|
||||
for(var/obj/item/stack/spacecash/cash in C.contents)
|
||||
. += cash.amount
|
||||
for(var/obj/item/storage/S in C.contents)
|
||||
. += .(S, level + 1)
|
||||
|
||||
/datum/scoreboard/proc/check_apc_power()
|
||||
for(var/_A in GLOB.apcs)
|
||||
var/obj/machinery/power/apc/A = _A
|
||||
if(!is_station_level(A.z))
|
||||
continue
|
||||
var/obj/item/stock_parts/cell/C = A.cell
|
||||
if(!C || C.charge < 2300)
|
||||
score_power_loss++ //200 charge leeway
|
||||
|
||||
/datum/scoreboard/proc/check_cleanables()
|
||||
for(var/obj/effect/decal/cleanable/C in world)
|
||||
if(!is_station_level(C.z))
|
||||
continue
|
||||
if(istype(C, /obj/effect/decal/cleanable/blood/gibs))
|
||||
score_mess += 3
|
||||
else if(istype(C, /obj/effect/decal/cleanable/blood))
|
||||
score_mess += 1
|
||||
else if(istype(C, /obj/effect/decal/cleanable/vomit))
|
||||
score_mess += 1
|
||||
|
||||
|
||||
// Check station's power levels
|
||||
for(var/thing in GLOB.apcs)
|
||||
var/obj/machinery/power/apc/A = thing
|
||||
if(!is_station_level(A.z)) continue
|
||||
for(var/obj/item/stock_parts/cell/C in A.contents)
|
||||
if(C.charge < 2300)
|
||||
GLOB.score_powerloss++ //200 charge leeway
|
||||
/datum/scoreboard/proc/generate_scoreboard()
|
||||
// Point modifiers
|
||||
var/points_events_endured = score_events_endured * 50
|
||||
var/points_research_done = score_research_done * 30
|
||||
var/points_disease = score_disease * 30
|
||||
var/points_dead_crew = score_dead_crew * 25
|
||||
var/points_escapees = score_escapees * 25
|
||||
var/points_power_loss = score_power_loss * 20
|
||||
var/points_things_harvested = score_things_harvested * 5
|
||||
var/points_things_shipped = score_things_shipped * 5
|
||||
var/points_meals = score_meals * 5
|
||||
var/points_ore_mined = score_ore_mined * 2
|
||||
|
||||
// Bonuses
|
||||
crewscore += points_events_endured
|
||||
crewscore += points_research_done
|
||||
crewscore += points_escapees
|
||||
crewscore += points_things_harvested
|
||||
crewscore += points_things_shipped
|
||||
crewscore += points_meals
|
||||
crewscore += points_ore_mined
|
||||
|
||||
// Check how much uncleaned mess is on the station
|
||||
for(var/obj/effect/decal/cleanable/M in world)
|
||||
if(!is_station_level(M.z)) continue
|
||||
if(istype(M, /obj/effect/decal/cleanable/blood/gibs))
|
||||
GLOB.score_mess += 3
|
||||
if(!score_power_loss)
|
||||
crewscore += 2500
|
||||
power_bonus = TRUE
|
||||
|
||||
if(istype(M, /obj/effect/decal/cleanable/blood))
|
||||
GLOB.score_mess += 1
|
||||
if(!score_mess)
|
||||
crewscore += 1500
|
||||
mess_bonus = TRUE
|
||||
|
||||
if(istype(M, /obj/effect/decal/cleanable/vomit))
|
||||
GLOB.score_mess += 1
|
||||
if(all_arrested) // This only seems to be implemented for Rev and Nukies. -DaveKorhal
|
||||
crewscore *= 3 // This needs to be here for the bonus to be applied properly
|
||||
|
||||
// Penalties
|
||||
crewscore -= points_dead_crew
|
||||
crewscore -= points_power_loss
|
||||
crewscore -= points_disease
|
||||
crewscore -= score_mess
|
||||
|
||||
// Bonus Modifiers
|
||||
var/deathpoints = GLOB.score_deadcrew * 25 //done
|
||||
var/researchpoints = GLOB.score_researchdone * 30
|
||||
var/eventpoints = GLOB.score_eventsendured * 50
|
||||
var/escapoints = GLOB.score_escapees * 25 //done
|
||||
var/harvests = GLOB.score_stuffharvested * 5
|
||||
var/shipping = GLOB.score_stuffshipped * 5
|
||||
var/mining = GLOB.score_oremined * 2 //done, might want polishing
|
||||
var/meals = GLOB.score_meals * 5
|
||||
var/power = GLOB.score_powerloss * 20
|
||||
var/messpoints
|
||||
if(GLOB.score_mess != 0)
|
||||
messpoints = GLOB.score_mess //done
|
||||
var/plaguepoints = GLOB.score_disease * 30
|
||||
if(dead_ai)
|
||||
crewscore -= 250
|
||||
|
||||
|
||||
// Good Things
|
||||
GLOB.score_crewscore += shipping
|
||||
GLOB.score_crewscore += harvests
|
||||
GLOB.score_crewscore += mining
|
||||
GLOB.score_crewscore += researchpoints
|
||||
GLOB.score_crewscore += eventpoints
|
||||
GLOB.score_crewscore += escapoints
|
||||
|
||||
if(power == 0)
|
||||
GLOB.score_crewscore += 2500
|
||||
GLOB.score_powerbonus = 1
|
||||
|
||||
|
||||
GLOB.score_crewscore += meals
|
||||
if(GLOB.score_allarrested) // This only seems to be implemented for Rev and Nukies. -DaveKorhal
|
||||
GLOB.score_crewscore *= 3 // This needs to be here for the bonus to be applied properly
|
||||
|
||||
|
||||
GLOB.score_crewscore -= deathpoints
|
||||
if(GLOB.score_deadaipenalty)
|
||||
GLOB.score_crewscore -= 250
|
||||
GLOB.score_crewscore -= power
|
||||
|
||||
|
||||
GLOB.score_crewscore -= messpoints
|
||||
GLOB.score_crewscore -= plaguepoints
|
||||
|
||||
// Show the score - might add "ranks" later
|
||||
to_chat(world, "<b>The crew's final score is:</b>")
|
||||
to_chat(world, "<b><font size='4'>[GLOB.score_crewscore]</font></b>")
|
||||
|
||||
// Generate the score panel
|
||||
var/dat = "<b>Round Statistics and Score</b><br><hr>"
|
||||
if(mode)
|
||||
dat += mode.get_scoreboard_stats()
|
||||
var/list/dat = list("<b>Round Statistics and Score</b><br><hr>")
|
||||
if(SSticker.mode)
|
||||
dat += SSticker.mode.get_scoreboard_stats()
|
||||
|
||||
dat += {"
|
||||
<b><u>General Statistics</u></b><br>
|
||||
<u>The Good</u><br>
|
||||
<b>Ore Mined:</b> [GLOB.score_oremined] ([GLOB.score_oremined * 2] Points)<br>"}
|
||||
if(SSshuttle.emergency.mode == SHUTTLE_ENDGAME) dat += "<b>Shuttle Escapees:</b> [GLOB.score_escapees] ([GLOB.score_escapees * 25] Points)<br>"
|
||||
dat += {"
|
||||
<b>Whole Station Powered:</b> [GLOB.score_powerbonus ? "Yes" : "No"] ([GLOB.score_powerbonus * 2500] Points)<br><br>
|
||||
<b>Ore Mined:</b> [score_ore_mined] ([points_ore_mined] Points)<br>"}
|
||||
if(score_escapees)
|
||||
dat += "<b>Shuttle Escapees:</b> [score_escapees] ([points_escapees] Points)<br>"
|
||||
dat += "<b>Whole Station Powered:</b> [power_bonus ? "Yes" : "No"] ([power_bonus * 2500] Points)<br>"
|
||||
dat += "<b>Whole Station Cleaned:</b> [mess_bonus ? "Yes" : "No"] ([mess_bonus * 1500] Points)<br><br>"
|
||||
|
||||
<U>The Bad</U><br>
|
||||
<b>Dead bodies on Station:</b> [GLOB.score_deadcrew] (-[GLOB.score_deadcrew * 25] Points)<br>
|
||||
<b>Uncleaned Messes:</b> [GLOB.score_mess] (-[GLOB.score_mess] Points)<br>
|
||||
<b>Station Power Issues:</b> [GLOB.score_powerloss] (-[GLOB.score_powerloss * 20] Points)<br>
|
||||
<b>AI Destroyed:</b> [GLOB.score_deadaipenalty ? "Yes" : "No"] (-[GLOB.score_deadaipenalty * 250] Points)<br><br>
|
||||
dat += "<U>The Bad</U><br>"
|
||||
dat += "<b>Dead bodies on Station:</b> [score_dead_crew] (-[points_dead_crew] Points)<br>"
|
||||
if(!mess_bonus)
|
||||
dat += "<b>Uncleaned Messes:</b> [score_mess] (-[score_mess] Points)<br>"
|
||||
if(!power_bonus)
|
||||
dat += "<b>Station Power Issues:</b> [score_power_loss] (-[points_power_loss] Points)<br>"
|
||||
dat += {"
|
||||
<b>AI Destroyed:</b> [dead_ai ? "Yes" : "No"] (-[dead_ai * 250] Points)<br><br>
|
||||
|
||||
<U>The Weird</U><br>
|
||||
<b>Food Eaten:</b> [GLOB.score_foodeaten] bites/sips<br>
|
||||
<b>Times a Clown was Abused:</b> [GLOB.score_clownabuse]<br><br>
|
||||
"}
|
||||
if(GLOB.score_escapees)
|
||||
dat += {"<b>Richest Escapee:</b> [GLOB.score_richestname], [GLOB.score_richestjob]: $[num2text(GLOB.score_richestcash,50)] ([GLOB.score_richestkey])<br>
|
||||
<b>Most Battered Escapee:</b> [GLOB.score_dmgestname], [GLOB.score_dmgestjob]: [GLOB.score_dmgestdamage] damage ([GLOB.score_dmgestkey])<br>"}
|
||||
<b>Food Eaten:</b> [score_food_eaten] bites/sips.<br>
|
||||
<b>Times a Clown was Abused:</b> [score_clown_abuse]<br><br>"}
|
||||
if(score_escapees)
|
||||
dat += "<b>Richest Escapee:</b> [richest_name], [richest_job]: $[num2text(richest_cash, 50)] ([richest_key])<br>"
|
||||
if(damaged_health)
|
||||
dat += "<b>Most Battered Escapee:</b> [damaged_name], [damaged_job]: [damaged_health] damage ([damaged_key])<br>"
|
||||
else
|
||||
if(SSshuttle.emergency.mode <= SHUTTLE_STRANDED)
|
||||
dat += "The station wasn't evacuated!<br>"
|
||||
else
|
||||
dat += "No-one escaped!<br>"
|
||||
|
||||
dat += mode.declare_job_completion()
|
||||
dat += SSticker.mode.declare_job_completion()
|
||||
|
||||
dat += {"
|
||||
<hr><br>
|
||||
<b><u>FINAL SCORE: [GLOB.score_crewscore]</u></b><br>
|
||||
<b><u>FINAL SCORE: [crewscore]</u></b><br>
|
||||
"}
|
||||
|
||||
var/score_rating = "The Aristocrats!"
|
||||
switch(GLOB.score_crewscore)
|
||||
if(-99999 to SINGULARITY_DESERVES_BETTER) score_rating = "Even the Singularity Deserves Better"
|
||||
switch(crewscore)
|
||||
if(-INFINITY to SINGULARITY_DESERVES_BETTER) score_rating = "Even the Singularity Deserves Better"
|
||||
if(SINGULARITY_DESERVES_BETTER+1 to SINGULARITY_FODDER) score_rating = "Singularity Fodder"
|
||||
if(SINGULARITY_FODDER+1 to ALL_FIRED) score_rating = "You're All Fired"
|
||||
if(ALL_FIRED+1 to WASTE_OF_OXYGEN) score_rating = "A Waste of Perfectly Good Oxygen"
|
||||
@@ -214,33 +301,20 @@
|
||||
if(NANOTRANSEN_FINEST to INFINITY) score_rating = "Nanotrasen's Finest"
|
||||
|
||||
dat += "<b><u>RATING:</u></b> [score_rating]"
|
||||
src << browse(dat, "window=roundstats;size=500x600")
|
||||
GLOB.scoreboard = jointext(dat, "")
|
||||
|
||||
for(var/mob/E in GLOB.player_list)
|
||||
if(E.client && !E.get_preference(PREFTOGGLE_DISABLE_SCOREBOARD))
|
||||
E << browse(dat, "window=roundstats;size=500x600")
|
||||
if(E.client)
|
||||
to_chat(E, "<b>The crew's final score is:</b>")
|
||||
to_chat(E, "<b><font size='4'><a href='?src=[E.UID()];scoreboard=1'>[crewscore]</a></font></b>")
|
||||
if(!E.get_preference(PREFTOGGLE_DISABLE_SCOREBOARD))
|
||||
E << browse(GLOB.scoreboard, "window=roundstats;size=500x600")
|
||||
|
||||
// A recursive function to properly determine the wealthiest escapee
|
||||
/datum/controller/subsystem/ticker/proc/get_score_container_worth(atom/C, level=0)
|
||||
if(level >= 5)
|
||||
// in case the containers recurse or something
|
||||
return 0
|
||||
else
|
||||
. = 0
|
||||
for(var/obj/item/card/id/id in C.contents)
|
||||
var/datum/money_account/A = get_money_account(id.associated_account_number)
|
||||
// has an account?
|
||||
if(A)
|
||||
. += A.money
|
||||
for(var/obj/item/stack/spacecash/cash in C.contents)
|
||||
. += cash.amount
|
||||
for(var/obj/item/storage/S in C.contents)
|
||||
. += .(S, level + 1)
|
||||
|
||||
/datum/game_mode/proc/get_scoreboard_stats()
|
||||
return null
|
||||
|
||||
/datum/game_mode/proc/set_scoreboard_gvars()
|
||||
/datum/game_mode/proc/set_scoreboard_vars()
|
||||
return null
|
||||
|
||||
#undef SINGULARITY_DESERVES_BETTER
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
action_background_icon_state = "bg_vampire"
|
||||
var/required_blood = 0
|
||||
var/gain_desc = null
|
||||
var/deduct_blood_on_cast = TRUE //Do we want to take the blood when this is cast, or at a later point?
|
||||
|
||||
/obj/effect/proc_holder/spell/vampire/New()
|
||||
..()
|
||||
@@ -99,6 +100,8 @@
|
||||
var/datum/vampire/vampire = usr.mind.vampire
|
||||
|
||||
if(required_blood <= vampire.bloodusable)
|
||||
if(!deduct_blood_on_cast) //don't take the blood yet if this is false!
|
||||
return
|
||||
vampire.bloodusable -= required_blood
|
||||
else
|
||||
// stop!!
|
||||
@@ -288,8 +291,10 @@
|
||||
gain_desc = "You have gained the Enthrall ability which at a heavy blood cost allows you to enslave a human that is not loyal to any other for a random period of time."
|
||||
action_icon_state = "vampire_enthrall"
|
||||
required_blood = 300
|
||||
deduct_blood_on_cast = FALSE
|
||||
|
||||
/obj/effect/proc_holder/spell/vampire/targetted/enthrall/cast(list/targets, mob/user = usr)
|
||||
var/datum/vampire/vampire = user.mind.vampire
|
||||
for(var/mob/living/target in targets)
|
||||
user.visible_message("<span class='warning'>[user] bites [target]'s neck!</span>", "<span class='warning'>You bite [target]'s neck and begin the flow of power.</span>")
|
||||
to_chat(target, "<span class='warning'>You feel the tendrils of evil invade your mind.</span>")
|
||||
@@ -299,6 +304,7 @@
|
||||
if(do_mob(user, target, 50))
|
||||
if(can_enthrall(user, target))
|
||||
handle_enthrall(user, target)
|
||||
vampire.bloodusable -= required_blood //we take the blood after enthralling, not before
|
||||
else
|
||||
revert_cast(user)
|
||||
to_chat(user, "<span class='warning'>You or your target either moved or you dont have enough usable blood.</span>")
|
||||
|
||||
@@ -366,7 +366,7 @@
|
||||
qdel(SS)
|
||||
|
||||
/proc/make_new_construct(mob/living/simple_animal/hostile/construct/c_type, mob/target, mob/user, cult_override = FALSE)
|
||||
if(jobban_isbanned(target, "cultist"))
|
||||
if(jobban_isbanned(target, ROLE_CULTIST))
|
||||
return
|
||||
var/mob/living/simple_animal/hostile/construct/C = new c_type(get_turf(target))
|
||||
C.faction |= "\ref[user]"
|
||||
|
||||
@@ -446,7 +446,7 @@
|
||||
|
||||
/datum/spellbook_entry/item/warp_cubes
|
||||
name = "Warp Cubes"
|
||||
desc = "Two magic cubes, that when they are twisted in hand, teleports the user to the location of the other cube instantly. Great for silently teleporting to a fixed location, or teleporting you to an appretnance, or vice versa. Do not leave on the wizard den, it will not work."
|
||||
desc = "Two magic cubes, that when they are twisted in hand, teleports the user to the location of the other cube instantly. Great for silently teleporting to a fixed location, or teleporting you to an apprentice, or vice versa. Do not leave on the wizard den, it will not work."
|
||||
item_path = /obj/item/warp_cube/red
|
||||
log_name = "WC"
|
||||
cost = 1
|
||||
@@ -479,7 +479,7 @@
|
||||
|
||||
/datum/spellbook_entry/item/singularity_hammer
|
||||
name = "Singularity Hammer"
|
||||
desc = "A hammer that creates an intensely powerful field of gravity where it strikes, pulling everthing nearby to the point of impact."
|
||||
desc = "A hammer that creates an intensely powerful field of gravity where it strikes, pulling everything nearby to the point of impact."
|
||||
item_path = /obj/item/twohanded/singularityhammer
|
||||
log_name = "SI"
|
||||
category = "Weapons and Armors"
|
||||
|
||||
@@ -226,7 +226,7 @@
|
||||
to_chat(H, "<span class='danger'>Failed to locate a storage object on your mob, either you spawned with no hands free and no backpack or this is a bug.</span>")
|
||||
qdel(G)
|
||||
|
||||
qdel(gear_leftovers)
|
||||
gear_leftovers.Cut()
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
@@ -4,133 +4,66 @@
|
||||
icon_state = "liquid_dispenser"
|
||||
layer = 3
|
||||
plane = FLOOR_PLANE
|
||||
anchored = 1.0
|
||||
anchored = TRUE
|
||||
max_integrity = 200
|
||||
armor = list(melee = 50, bullet = 20, laser = 20, energy = 20, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30)
|
||||
var/uses = 20
|
||||
var/disabled = TRUE
|
||||
var/lethal = 0
|
||||
var/locked = TRUE
|
||||
var/cooldown_time = 0
|
||||
var/cooldown_timeleft = 0
|
||||
var/cooldown_time = 10 SECONDS
|
||||
var/cooldown_on = FALSE
|
||||
req_access = list(ACCESS_AI_UPLOAD)
|
||||
|
||||
/obj/machinery/ai_slipper/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>A small counter shows it has: [uses] use\s remaining.</span>"
|
||||
|
||||
/obj/machinery/ai_slipper/power_change()
|
||||
if(stat & BROKEN)
|
||||
update_icon()
|
||||
if(powered())
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
if( powered() )
|
||||
stat &= ~NOPOWER
|
||||
else
|
||||
stat |= NOPOWER
|
||||
disabled = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/ai_slipper/proc/setState(enabled, uses)
|
||||
disabled = disabled
|
||||
uses = uses
|
||||
power_change()
|
||||
|
||||
/obj/machinery/ai_slipper/attackby(obj/item/W, mob/user, params)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(istype(user, /mob/living/silicon))
|
||||
return attack_hand(user)
|
||||
if(allowed(usr)) // trying to unlock the interface
|
||||
locked = !locked
|
||||
to_chat(user, "You [locked ? "lock" : "unlock"] the device.")
|
||||
if(locked)
|
||||
if(user.machine == src)
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=ai_slipper")
|
||||
else
|
||||
if(user.machine == src)
|
||||
attack_hand(usr)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/ai_slipper/proc/ToggleOn()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
disabled = !disabled
|
||||
stat |= NOPOWER
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/ai_slipper/proc/Activate()
|
||||
/obj/machinery/ai_slipper/attack_ai(mob/user)
|
||||
add_hiddenprint(user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/ai_slipper/attack_ghost(mob/user)
|
||||
if(user.can_advanced_admin_interact())
|
||||
Activate(user)
|
||||
|
||||
/obj/machinery/ai_slipper/attack_hand(mob/user)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
to_chat(user, "<span class='warning'>[src] has no power or is broken!</span>")
|
||||
return
|
||||
if(!allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
return
|
||||
Activate(user)
|
||||
|
||||
/obj/machinery/ai_slipper/proc/Activate(mob/user)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(cooldown_on || disabled)
|
||||
if(!uses)
|
||||
to_chat(user, "<span class='warning'>[src] is empty!</span>")
|
||||
return
|
||||
if(cooldown_on)
|
||||
to_chat(user, "<span class='warning'>[src] is still recharging!</span>")
|
||||
return
|
||||
else
|
||||
new /obj/effect/particle_effect/foam(loc)
|
||||
uses--
|
||||
cooldown_on = TRUE
|
||||
cooldown_time = world.timeofday + 100
|
||||
slip_process()
|
||||
power_change()
|
||||
addtimer(CALLBACK(src, .proc/recharge), cooldown_time)
|
||||
|
||||
/obj/machinery/ai_slipper/update_icon()
|
||||
if(stat & (NOPOWER|BROKEN) || disabled)
|
||||
if(stat & (NOPOWER|BROKEN) || cooldown_on || !uses)
|
||||
icon_state = "liquid_dispenser"
|
||||
else
|
||||
icon_state = "liquid_dispenser_on"
|
||||
|
||||
/obj/machinery/ai_slipper/attack_ai(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/ai_slipper/attack_ghost(mob/user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/ai_slipper/attack_hand(mob/user)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
/obj/machinery/ai_slipper/proc/recharge()
|
||||
if(!uses)
|
||||
return
|
||||
|
||||
if(get_dist(src, user) > 1 && (!issilicon(user) && !user.can_admin_interact()))
|
||||
to_chat(user, "<span class='warning'>Too far away.</span>")
|
||||
user.unset_machine()
|
||||
user << browse(null, "window=ai_slipper")
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
var/area/myarea = get_area(src)
|
||||
var/t = "<TT><B>AI Liquid Dispenser</B> ([myarea.name])<HR>"
|
||||
|
||||
if(locked && (!issilicon(user) && !user.can_admin_interact()))
|
||||
t += "<I>(Swipe ID card to unlock control panel.)</I><BR>"
|
||||
else
|
||||
t += text("Dispenser [] - <A href='?src=[UID()];toggleOn=1'>[]?</a><br>\n", disabled ? "deactivated" : "activated", disabled ? "Enable" : "Disable")
|
||||
t += text("Uses Left: [uses]. <A href='?src=[UID()];toggleUse=1'>Activate the dispenser?</A><br>\n")
|
||||
|
||||
user << browse(t, "window=computer;size=575x450")
|
||||
onclose(user, "computer")
|
||||
|
||||
/obj/machinery/ai_slipper/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(locked && (!issilicon(usr) && !usr.can_admin_interact()))
|
||||
to_chat(usr, "Control panel is locked!")
|
||||
return 1
|
||||
|
||||
if(href_list["toggleOn"])
|
||||
ToggleOn()
|
||||
|
||||
if(href_list["toggleUse"])
|
||||
Activate()
|
||||
|
||||
attack_hand(usr)
|
||||
|
||||
/obj/machinery/ai_slipper/proc/slip_process()
|
||||
while(cooldown_time - world.timeofday > 0)
|
||||
var/ticksleft = cooldown_time - world.timeofday
|
||||
|
||||
if(ticksleft > 1e5)
|
||||
cooldown_time = world.timeofday + 10 // midnight rollover
|
||||
|
||||
|
||||
cooldown_timeleft = (ticksleft / 10)
|
||||
sleep(5)
|
||||
if(uses <= 0)
|
||||
return
|
||||
if(uses >= 0)
|
||||
cooldown_on = FALSE
|
||||
cooldown_on = FALSE
|
||||
power_change()
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
max_integrity = 100
|
||||
var/state = 0
|
||||
var/obj/item/circuitboard/circuit = null
|
||||
var/base_mineral = /obj/item/stack/sheet/metal
|
||||
|
||||
/obj/structure/computerframe/deconstruct(disassembled = TRUE)
|
||||
if(!(flags & NODECONSTRUCT))
|
||||
@@ -18,7 +17,7 @@
|
||||
deconstruct()
|
||||
|
||||
/obj/structure/computerframe/proc/drop_computer_parts()
|
||||
new base_mineral(loc, 5)
|
||||
new /obj/item/stack/sheet/metal(loc, 5)
|
||||
if(circuit)
|
||||
circuit.forceMove(loc)
|
||||
circuit = null
|
||||
@@ -357,14 +356,6 @@
|
||||
build_path = /obj/machinery/computer/turbine_computer
|
||||
origin_tech = "programming=4;engineering=4;powerstorage=4"
|
||||
|
||||
/obj/item/circuitboard/HONKputer
|
||||
name = "Circuit board (HONKputer)"
|
||||
build_path = /obj/machinery/computer/HONKputer
|
||||
origin_tech = "programming=2"
|
||||
icon = 'icons/obj/machines/HONKputer.dmi'
|
||||
icon_state = "bananium_board"
|
||||
board_type = "honkcomputer"
|
||||
|
||||
|
||||
/obj/item/circuitboard/supplycomp/attackby(obj/item/I as obj, mob/user as mob, params)
|
||||
if(istype(I,/obj/item/multitool))
|
||||
@@ -552,116 +543,3 @@
|
||||
if(I.use_tool(src, user, 50, volume = I.tool_volume) && !state)
|
||||
to_chat(user, "<span class='notice'>You deconstruct [src].</span>")
|
||||
deconstruct(TRUE)
|
||||
|
||||
|
||||
|
||||
/obj/structure/computerframe/HONKputer
|
||||
name = "Bananium Computer-frame"
|
||||
icon = 'icons/obj/machines/HONKputer.dmi'
|
||||
base_mineral = /obj/item/stack/sheet/mineral/bananium
|
||||
|
||||
/obj/structure/computerframe/HONKputer/attackby(obj/item/P as obj, mob/user as mob, params)
|
||||
switch(state)
|
||||
if(0)
|
||||
if(istype(P, /obj/item/wrench))
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
if(do_after(user, 20, target = src))
|
||||
to_chat(user, "<span class='notice'>You wrench the frame into place.</span>")
|
||||
anchored = 1
|
||||
state = 1
|
||||
if(1)
|
||||
if(istype(P, /obj/item/wrench))
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
if(do_after(user, 20 * P.toolspeed, target = src))
|
||||
to_chat(user, "<span class='notice'>You unfasten the frame.</span>")
|
||||
anchored = 0
|
||||
state = 0
|
||||
if(istype(P, /obj/item/circuitboard) && !circuit)
|
||||
var/obj/item/circuitboard/B = P
|
||||
if(B.board_type == "honkcomputer")
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You place the circuit board inside the frame.</span>")
|
||||
icon_state = "1"
|
||||
circuit = P
|
||||
user.drop_item()
|
||||
P.loc = src
|
||||
else
|
||||
to_chat(user, "<span class='warning'>This frame does not accept circuit boards of this type!</span>")
|
||||
if(istype(P, /obj/item/screwdriver) && circuit)
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You screw the circuit board into place.</span>")
|
||||
state = 2
|
||||
icon_state = "2"
|
||||
if(istype(P, /obj/item/crowbar) && circuit)
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You remove the circuit board.</span>")
|
||||
state = 1
|
||||
icon_state = "0"
|
||||
circuit.loc = loc
|
||||
circuit = null
|
||||
return
|
||||
if(2)
|
||||
if(istype(P, /obj/item/screwdriver) && circuit)
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You unfasten the circuit board.</span>")
|
||||
state = 1
|
||||
icon_state = "1"
|
||||
if(istype(P, /obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/C = P
|
||||
if(C.get_amount() >= 5)
|
||||
playsound(loc, C.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You start to add cables to the frame.</span>")
|
||||
if(do_after(user, 20 * C.toolspeed, target = src))
|
||||
if(state == 2 && C.get_amount() >= 5 && C.use(5))
|
||||
to_chat(user, "<span class='notice'>You add cables to the frame.</span>")
|
||||
state = 3
|
||||
icon_state = "3"
|
||||
else
|
||||
to_chat(user, "<span class='warning'>At some point during construction you lost some cable. Make sure you have five lengths before trying again.</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need five lengths of cable to wire the frame.</span>")
|
||||
return
|
||||
if(3)
|
||||
if(istype(P, /obj/item/wirecutters))
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You remove the cables.</span>")
|
||||
state = 2
|
||||
icon_state = "2"
|
||||
var/obj/item/stack/cable_coil/A = new /obj/item/stack/cable_coil( loc )
|
||||
A.amount = 5
|
||||
|
||||
if(istype(P, /obj/item/stack/sheet/glass))
|
||||
var/obj/item/stack/sheet/glass/G = P
|
||||
if(G.get_amount() >= 2)
|
||||
playsound(loc, G.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You start to add the glass panel to the frame.</span>")
|
||||
if(do_after(user, 20 * G.toolspeed, target = src))
|
||||
if(state == 3 && G.get_amount() >= 2 && G.use(2))
|
||||
to_chat(user, "<span class='notice'>You put in the glass panel.</span>")
|
||||
state = 4
|
||||
icon_state = "4"
|
||||
else
|
||||
to_chat(user, "<span class='warning'>At some point during construction you lost some glass. Make sure you have two sheets before trying again.</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need two sheets of glass for this.</span>")
|
||||
return
|
||||
if(4)
|
||||
if(istype(P, /obj/item/crowbar))
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You remove the glass panel.</span>")
|
||||
state = 3
|
||||
icon_state = "3"
|
||||
new /obj/item/stack/sheet/glass(loc, 2)
|
||||
if(istype(P, /obj/item/screwdriver))
|
||||
playsound(loc, P.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You connect the monitor.</span>")
|
||||
var/B = new circuit.build_path (loc)
|
||||
if(circuit.powernet) B:powernet = circuit.powernet
|
||||
if(circuit.id) B:id = circuit.id
|
||||
if(circuit.records) B:records = circuit.records
|
||||
if(circuit.frequency) B:frequency = circuit.frequency
|
||||
qdel(src)
|
||||
return
|
||||
return ..()
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
|
||||
if(!C.can_use())
|
||||
continue
|
||||
if(C.network&networks)
|
||||
if(length(C.network & networks))
|
||||
camera_location = get_turf(C)
|
||||
break
|
||||
if(camera_location)
|
||||
@@ -101,6 +101,8 @@
|
||||
|
||||
/mob/camera/aiEye/remote
|
||||
name = "Inactive Camera Eye"
|
||||
// Abductors dont trigger the Ai Detector
|
||||
ai_detector_visible = FALSE
|
||||
var/sprint = 10
|
||||
var/cooldown = 0
|
||||
var/acceleration = 1
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
/obj/machinery/computer/HONKputer
|
||||
name = "\improper HONKputer Mark I"
|
||||
desc = "A yellow computer used in case of critically low levels of HONK."
|
||||
icon = 'icons/obj/machines/HONKputer.dmi'
|
||||
icon_state = "honkputer"
|
||||
icon_keyboard = "key_honk"
|
||||
icon_screen = "honkcomms"
|
||||
light_color = LIGHT_COLOR_PINK
|
||||
req_access = list(ACCESS_CLOWN)
|
||||
circuit = /obj/item/circuitboard/HONKputer
|
||||
var/authenticated = 0
|
||||
var/message_cooldown = 0
|
||||
var/state = STATE_DEFAULT
|
||||
var/const/STATE_DEFAULT = 1
|
||||
|
||||
/obj/machinery/computer/HONKputer/process()
|
||||
if(..())
|
||||
src.updateDialog()
|
||||
|
||||
/obj/machinery/computer/HONKputer/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(is_away_level(src.z))
|
||||
to_chat(usr, "<span class='danger'>Unable to establish a connection</span>: You're too far away from the station!")
|
||||
return
|
||||
usr.set_machine(src)
|
||||
|
||||
if(!href_list["operation"])
|
||||
return
|
||||
switch(href_list["operation"])
|
||||
// main interface
|
||||
if("main")
|
||||
src.state = STATE_DEFAULT
|
||||
if("login")
|
||||
var/mob/M = usr
|
||||
var/obj/item/card/id/I = M.get_active_hand()
|
||||
if(istype(I, /obj/item/pda))
|
||||
var/obj/item/pda/pda = I
|
||||
I = pda.id
|
||||
if(I && istype(I))
|
||||
if(src.check_access(I) || src.emagged==1)
|
||||
authenticated = 1
|
||||
if("logout")
|
||||
authenticated = 0
|
||||
|
||||
if("MessageHonkplanet")
|
||||
if(src.authenticated==1)
|
||||
if(message_cooldown)
|
||||
to_chat(usr, "Arrays recycling. Please stand by.")
|
||||
return
|
||||
var/input = stripped_input(usr, "Please choose a message to transmit to your HONKbrothers on the homeworld. Transmission does not guarantee a response.", "To abort, send an empty message.", "")
|
||||
if(!input || !(usr in view(1,src)))
|
||||
return
|
||||
HONK_announce(input, usr)
|
||||
to_chat(usr, "Message transmitted.")
|
||||
log_game("[key_name(usr)] has made a HONKplanet announcement: [input]")
|
||||
message_cooldown = 1
|
||||
spawn(6000)//10 minute cooldown
|
||||
message_cooldown = 0
|
||||
|
||||
src.updateUsrDialog()
|
||||
|
||||
/obj/machinery/computer/HONKputer/emag_act(user as mob)
|
||||
if(!emagged)
|
||||
src.emagged = 1
|
||||
to_chat(user, "You scramble the login circuits, allowing anyone to use the console!")
|
||||
|
||||
/obj/machinery/computer/HONKputer/attack_hand(mob/user as mob)
|
||||
if(..())
|
||||
return
|
||||
if(is_away_level(src.z))
|
||||
to_chat(user, "<span class='danger'>Unable to establish a connection</span>: You're too far away from the station!")
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
var/dat = "<head><title>HONKputer Interface</title></head><body>"
|
||||
|
||||
if(istype(user, /mob/living/silicon))
|
||||
to_chat(user, "This console is not networked to the rest of the grid.")
|
||||
return
|
||||
|
||||
switch(src.state)
|
||||
if(STATE_DEFAULT)
|
||||
if(src.authenticated)
|
||||
dat += "<BR>\[ <A HREF='?src=[UID()];operation=logout'>Log Out</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=[UID()];operation=MessageHonkplanet'>Send an emergency message to Honkplanet</A> \]"
|
||||
else
|
||||
dat += "<BR>\[ <A HREF='?src=[UID()];operation=login'>Log In</A> \]"
|
||||
|
||||
|
||||
dat += "<BR>\[ [(src.state != STATE_DEFAULT) ? "<A HREF='?src=[UID()];operation=main'>Main Menu</A> | " : ""]<A HREF='?src=[user.UID()];mach_close=honkputer'>Close</A> \]"
|
||||
user << browse(dat, "window=honkputer;size=400x500")
|
||||
onclose(user, "honkputer")
|
||||
|
||||
|
||||
/obj/machinery/computer/HONKputer/attackby(obj/I, mob/user, params)
|
||||
if(istype(I, /obj/item/screwdriver) && circuit)
|
||||
var/obj/item/screwdriver/S = I
|
||||
playsound(src.loc, S.usesound, 50, 1)
|
||||
if(do_after(user, 20 * S.toolspeed, target = src))
|
||||
var/obj/structure/computerframe/HONKputer/A = new /obj/structure/computerframe/HONKputer( src.loc )
|
||||
var/obj/item/circuitboard/M = new circuit( A )
|
||||
A.circuit = M
|
||||
A.anchored = 1
|
||||
for(var/obj/C in src)
|
||||
C.loc = src.loc
|
||||
if(src.stat & BROKEN)
|
||||
to_chat(user, "<span class='notice'>The broken glass falls out.</span>")
|
||||
new /obj/item/shard( src.loc )
|
||||
A.state = 3
|
||||
A.icon_state = "3"
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You disconnect the monitor.</span>")
|
||||
A.state = 4
|
||||
A.icon_state = "4"
|
||||
qdel(src)
|
||||
else
|
||||
return ..()
|
||||
@@ -1,110 +0,0 @@
|
||||
#define SALVAGE_SHIP_MOVE_TIME 300
|
||||
#define SALVAGE_SHIP_COOLDOWN 800
|
||||
|
||||
/obj/machinery/computer/salvage_ship
|
||||
name = "salvage ship terminal"
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_keyboard = "syndie_key"
|
||||
icon_screen = "syndishuttle"
|
||||
req_access = list(ACCESS_SALVAGE_CAPTAIN)
|
||||
var/area/curr_location
|
||||
var/moving = 0
|
||||
var/lastMove = 0
|
||||
|
||||
|
||||
/obj/machinery/computer/salvage_ship/New()
|
||||
. = ..()
|
||||
curr_location = locate(/area/shuttle/salvage/start)
|
||||
|
||||
|
||||
/obj/machinery/computer/salvage_ship/proc/salvage_move_to(area/destination as area)
|
||||
if(moving) return
|
||||
if(lastMove + SALVAGE_SHIP_COOLDOWN > world.time) return
|
||||
var/area/dest_location = locate(destination)
|
||||
if(curr_location == dest_location) return
|
||||
|
||||
moving = 1
|
||||
lastMove = world.time
|
||||
|
||||
if(curr_location.z != dest_location.z)
|
||||
var/area/transit_location = locate(/area/shuttle/salvage/transit)
|
||||
curr_location.move_contents_to(transit_location)
|
||||
curr_location = transit_location
|
||||
sleep(SALVAGE_SHIP_MOVE_TIME)
|
||||
|
||||
curr_location.move_contents_to(dest_location)
|
||||
curr_location = dest_location
|
||||
moving = 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/salvage_ship/attack_ai(mob/user as mob)
|
||||
src.add_hiddenprint(user)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/computer/salvage_ship/attack_hand(mob/user as mob)
|
||||
if(!allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access Denied</span>")
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
|
||||
var/dat = {"Location: [curr_location]<br>
|
||||
Ready to move[max(lastMove + SALVAGE_SHIP_COOLDOWN - world.time, 0) ? " in [max(round((lastMove + SALVAGE_SHIP_COOLDOWN - world.time) * 0.1), 0)] seconds" : ": now"]<br>
|
||||
<a href='?src=[UID()];start=1'>Middle of Nowhere</a><br>
|
||||
<a href='?src=[UID()];arrivals=1'>Station Auxiliary Docking</a> |
|
||||
<a href='?src=[UID()];north=1'>North of the Station</a> |
|
||||
<a href='?src=[UID()];east=1'>East of the Station</a> |
|
||||
<a href='?src=[UID()];south=1'>South of the Station</a><br>
|
||||
<a href='?src=[UID()];trading_post=1'>Trading Post</a><br>
|
||||
<a href='?src=[UID()];clown_asteroid=1'>Clown Asteroid</a> |
|
||||
<a href='?src=[UID()];derelict=1'>Derelict Station</a> |
|
||||
<a href='?src=[UID()];djstation=1'>Ruskie DJ Station</a><br>
|
||||
<a href='?src=[UID()];commssat=1'>Communications Satellite</a> |
|
||||
<a href='?src=[UID()];abandoned_ship=1'>Abandoned Ship</a><br>
|
||||
<a href='?src=[user.UID()];mach_close=computer'>Close</a>"}
|
||||
|
||||
user << browse(dat, "window=computer;size=575x450")
|
||||
onclose(user, "computer")
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/computer/salvage_ship/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(!isliving(usr)) return
|
||||
var/mob/living/user = usr
|
||||
|
||||
if(in_range(src, user) || istype(user, /mob/living/silicon))
|
||||
user.set_machine(src)
|
||||
|
||||
if(href_list["salvage"])
|
||||
salvage_move_to(/area/shuttle/salvage/start)
|
||||
else if(href_list["start"])
|
||||
salvage_move_to(/area/shuttle/salvage/start)
|
||||
else if(href_list["arrivals"])
|
||||
salvage_move_to(/area/shuttle/salvage/arrivals)
|
||||
else if(href_list["derelict"])
|
||||
salvage_move_to(/area/shuttle/salvage/derelict)
|
||||
else if(href_list["djstation"])
|
||||
salvage_move_to(/area/shuttle/salvage/djstation)
|
||||
else if(href_list["north"])
|
||||
salvage_move_to(/area/shuttle/salvage/north)
|
||||
else if(href_list["east"])
|
||||
salvage_move_to(/area/shuttle/salvage/east)
|
||||
else if(href_list["south"])
|
||||
salvage_move_to(/area/shuttle/salvage/south)
|
||||
else if(href_list["commssat"])
|
||||
salvage_move_to(/area/shuttle/salvage/commssat)
|
||||
else if(href_list["abandoned_ship"])
|
||||
salvage_move_to(/area/shuttle/salvage/abandoned_ship)
|
||||
else if(href_list["clown_asteroid"])
|
||||
salvage_move_to(/area/shuttle/salvage/clown_asteroid)
|
||||
else if(href_list["trading_post"])
|
||||
salvage_move_to(/area/shuttle/salvage/trading_post)
|
||||
|
||||
add_fingerprint(usr)
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/salvage_ship/bullet_act(obj/item/projectile/Proj)
|
||||
visible_message("[Proj] ricochets off [src]!")
|
||||
@@ -1,338 +0,0 @@
|
||||
//Config stuff
|
||||
#define SPECOPS_MOVETIME 600 //Time to station is milliseconds. 60 seconds, enough time for everyone to be on the shuttle before it leaves.
|
||||
#define SPECOPS_STATION_AREATYPE "/area/shuttle/specops/station" //Type of the spec ops shuttle area for station
|
||||
#define SPECOPS_DOCK_AREATYPE "/area/shuttle/specops/centcom" //Type of the spec ops shuttle area for dock
|
||||
#define SPECOPS_RETURN_DELAY 6000 //Time between the shuttle is capable of moving.
|
||||
|
||||
GLOBAL_VAR_INIT(specops_shuttle_moving_to_station, 0)
|
||||
GLOBAL_VAR_INIT(specops_shuttle_moving_to_centcom, 0)
|
||||
GLOBAL_VAR_INIT(specops_shuttle_at_station, 0)
|
||||
GLOBAL_VAR_INIT(specops_shuttle_can_send, 1)
|
||||
GLOBAL_VAR_INIT(specops_shuttle_time, 0)
|
||||
GLOBAL_VAR_INIT(specops_shuttle_timeleft, 0)
|
||||
|
||||
/obj/machinery/computer/specops_shuttle
|
||||
name = "\improper Spec. Ops. shuttle console"
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_keyboard = "security_key"
|
||||
icon_screen = "syndishuttle"
|
||||
light_color = LIGHT_COLOR_PURE_CYAN
|
||||
req_access = list(ACCESS_CENT_SPECOPS)
|
||||
// req_access = list(ACCESS_CENT_SPECOPS)
|
||||
var/temp = null
|
||||
var/hacked = 0
|
||||
var/allowedtocall = 0
|
||||
var/specops_shuttle_timereset = 0
|
||||
|
||||
/proc/specops_return()
|
||||
var/obj/item/radio/intercom/announcer = new /obj/item/radio/intercom(null)//We need a fake AI to announce some stuff below. Otherwise it will be wonky.
|
||||
announcer.config(list("Response Team" = 0))
|
||||
|
||||
var/message_tracker[] = list(0,1,2,3,5,10,30,45)//Create a a list with potential time values.
|
||||
var/message = "\"THE SPECIAL OPERATIONS SHUTTLE IS PREPARING TO RETURN\""//Initial message shown.
|
||||
if(announcer)
|
||||
announcer.autosay(message, "A.L.I.C.E.", "Response Team", list(1,2))
|
||||
|
||||
while(GLOB.specops_shuttle_time - world.timeofday > 0)
|
||||
var/ticksleft = GLOB.specops_shuttle_time - world.timeofday
|
||||
|
||||
if(ticksleft > 1e5)
|
||||
GLOB.specops_shuttle_time = world.timeofday + 10 // midnight rollover
|
||||
GLOB.specops_shuttle_timeleft = (ticksleft / 10)
|
||||
|
||||
//All this does is announce the time before launch.
|
||||
if(announcer)
|
||||
var/rounded_time_left = round(GLOB.specops_shuttle_timeleft)//Round time so that it will report only once, not in fractions.
|
||||
if(rounded_time_left in message_tracker)//If that time is in the list for message announce.
|
||||
message = "\"ALERT: [rounded_time_left] SECOND[(rounded_time_left!=1)?"S":""] REMAIN\""
|
||||
if(rounded_time_left==0)
|
||||
message = "\"ALERT: TAKEOFF\""
|
||||
announcer.autosay(message, "A.L.I.C.E.", "Response Team")
|
||||
message_tracker -= rounded_time_left//Remove the number from the list so it won't be called again next cycle.
|
||||
//Should call all the numbers but lag could mean some issues. Oh well. Not much I can do about that.
|
||||
|
||||
sleep(5)
|
||||
|
||||
GLOB.specops_shuttle_moving_to_station = 0
|
||||
GLOB.specops_shuttle_moving_to_centcom = 0
|
||||
|
||||
GLOB.specops_shuttle_at_station = 1
|
||||
|
||||
var/area/start_location = locate(/area/shuttle/specops/station)
|
||||
var/area/end_location = locate(/area/shuttle/specops/centcom)
|
||||
|
||||
var/list/dstturfs = list()
|
||||
var/throwy = world.maxy
|
||||
|
||||
for(var/turf/T in end_location)
|
||||
dstturfs += T
|
||||
if(T.y < throwy)
|
||||
throwy = T.y
|
||||
|
||||
// hey you, get out of the way!
|
||||
for(var/turf/T in dstturfs)
|
||||
// find the turf to move things to
|
||||
var/turf/D = locate(T.x, throwy - 1, 1)
|
||||
//var/turf/E = get_step(D, SOUTH)
|
||||
for(var/atom/movable/AM as mob|obj in T)
|
||||
AM.Move(D)
|
||||
if(istype(T, /turf/simulated))
|
||||
qdel(T)
|
||||
|
||||
for(var/mob/living/carbon/bug in end_location) // If someone somehow is still in the shuttle's docking area...
|
||||
bug.gib()
|
||||
|
||||
for(var/mob/living/simple_animal/pest in end_location) // And for the other kind of bug...
|
||||
pest.gib()
|
||||
|
||||
start_location.move_contents_to(end_location)
|
||||
|
||||
for(var/turf/T in get_area_turfs(end_location) )
|
||||
var/mob/M = locate(/mob) in T
|
||||
to_chat(M, "<span class='warning'>You have arrived at Central Command. Operation has ended!</span>")
|
||||
|
||||
GLOB.specops_shuttle_at_station = 0
|
||||
|
||||
for(var/obj/machinery/computer/specops_shuttle/S in GLOB.machines)
|
||||
S.specops_shuttle_timereset = world.time + SPECOPS_RETURN_DELAY
|
||||
|
||||
qdel(announcer)
|
||||
|
||||
/proc/specops_process()
|
||||
var/area/centcom/specops/special_ops = locate()//Where is the specops area located?
|
||||
var/obj/item/radio/intercom/announcer = new /obj/item/radio/intercom(null)//We need a fake AI to announce some stuff below. Otherwise it will be wonky.
|
||||
announcer.config(list("Response Team" = 0))
|
||||
|
||||
var/message_tracker[] = list(0,1,2,3,5,10,30,45)//Create a a list with potential time values.
|
||||
var/message = "\"THE SPECIAL OPERATIONS SHUTTLE IS PREPARING FOR LAUNCH\""//Initial message shown.
|
||||
if(announcer)
|
||||
announcer.autosay(message, "A.L.I.C.E.", "Response Team")
|
||||
//message = "ARMORED SQUAD TAKE YOUR POSITION ON GRAVITY LAUNCH PAD"
|
||||
//announcer.autosay(message, "A.L.I.C.E.", "Response Team")
|
||||
|
||||
while(GLOB.specops_shuttle_time - world.timeofday > 0)
|
||||
var/ticksleft = GLOB.specops_shuttle_time - world.timeofday
|
||||
|
||||
if(ticksleft > 1e5)
|
||||
GLOB.specops_shuttle_time = world.timeofday + 10 // midnight rollover
|
||||
GLOB.specops_shuttle_timeleft = (ticksleft / 10)
|
||||
|
||||
//All this does is announce the time before launch.
|
||||
if(announcer)
|
||||
var/rounded_time_left = round(GLOB.specops_shuttle_timeleft)//Round time so that it will report only once, not in fractions.
|
||||
if(rounded_time_left in message_tracker)//If that time is in the list for message announce.
|
||||
message = "\"ALERT: [rounded_time_left] SECOND[(rounded_time_left!=1)?"S":""] REMAIN\""
|
||||
if(rounded_time_left==0)
|
||||
message = "\"ALERT: TAKEOFF\""
|
||||
announcer.autosay(message, "A.L.I.C.E.", "Response Team")
|
||||
message_tracker -= rounded_time_left//Remove the number from the list so it won't be called again next cycle.
|
||||
//Should call all the numbers but lag could mean some issues. Oh well. Not much I can do about that.
|
||||
|
||||
sleep(5)
|
||||
|
||||
GLOB.specops_shuttle_moving_to_station = 0
|
||||
GLOB.specops_shuttle_moving_to_centcom = 0
|
||||
|
||||
GLOB.specops_shuttle_at_station = 1
|
||||
if(GLOB.specops_shuttle_moving_to_station || GLOB.specops_shuttle_moving_to_centcom) return
|
||||
|
||||
if(!specops_can_move())
|
||||
to_chat(usr, "<span class='warning'>The Special Operations shuttle is unable to leave.</span>")
|
||||
return
|
||||
|
||||
//Begin Marauder launchpad.
|
||||
spawn(0)//So it parallel processes it.
|
||||
for(var/obj/machinery/door/poddoor/M in special_ops)
|
||||
switch(M.id_tag)
|
||||
if("ASSAULT0")
|
||||
spawn(10)//1 second delay between each.
|
||||
M.open()
|
||||
if("ASSAULT1")
|
||||
spawn(20)
|
||||
M.open()
|
||||
if("ASSAULT2")
|
||||
spawn(30)
|
||||
M.open()
|
||||
if("ASSAULT3")
|
||||
spawn(40)
|
||||
M.open()
|
||||
|
||||
sleep(10)
|
||||
|
||||
var/spawn_marauder[] = new()
|
||||
for(var/thing in GLOB.landmarks_list)
|
||||
var/obj/effect/landmark/L = thing
|
||||
if(L.name == "Marauder Entry")
|
||||
spawn_marauder.Add(L.loc)
|
||||
for(var/thing in GLOB.landmarks_list)
|
||||
var/obj/effect/landmark/L = thing
|
||||
if(L.name == "Marauder Exit")
|
||||
var/obj/effect/portal/P = new(L.loc, pick(spawn_marauder))
|
||||
//P.invisibility = 101//So it is not seen by anyone.
|
||||
P.failchance = 0//So it has no fail chance when teleporting.
|
||||
spawn_marauder.Remove(P.target)
|
||||
|
||||
sleep(10)
|
||||
|
||||
for(var/obj/machinery/mass_driver/M in special_ops)
|
||||
switch(M.id_tag)
|
||||
if("ASSAULT0")
|
||||
spawn(10)
|
||||
M.drive()
|
||||
if("ASSAULT1")
|
||||
spawn(20)
|
||||
M.drive()
|
||||
if("ASSAULT2")
|
||||
spawn(30)
|
||||
M.drive()
|
||||
if("ASSAULT3")
|
||||
spawn(40)
|
||||
M.drive()
|
||||
|
||||
sleep(50)//Doors remain open for 5 seconds.
|
||||
|
||||
for(var/obj/machinery/door/poddoor/M in special_ops)
|
||||
switch(M.id_tag)//Doors close at the same time.
|
||||
if("ASSAULT0")
|
||||
spawn(0)
|
||||
M.close()
|
||||
if("ASSAULT1")
|
||||
spawn(0)
|
||||
M.close()
|
||||
if("ASSAULT2")
|
||||
spawn(0)
|
||||
M.close()
|
||||
if("ASSAULT3")
|
||||
spawn(0)
|
||||
M.close()
|
||||
//End Marauder launchpad.
|
||||
|
||||
var/area/start_location = locate(/area/shuttle/specops/centcom)
|
||||
var/area/end_location = locate(/area/shuttle/specops/station)
|
||||
|
||||
var/list/dstturfs = list()
|
||||
var/throwy = world.maxy
|
||||
|
||||
for(var/turf/T in end_location)
|
||||
dstturfs += T
|
||||
if(T.y < throwy)
|
||||
throwy = T.y
|
||||
|
||||
// hey you, get out of the way!
|
||||
for(var/turf/T in dstturfs)
|
||||
// find the turf to move things to
|
||||
var/turf/D = locate(T.x, throwy - 1, 1)
|
||||
//var/turf/E = get_step(D, SOUTH)
|
||||
for(var/atom/movable/AM as mob|obj in T)
|
||||
AM.Move(D)
|
||||
if(istype(T, /turf/simulated))
|
||||
qdel(T)
|
||||
|
||||
start_location.move_contents_to(end_location)
|
||||
|
||||
for(var/turf/T in get_area_turfs(end_location) )
|
||||
var/mob/M = locate(/mob) in T
|
||||
to_chat(M, "<span class='warning'>You have arrived to [station_name()]. Commence operation!</span>")
|
||||
|
||||
for(var/obj/machinery/computer/specops_shuttle/S in GLOB.machines)
|
||||
S.specops_shuttle_timereset = world.time + SPECOPS_RETURN_DELAY
|
||||
|
||||
qdel(announcer)
|
||||
|
||||
/proc/specops_can_move()
|
||||
if(GLOB.specops_shuttle_moving_to_station || GLOB.specops_shuttle_moving_to_centcom)
|
||||
return 0
|
||||
for(var/obj/machinery/computer/specops_shuttle/S in GLOB.machines)
|
||||
if(world.timeofday <= S.specops_shuttle_timereset)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/specops_shuttle/attack_ai(mob/user as mob)
|
||||
to_chat(user, "<span class='warning'>Access Denied.</span>")
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/specops_shuttle/attackby(I as obj, user as mob, params)
|
||||
if(istype(I,/obj/item/card/emag))
|
||||
to_chat(user, "<span class='notice'>The electronic systems in this console are far too advanced for your primitive hacking peripherals.</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/specops_shuttle/attack_hand(mob/user as mob)
|
||||
if(!allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access Denied.</span>")
|
||||
return
|
||||
|
||||
//Commented out so admins can do shenanigans at their leisure. Also makes the force-spawned admin ERTs able to use the shuttle.
|
||||
// if(sent_strike_team == 0 && send_emergency_team == 0)
|
||||
// to_chat(usr, "<span class='warning'>The strike team has not yet deployed.</span>")
|
||||
// return
|
||||
|
||||
if(..())
|
||||
return
|
||||
|
||||
user.machine = src
|
||||
var/dat
|
||||
if(temp)
|
||||
dat = temp
|
||||
else
|
||||
dat += {"<BR><B>Special Operations Shuttle</B><HR>
|
||||
\nLocation: [GLOB.specops_shuttle_moving_to_station || GLOB.specops_shuttle_moving_to_centcom ? "Departing for [station_name()] in ([GLOB.specops_shuttle_timeleft] seconds.)":GLOB.specops_shuttle_at_station ? "Station":"Dock"]<BR>
|
||||
[GLOB.specops_shuttle_moving_to_station || GLOB.specops_shuttle_moving_to_centcom ? "\n*The Special Ops. shuttle is already leaving.*<BR>\n<BR>":GLOB.specops_shuttle_at_station ? "\n<A href='?src=[UID()];sendtodock=1'>Shuttle standing by...</A><BR>\n<BR>":"\n<A href='?src=[UID()];sendtostation=1'>Depart to [station_name()]</A><BR>\n<BR>"]
|
||||
\n<A href='?src=[user.UID()];mach_close=computer'>Close</A>"}
|
||||
|
||||
user << browse(dat, "window=computer;size=575x450")
|
||||
onclose(user, "computer")
|
||||
return
|
||||
|
||||
/obj/machinery/computer/specops_shuttle/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon)))
|
||||
usr.machine = src
|
||||
|
||||
if(href_list["sendtodock"])
|
||||
if(!GLOB.specops_shuttle_at_station|| GLOB.specops_shuttle_moving_to_station || GLOB.specops_shuttle_moving_to_centcom) return
|
||||
|
||||
if(!specops_can_move())
|
||||
to_chat(usr, "<span class='notice'>Central Command will not allow the Special Operations shuttle to return yet.</span>")
|
||||
if(world.timeofday <= specops_shuttle_timereset)
|
||||
if(((world.timeofday - specops_shuttle_timereset)/10) > 60)
|
||||
to_chat(usr, "<span class='notice'>[-((world.timeofday - specops_shuttle_timereset)/10)/60] minutes remain!</span>")
|
||||
to_chat(usr, "<span class='notice'>[-(world.timeofday - specops_shuttle_timereset)/10] seconds remain!</span>")
|
||||
return
|
||||
|
||||
to_chat(usr, "<span class='notice'>The Special Operations shuttle will arrive at Central Command in [(SPECOPS_MOVETIME/10)] seconds.</span>")
|
||||
|
||||
temp += "Shuttle departing.<BR><BR><A href='?src=[UID()];mainmenu=1'>OK</A>"
|
||||
updateUsrDialog()
|
||||
|
||||
GLOB.specops_shuttle_moving_to_centcom = 1
|
||||
GLOB.specops_shuttle_time = world.timeofday + SPECOPS_MOVETIME
|
||||
spawn(0)
|
||||
specops_return()
|
||||
|
||||
else if(href_list["sendtostation"])
|
||||
if(GLOB.specops_shuttle_at_station || GLOB.specops_shuttle_moving_to_station || GLOB.specops_shuttle_moving_to_centcom) return
|
||||
|
||||
if(!specops_can_move())
|
||||
to_chat(usr, "<span class='warning'>The Special Operations shuttle is unable to leave.</span>")
|
||||
return
|
||||
|
||||
to_chat(usr, "<span class='notice'>The Special Operations shuttle will arrive on [station_name()] in [(SPECOPS_MOVETIME/10)] seconds.</span>")
|
||||
|
||||
temp += "Shuttle departing.<BR><BR><A href='?src=[UID()];mainmenu=1'>OK</A>"
|
||||
updateUsrDialog()
|
||||
|
||||
GLOB.specops_shuttle_moving_to_station = 1
|
||||
|
||||
GLOB.specops_shuttle_time = world.timeofday + SPECOPS_MOVETIME
|
||||
spawn(0)
|
||||
specops_process()
|
||||
|
||||
else if(href_list["mainmenu"])
|
||||
temp = null
|
||||
|
||||
add_fingerprint(usr)
|
||||
updateUsrDialog()
|
||||
return
|
||||
@@ -1,254 +0,0 @@
|
||||
//Config stuff
|
||||
#define SYNDICATE_ELITE_MOVETIME 600 //Time to station is milliseconds. 60 seconds, enough time for everyone to be on the shuttle before it leaves.
|
||||
#define SYNDICATE_ELITE_STATION_AREATYPE "/area/shuttle/syndicate_elite/station" //Type of the spec ops shuttle area for station
|
||||
#define SYNDICATE_ELITE_DOCK_AREATYPE "/area/shuttle/syndicate_elite/mothership" //Type of the spec ops shuttle area for dock
|
||||
|
||||
GLOBAL_VAR_INIT(syndicate_elite_shuttle_moving_to_station, 0)
|
||||
GLOBAL_VAR_INIT(syndicate_elite_shuttle_moving_to_mothership, 0)
|
||||
GLOBAL_VAR_INIT(syndicate_elite_shuttle_at_station, 0)
|
||||
GLOBAL_VAR_INIT(syndicate_elite_shuttle_can_send, 1)
|
||||
GLOBAL_VAR_INIT(syndicate_elite_shuttle_time, 0)
|
||||
GLOBAL_VAR_INIT(syndicate_elite_shuttle_timeleft, 0)
|
||||
|
||||
/obj/machinery/computer/syndicate_elite_shuttle
|
||||
name = "\improper Elite Syndicate Squad shuttle console"
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_keyboard = "syndie_key"
|
||||
icon_screen = "syndishuttle"
|
||||
light_color = LIGHT_COLOR_PURE_CYAN
|
||||
req_access = list(ACCESS_SYNDICATE)
|
||||
bubble_icon = "syndibot"
|
||||
var/temp = null
|
||||
var/hacked = 0
|
||||
var/allowedtocall = 0
|
||||
|
||||
/proc/syndicate_elite_process()
|
||||
var/area/syndicate_mothership/control/syndicate_ship = locate()//To find announcer. This area should exist for this proc to work.
|
||||
//var/area/syndicate_mothership/elite_squad/elite_squad = locate()//Where is the specops area located?
|
||||
var/mob/living/silicon/decoy/announcer = locate() in syndicate_ship//We need a fake AI to announce some stuff below. Otherwise it will be wonky.
|
||||
|
||||
var/message_tracker[] = list(0,1,2,3,5,10,30,45)//Create a a list with potential time values.
|
||||
var/message = "THE SYNDICATE ELITE SHUTTLE IS PREPARING FOR LAUNCH"//Initial message shown.
|
||||
if(announcer)
|
||||
announcer.say(message)
|
||||
// message = "ARMORED SQUAD TAKE YOUR POSITION ON GRAVITY LAUNCH PAD"
|
||||
// announcer.say(message)
|
||||
|
||||
while(GLOB.syndicate_elite_shuttle_time - world.timeofday > 0)
|
||||
var/ticksleft = GLOB.syndicate_elite_shuttle_time - world.timeofday
|
||||
|
||||
if(ticksleft > 1e5)
|
||||
GLOB.syndicate_elite_shuttle_time = world.timeofday // midnight rollover
|
||||
GLOB.syndicate_elite_shuttle_timeleft = (ticksleft / 10)
|
||||
|
||||
//All this does is announce the time before launch.
|
||||
if(announcer)
|
||||
var/rounded_time_left = round(GLOB.syndicate_elite_shuttle_timeleft)//Round time so that it will report only once, not in fractions.
|
||||
if(rounded_time_left in message_tracker)//If that time is in the list for message announce.
|
||||
message = "ALERT: [rounded_time_left] SECOND[(rounded_time_left!=1)?"S":""] REMAIN"
|
||||
if(rounded_time_left==0)
|
||||
message = "ALERT: TAKEOFF"
|
||||
announcer.say(message)
|
||||
message_tracker -= rounded_time_left//Remove the number from the list so it won't be called again next cycle.
|
||||
//Should call all the numbers but lag could mean some issues. Oh well. Not much I can do about that.
|
||||
|
||||
sleep(5)
|
||||
|
||||
GLOB.syndicate_elite_shuttle_moving_to_station = 0
|
||||
GLOB.syndicate_elite_shuttle_moving_to_mothership = 0
|
||||
|
||||
GLOB.syndicate_elite_shuttle_at_station = 1
|
||||
if(GLOB.syndicate_elite_shuttle_moving_to_station || GLOB.syndicate_elite_shuttle_moving_to_mothership) return
|
||||
|
||||
if(!syndicate_elite_can_move())
|
||||
to_chat(usr, "<span class='warning'>The Syndicate Elite shuttle is unable to leave.</span>")
|
||||
return
|
||||
|
||||
/*
|
||||
//Begin Marauder launchpad.
|
||||
spawn(0)//So it parallel processes it.
|
||||
for(var/obj/machinery/door/poddoor/M in elite_squad)
|
||||
switch(M.id)
|
||||
if("ASSAULT0")
|
||||
spawn(10)//1 second delay between each.
|
||||
M.open()
|
||||
if("ASSAULT1")
|
||||
spawn(20)
|
||||
M.open()
|
||||
if("ASSAULT2")
|
||||
spawn(30)
|
||||
M.open()
|
||||
if("ASSAULT3")
|
||||
spawn(40)
|
||||
M.open()
|
||||
|
||||
sleep(10)
|
||||
|
||||
var/spawn_marauder[] = new()
|
||||
for(var/obj/effect/landmark/L in GLOB.landmarks_list)
|
||||
if(L.name == "Marauder Entry")
|
||||
spawn_marauder.Add(L)
|
||||
for(var/obj/effect/landmark/L in GLOB.landmarks_list)
|
||||
if(L.name == "Marauder Exit")
|
||||
var/obj/effect/portal/P = new(L.loc)
|
||||
P.invisibility = 101//So it is not seen by anyone.
|
||||
P.failchance = 0//So it has no fail chance when teleporting.
|
||||
P.target = pick(spawn_marauder)//Where the marauder will arrive.
|
||||
spawn_marauder.Remove(P.target)
|
||||
|
||||
sleep(10)
|
||||
|
||||
for(var/obj/machinery/mass_driver/M in elite_squad)
|
||||
switch(M.id)
|
||||
if("ASSAULT0")
|
||||
spawn(10)
|
||||
M.drive()
|
||||
if("ASSAULT1")
|
||||
spawn(20)
|
||||
M.drive()
|
||||
if("ASSAULT2")
|
||||
spawn(30)
|
||||
M.drive()
|
||||
if("ASSAULT3")
|
||||
spawn(40)
|
||||
M.drive()
|
||||
|
||||
sleep(50)//Doors remain open for 5 seconds.
|
||||
|
||||
for(var/obj/machinery/door/poddoor/M in elite_squad)
|
||||
switch(M.id)//Doors close at the same time.
|
||||
if("ASSAULT0")
|
||||
spawn(0)
|
||||
M.close()
|
||||
if("ASSAULT1")
|
||||
spawn(0)
|
||||
M.close()
|
||||
if("ASSAULT2")
|
||||
spawn(0)
|
||||
M.close()
|
||||
if("ASSAULT3")
|
||||
spawn(0)
|
||||
M.close()
|
||||
elite_squad.readyreset()//Reset firealarm after the team launched.
|
||||
*/
|
||||
//End Marauder launchpad.
|
||||
|
||||
for(var/thing in GLOB.landmarks_list)
|
||||
var/obj/effect/landmark/L = thing
|
||||
if(L.name == "Syndicate Breach Area")
|
||||
explosion(L.loc,4,6,8,10,0)
|
||||
|
||||
sleep(40)
|
||||
|
||||
|
||||
var/area/start_location = locate(/area/shuttle/syndicate_elite/mothership)
|
||||
var/area/end_location = locate(/area/shuttle/syndicate_elite/station)
|
||||
|
||||
var/list/dstturfs = list()
|
||||
var/throwy = world.maxy
|
||||
|
||||
for(var/turf/T in end_location)
|
||||
dstturfs = T
|
||||
if(T.y < throwy)
|
||||
throwy = T.y
|
||||
|
||||
// hey you, get out of the way!
|
||||
for(var/turf/T in dstturfs)
|
||||
// find the turf to move things to
|
||||
var/turf/D = locate(T.x, throwy - 1, 1)
|
||||
//var/turf/E = get_step(D, SOUTH)
|
||||
for(var/atom/movable/AM as mob|obj in T)
|
||||
AM.Move(D)
|
||||
if(istype(T, /turf/simulated))
|
||||
qdel(T)
|
||||
|
||||
for(var/mob/living/carbon/bug in end_location) // If someone somehow is still in the shuttle's docking area...
|
||||
bug.gib()
|
||||
|
||||
for(var/mob/living/simple_animal/pest in end_location) // And for the other kind of bug...
|
||||
pest.gib()
|
||||
|
||||
start_location.move_contents_to(end_location)
|
||||
|
||||
for(var/turf/T in get_area_turfs(end_location) )
|
||||
var/mob/M = locate(/mob) in T
|
||||
to_chat(M, "<span class='warning'>You have arrived to [station_name()]. Commence operation!</span>")
|
||||
|
||||
/proc/syndicate_elite_can_move()
|
||||
if(GLOB.syndicate_elite_shuttle_moving_to_station || GLOB.syndicate_elite_shuttle_moving_to_mothership) return 0
|
||||
else return 1
|
||||
|
||||
/obj/machinery/computer/syndicate_elite_shuttle/attack_ai(mob/user as mob)
|
||||
to_chat(user, "<span class='warning'>Access Denied.</span>")
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/syndicate_elite_shuttle/attackby(I as obj, user as mob, params)
|
||||
if(istype(I,/obj/item/card/emag))
|
||||
to_chat(user, "<span class='notice'>The electronic systems in this console are far too advanced for your primitive hacking peripherals.</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/syndicate_elite_shuttle/attack_hand(mob/user as mob)
|
||||
if(!allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access Denied.</span>")
|
||||
return
|
||||
|
||||
// if(sent_syndicate_strike_team == 0)
|
||||
// to_chat(usr, "<span class='warning'>The strike team has not yet deployed.</span>")
|
||||
// return
|
||||
|
||||
if(..())
|
||||
return
|
||||
|
||||
user.set_machine(src)
|
||||
var/dat
|
||||
if(temp)
|
||||
dat = temp
|
||||
else
|
||||
dat = {"<BR><B>Special Operations Shuttle</B><HR>
|
||||
\nLocation: [GLOB.syndicate_elite_shuttle_moving_to_station || GLOB.syndicate_elite_shuttle_moving_to_mothership ? "Departing for [station_name()] in ([GLOB.syndicate_elite_shuttle_timeleft] seconds.)":GLOB.syndicate_elite_shuttle_at_station ? "Station":"Dock"]<BR>
|
||||
[GLOB.syndicate_elite_shuttle_moving_to_station || GLOB.syndicate_elite_shuttle_moving_to_mothership ? "\n*The Syndicate Elite shuttle is already leaving.*<BR>\n<BR>":GLOB.syndicate_elite_shuttle_at_station ? "\n<A href='?src=[UID()];sendtodock=1'>Shuttle Offline</A><BR>\n<BR>":"\n<A href='?src=[UID()];sendtostation=1'>Depart to [station_name()]</A><BR>\n<BR>"]
|
||||
\n<A href='?src=[user.UID()];mach_close=computer'>Close</A>"}
|
||||
|
||||
user << browse(dat, "window=computer;size=575x450")
|
||||
onclose(user, "computer")
|
||||
return
|
||||
|
||||
/obj/machinery/computer/syndicate_elite_shuttle/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon)))
|
||||
usr.set_machine(src)
|
||||
|
||||
if(href_list["sendtodock"])
|
||||
if(!GLOB.syndicate_elite_shuttle_at_station|| GLOB.syndicate_elite_shuttle_moving_to_station || GLOB.syndicate_elite_shuttle_moving_to_mothership) return
|
||||
|
||||
to_chat(usr, "<span class='notice'>The Syndicate will not allow the Elite Squad shuttle to return.</span>")
|
||||
return
|
||||
|
||||
else if(href_list["sendtostation"])
|
||||
if(GLOB.syndicate_elite_shuttle_at_station || GLOB.syndicate_elite_shuttle_moving_to_station || GLOB.syndicate_elite_shuttle_moving_to_mothership) return
|
||||
|
||||
if(!specops_can_move())
|
||||
to_chat(usr, "<span class='warning'>The Syndicate Elite shuttle is unable to leave.</span>")
|
||||
return
|
||||
|
||||
to_chat(usr, "<span class='notice'>The Syndicate Elite shuttle will arrive on [station_name()] in [(SYNDICATE_ELITE_MOVETIME/10)] seconds.</span>")
|
||||
|
||||
temp = "Shuttle departing.<BR><BR><A href='?src=[UID()];mainmenu=1'>OK</A>"
|
||||
updateUsrDialog()
|
||||
|
||||
GLOB.syndicate_elite_shuttle_moving_to_station = 1
|
||||
|
||||
GLOB.syndicate_elite_shuttle_time = world.timeofday + SYNDICATE_ELITE_MOVETIME
|
||||
spawn(0)
|
||||
syndicate_elite_process()
|
||||
|
||||
|
||||
else if(href_list["mainmenu"])
|
||||
temp = null
|
||||
|
||||
add_fingerprint(usr)
|
||||
updateUsrDialog()
|
||||
return
|
||||
@@ -720,6 +720,10 @@
|
||||
// Won't announce when used for cryoing.
|
||||
silent = TRUE
|
||||
|
||||
/obj/machinery/cryopod/offstation/right
|
||||
orient_right = TRUE
|
||||
icon_state = "body_scanner_0-r"
|
||||
|
||||
/obj/machinery/computer/cryopod/robot
|
||||
name = "robotic storage console"
|
||||
desc = "An interface between crew and the robotic storage systems"
|
||||
|
||||
@@ -145,6 +145,8 @@
|
||||
else if(our_rpd.mode == RPD_FLIP_MODE)
|
||||
flip()
|
||||
else if(our_rpd.mode == RPD_DELETE_MODE)
|
||||
if(pipe_type == PIPE_CIRCULATOR) //Skip TEG heat circulators, they aren't really pipes
|
||||
return ..()
|
||||
our_rpd.delete_single_pipe(user, src)
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -657,6 +657,7 @@ GLOBAL_LIST_EMPTY(turret_icons)
|
||||
qdel(flick_holder)
|
||||
|
||||
set_raised_raising(FALSE, FALSE)
|
||||
set_angle(0)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/porta_turret/on_assess_perp(mob/living/carbon/human/perp)
|
||||
@@ -678,7 +679,8 @@ GLOBAL_LIST_EMPTY(turret_icons)
|
||||
last_target = target
|
||||
if(has_cover)
|
||||
popUp() //pop the turret up if it's not already up.
|
||||
setDir(get_dir(src, target)) //even if you can't shoot, follow the target
|
||||
// Set angle
|
||||
set_angle(get_angle(src, target))
|
||||
shootAt(target)
|
||||
return TRUE
|
||||
|
||||
@@ -842,6 +844,9 @@ GLOBAL_LIST_EMPTY(turret_icons)
|
||||
if(!user.unEquip(I))
|
||||
to_chat(user, "<span class='notice'>\the [I] is stuck to your hand, you cannot put it in \the [src]</span>")
|
||||
return
|
||||
if(!E.can_fit_in_turrets)
|
||||
to_chat(user, "<span class='notice'>[I] will not operate correctly in [src].</span>")
|
||||
return
|
||||
installation = I.type //installation becomes I.type
|
||||
gun_charge = E.cell.charge //the gun's charge is stored in gun_charge
|
||||
to_chat(user, "<span class='notice'>You add [I] to the turret.</span>")
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
name = "syndicate suit storage unit"
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/syndi
|
||||
mask_type = /obj/item/clothing/mask/gas/syndicate
|
||||
storage_type = /obj/item/tank/jetpack/oxygen/harness
|
||||
storage_type = /obj/item/tank/internals/oxygen/red
|
||||
req_access = list(ACCESS_SYNDICATE)
|
||||
safeties = FALSE //in a syndicate base, everything can be used as a murder weapon at a moment's notice.
|
||||
|
||||
|
||||
@@ -313,7 +313,7 @@
|
||||
name = "teleporter hub"
|
||||
desc = "It's the hub of a teleporting machine."
|
||||
icon_state = "tele0"
|
||||
var/accurate = FALSE
|
||||
var/accurate = 0
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 2000
|
||||
@@ -353,6 +353,8 @@
|
||||
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
|
||||
A += M.rating
|
||||
accurate = A
|
||||
if(accurate >= 3)
|
||||
calibrated = TRUE
|
||||
|
||||
/obj/machinery/teleport/hub/proc/link_power_station()
|
||||
if(power_station)
|
||||
@@ -401,12 +403,13 @@
|
||||
if(!calibrated && com.cc_beacon)
|
||||
visible_message("<span class='alert'>Cannot lock on target. Please calibrate the teleporter before attempting long range teleportation.</span>")
|
||||
else if(!calibrated && prob(25 - ((accurate) * 10)) && !com.cc_beacon) //oh dear a problem
|
||||
var/list/target_z = levels_by_trait(REACHABLE)
|
||||
var/list/target_z = levels_by_trait(SPAWN_RUINS)
|
||||
target_z -= M.z //Where to sir? Anywhere but here.
|
||||
. = do_teleport(M, locate(rand((2*TRANSITIONEDGE), world.maxx - (2*TRANSITIONEDGE)), rand((2*TRANSITIONEDGE), world.maxy - (2*TRANSITIONEDGE)), pick(target_z)), 2, bypass_area_flag = com.area_bypass)
|
||||
else
|
||||
. = do_teleport(M, com.target, bypass_area_flag = com.area_bypass)
|
||||
calibrated = FALSE
|
||||
if(accurate < 3)
|
||||
calibrated = FALSE
|
||||
|
||||
/obj/machinery/teleport/hub/update_icon()
|
||||
if(panel_open)
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
to_chat(user, "<span class='warning'>You feel a dark stirring inside of the Wish Granter, something you want nothing of. Your instincts are better than any man's.</warning>")
|
||||
return TRUE
|
||||
|
||||
if(is_special_character(user) || jobban_isbanned(user, ROLE_TRAITOR) || jobban_isbanned(user, "Syndicate"))
|
||||
if(is_special_character(user) || jobban_isbanned(user, ROLE_TRAITOR) || jobban_isbanned(user, ROLE_SYNDICATE))
|
||||
to_chat(user, "<span class='warning'>Something instinctual makes you pull away.</span>")
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -483,7 +483,7 @@
|
||||
if(R.can_synth && add_known_reagent(R.id, R.name))
|
||||
occupant_message("Reagent analyzed, identified as [R.name] and added to database.")
|
||||
send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form())
|
||||
occupant_message("Analyzis complete.")
|
||||
occupant_message("Analysis complete.")
|
||||
return 1
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/add_known_reagent(r_id,r_name)
|
||||
|
||||
@@ -30,28 +30,38 @@
|
||||
return
|
||||
if(!cargo_holder)
|
||||
return
|
||||
if(istype(target,/obj))
|
||||
if(isobj(target))
|
||||
var/obj/O = target
|
||||
if(!O.anchored)
|
||||
if(cargo_holder.cargo.len < cargo_holder.cargo_capacity)
|
||||
chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.")
|
||||
O.anchored = 1
|
||||
if(do_after_cooldown(target))
|
||||
cargo_holder.cargo += O
|
||||
O.loc = chassis
|
||||
O.anchored = 0
|
||||
occupant_message("<span class='notice'>[target] successfully loaded.</span>")
|
||||
log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]")
|
||||
else
|
||||
O.anchored = initial(O.anchored)
|
||||
else
|
||||
occupant_message("<span class='warning'>Not enough room in cargo compartment!</span>")
|
||||
else
|
||||
if(istype(target, /obj/machinery/power/supermatter_crystal)) //No, you can't pick up the SM with this you moron, did you think you were clever?
|
||||
var/obj/mecha/working/ripley/R = chassis
|
||||
QDEL_LIST(R.cargo) //We don't want to drop cargo that just spam hits the SM, let's delete it
|
||||
occupant_message("<span class='userdanger'>You realise in horror what you have done as [chassis] starts warping around you!</span>")
|
||||
chassis.occupant.dust()
|
||||
target.Bumped(chassis)
|
||||
return
|
||||
if(O.anchored)
|
||||
occupant_message("<span class='warning'>[target] is firmly secured!</span>")
|
||||
return
|
||||
if(length(cargo_holder.cargo) >= cargo_holder.cargo_capacity)
|
||||
occupant_message("<span class='warning'>Not enough room in cargo compartment!</span>")
|
||||
return
|
||||
chassis.visible_message("<span class='notice'>[chassis] lifts [target] and starts to load it into cargo compartment.</span>")
|
||||
var/anchor_state_before_load = O.anchored
|
||||
O.anchored = TRUE
|
||||
if(!do_after_cooldown(target))
|
||||
O.anchored = anchor_state_before_load
|
||||
return
|
||||
cargo_holder.cargo += O
|
||||
O.forceMove(chassis)
|
||||
O.anchored = FALSE
|
||||
occupant_message("<span class='notice'>[target] was successfully loaded.</span>")
|
||||
log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - length(cargo_holder.cargo)]")
|
||||
return
|
||||
|
||||
else if(istype(target,/mob/living))
|
||||
if(isliving(target))
|
||||
var/mob/living/M = target
|
||||
if(M.stat == DEAD) return
|
||||
if(M.stat == DEAD)
|
||||
return
|
||||
if(chassis.occupant.a_intent == INTENT_HARM)
|
||||
M.take_overall_damage(dam_force)
|
||||
if(!M)
|
||||
@@ -62,12 +72,10 @@
|
||||
"<span class='italics'>You hear something crack.</span>")
|
||||
add_attack_logs(chassis.occupant, M, "Squeezed with [src] ([uppertext(chassis.occupant.a_intent)]) ([uppertext(damtype)])")
|
||||
start_cooldown()
|
||||
else
|
||||
step_away(M,chassis)
|
||||
occupant_message("<span class='notice'>You push [target] out of the way.</span>")
|
||||
chassis.visible_message("<span class='notice'>[chassis] pushes [target] out of the way.</span>")
|
||||
return 1
|
||||
|
||||
return
|
||||
step_away(M, chassis)
|
||||
occupant_message("<span class='notice'>You push [target] out of the way.</span>")
|
||||
chassis.visible_message("<span class='notice'>[chassis] pushes [target] out of the way.</span>")
|
||||
|
||||
|
||||
//This is pretty much just for the death-ripley
|
||||
|
||||
@@ -1200,7 +1200,8 @@
|
||||
|
||||
/obj/mecha/Exited(atom/movable/M, atom/newloc)
|
||||
if(occupant && occupant == M) // The occupant exited the mech without calling go_out()
|
||||
go_out(1, newloc)
|
||||
if(!isAI(occupant)) //This causes carded AIS to gib, so we do not want this to be called during carding.
|
||||
go_out(1, newloc)
|
||||
|
||||
/obj/mecha/proc/go_out(forced, atom/newloc = loc)
|
||||
if(!occupant)
|
||||
@@ -1507,7 +1508,7 @@
|
||||
if(internal_tank)
|
||||
WR.crowbar_salvage += internal_tank
|
||||
internal_tank.forceMove(WR)
|
||||
cell = null
|
||||
internal_tank = null
|
||||
. = ..()
|
||||
|
||||
/obj/mecha/CtrlClick(mob/living/L)
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
user.visible_message("<span class='notice'>[user] pries [S] from [src].</span>", "<span class='notice'>You pry [S] from [src].</span>")
|
||||
crowbar_salvage -= S
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You don't see anything that can be cut with [I]!</span>")
|
||||
to_chat(user, "<span class='notice'>You don't see anything that can be pried with [I]!</span>")
|
||||
|
||||
/obj/structure/mecha_wreckage/welder_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
|
||||
@@ -122,6 +122,10 @@
|
||||
if(!in_range(user, src) || !isturf(user.loc) || user.incapacitated() || M.anchored)
|
||||
return FALSE
|
||||
|
||||
if (isguardian(user))
|
||||
if (M.loc == user.loc || user.alpha == 60) //Alpha is for detecting ranged guardians in scout mode
|
||||
return //unmanifested guardians shouldn't be able to buckle mobs
|
||||
|
||||
add_fingerprint(user)
|
||||
. = buckle_mob(M, check_loc = check_loc)
|
||||
if(.)
|
||||
|
||||
@@ -53,6 +53,9 @@
|
||||
/obj/effect/decal/cleanable/proc/can_bloodcrawl_in()
|
||||
return FALSE
|
||||
|
||||
/obj/effect/decal/cleanable/is_cleanable()
|
||||
return TRUE
|
||||
|
||||
/obj/effect/decal/cleanable/Initialize(mapload)
|
||||
. = ..()
|
||||
if(loc && isturf(loc))
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
/obj/effect/acid_act()
|
||||
return
|
||||
|
||||
/obj/effect/proc/is_cleanable() //Called when you want to clean something, and usualy delete it after
|
||||
return FALSE
|
||||
|
||||
/obj/effect/mech_melee_attack(obj/mecha/M)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
var/precision = TRUE // how close to the portal you will teleport. FALSE = on the portal, TRUE = adjacent
|
||||
var/can_multitool_to_remove = FALSE
|
||||
var/ignore_tele_proof_area_setting = FALSE
|
||||
var/one_use = FALSE // Does this portal go away after one teleport?
|
||||
|
||||
/obj/effect/portal/New(loc, turf/target, creator = null, lifespan = 300)
|
||||
..()
|
||||
@@ -101,14 +102,17 @@
|
||||
|
||||
if(prob(failchance))
|
||||
icon_state = fail_icon
|
||||
if(!do_teleport(M, locate(rand(5, world.maxx - 5), rand(5, world.maxy -5), 3), 0, bypass_area_flag = ignore_tele_proof_area_setting)) // Try to send them to deep space.
|
||||
var/list/target_z = levels_by_trait(SPAWN_RUINS)
|
||||
target_z -= M.z
|
||||
if(!do_teleport(M, locate(rand(5, world.maxx - 5), rand(5, world.maxy -5), pick(target_z)), 0, bypass_area_flag = ignore_tele_proof_area_setting)) // Try to send them to deep space.
|
||||
invalid_teleport()
|
||||
return FALSE
|
||||
else
|
||||
if(!do_teleport(M, target, precision, bypass_area_flag = ignore_tele_proof_area_setting)) // Try to send them to a turf adjacent to target.
|
||||
invalid_teleport()
|
||||
return FALSE
|
||||
|
||||
if(one_use)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/portal/proc/invalid_teleport()
|
||||
|
||||
@@ -354,3 +354,12 @@
|
||||
/obj/effect/temp_visual/impact_effect/ion
|
||||
icon_state = "shieldsparkles"
|
||||
duration = 6
|
||||
|
||||
/obj/effect/temp_visual/bsg_kaboom
|
||||
name = "bluespace explosion"
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "explosionfast"
|
||||
color = "blue"
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
duration = 42
|
||||
|
||||
@@ -424,6 +424,17 @@ GLOBAL_DATUM_INIT(fire_overlay, /image, image("icon" = 'icons/goonstation/effect
|
||||
/obj/item/proc/on_enter_storage(obj/item/storage/S as obj)
|
||||
return
|
||||
|
||||
/**
|
||||
* Called to check if this item can be put into a storage item.
|
||||
*
|
||||
* Return `FALSE` if `src` can't be inserted, and `TRUE` if it can.
|
||||
* Arguments:
|
||||
* * S - The [/obj/item/storage] that `src` is being inserted into.
|
||||
* * user - The mob trying to insert the item.
|
||||
*/
|
||||
/obj/item/proc/can_enter_storage(obj/item/storage/S, mob/user)
|
||||
return TRUE
|
||||
|
||||
// called when "found" in pockets and storage items. Returns 1 if the search should end.
|
||||
/obj/item/proc/on_found(mob/finder as mob)
|
||||
return
|
||||
|
||||
@@ -30,6 +30,12 @@
|
||||
else i = 3
|
||||
icon_state = "candle[i][lit ? "_lit" : ""]"
|
||||
|
||||
/obj/item/candle/can_enter_storage(obj/item/storage/S, mob/user)
|
||||
if(lit)
|
||||
to_chat(user, "<span class='warning'>[S] can't hold [src] while it's lit!</span>")
|
||||
return FALSE
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/obj/item/candle/attackby(obj/item/W, mob/user, params)
|
||||
if(is_hot(W))
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/obj/item/changestone
|
||||
name = "An uncut ruby"
|
||||
desc = "The ruby shines and catches the light, despite being uncut"
|
||||
icon = 'icons/obj/artifacts.dmi'
|
||||
icon_state = "changerock"
|
||||
|
||||
/obj/item/changestone/attack_hand(mob/user as mob)
|
||||
if(istype(user,/mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!H.gloves)
|
||||
if(H.gender == FEMALE)
|
||||
H.change_gender(MALE)
|
||||
else
|
||||
H.change_gender(FEMALE)
|
||||
H.dna.ready_dna(H)
|
||||
H.update_body()
|
||||
..()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -50,6 +50,10 @@
|
||||
/obj/item/radio/beacon/bacon/proc/digest_delay()
|
||||
QDEL_IN(src, 600)
|
||||
|
||||
/obj/item/radio/beacon/emagged
|
||||
syndicate = TRUE
|
||||
emagged = TRUE
|
||||
|
||||
// SINGULO BEACON SPAWNER
|
||||
/obj/item/radio/beacon/syndicate
|
||||
name = "suspicious beacon"
|
||||
@@ -71,6 +75,18 @@
|
||||
user.drop_item()
|
||||
qdel(src)
|
||||
|
||||
/obj/item/radio/beacon/syndicate/power_sink
|
||||
name = "suspicious beacon"
|
||||
desc = "A label on it reads: <i>Warning: Activating this device will send a power sink to your location</i>."
|
||||
|
||||
/obj/item/radio/beacon/syndicate/power_sink/attack_self(mob/user)
|
||||
if(user)
|
||||
to_chat(user, "<span class='notice'>Locked In</span>")
|
||||
new /obj/item/powersink(user.loc)
|
||||
playsound(src, 'sound/effects/pop.ogg', 100, TRUE, 1)
|
||||
user.drop_item()
|
||||
qdel(src)
|
||||
|
||||
/obj/item/radio/beacon/syndicate/bomb
|
||||
name = "suspicious beacon"
|
||||
desc = "A label on it reads: <i>Warning: Activating this device will send a high-ordinance explosive to your location</i>."
|
||||
|
||||
@@ -273,20 +273,20 @@ effective or pretty fucking useless.
|
||||
/obj/item/teleporter/proc/dir_correction(mob/user) //Direction movement, screws with teleport distance and saving throw, and thus must be removed first
|
||||
var/temp_direction = user.dir
|
||||
switch(temp_direction)
|
||||
if(NORTHEAST || SOUTHEAST)
|
||||
if(NORTHEAST, SOUTHEAST)
|
||||
user.dir = EAST
|
||||
if(NORTHWEST || SOUTHWEST)
|
||||
if(NORTHWEST, SOUTHWEST)
|
||||
user.dir = WEST
|
||||
|
||||
/obj/item/teleporter/proc/panic_teleport(mob/user, turf/destination, direction = NORTH)
|
||||
var/saving_throw
|
||||
switch(direction)
|
||||
if(NORTH || SOUTH)
|
||||
if(NORTH, SOUTH)
|
||||
if(prob(50))
|
||||
saving_throw = EAST
|
||||
else
|
||||
saving_throw = WEST
|
||||
if(EAST || WEST)
|
||||
if(EAST, WEST)
|
||||
if(prob(50))
|
||||
saving_throw = NORTH
|
||||
else
|
||||
|
||||
@@ -28,5 +28,5 @@
|
||||
return TRUE
|
||||
|
||||
/obj/item/mounted/frame/apc_frame/do_build(turf/on_wall, mob/user)
|
||||
new /obj/machinery/power/apc(get_turf(src), get_dir(user, on_wall), 1)
|
||||
new /obj/machinery/power/apc(get_turf(src), get_dir(user, on_wall), TRUE)
|
||||
qdel(src)
|
||||
|
||||
@@ -226,7 +226,7 @@
|
||||
to_chat(user, "<span class='warning'>Sticking an empty [M] into the frame would sort of defeat the purpose.</span>")
|
||||
return
|
||||
|
||||
if(jobban_isbanned(M.brainmob, "Cyborg") || jobban_isbanned(M.brainmob,"nonhumandept"))
|
||||
if(jobban_isbanned(M.brainmob, "Cyborg") || jobban_isbanned(M.brainmob, "nonhumandept"))
|
||||
to_chat(user, "<span class='warning'>This [W] is not fit to serve as a cyborg!</span>")
|
||||
return
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
if(replacement_type in special_rechargables)
|
||||
R.module.special_rechargables += replacement
|
||||
|
||||
R.module.rebuild_modules()
|
||||
R.module?.rebuild_modules()
|
||||
return TRUE
|
||||
|
||||
/obj/item/borg/upgrade/reset
|
||||
|
||||
@@ -19,7 +19,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \
|
||||
new/datum/stack_recipe/window("fulltile window", /obj/structure/window/full/basic, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe("fishbowl", /obj/machinery/fishtank/bowl, 1, time = 10), \
|
||||
new/datum/stack_recipe("fish tank", /obj/machinery/fishtank/tank, 3, time = 20, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("wall aquariam", /obj/machinery/fishtank/wall, 4, time = 40, on_floor = TRUE) \
|
||||
new/datum/stack_recipe("wall aquarium", /obj/machinery/fishtank/wall, 4, time = 40, on_floor = TRUE) \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/glass
|
||||
|
||||
@@ -83,7 +83,6 @@ GLOBAL_LIST_INIT(bananium_recipes, list ( \
|
||||
null, \
|
||||
new/datum/stack_recipe("Clown Statue", /obj/structure/statue/bananium/clown, 5, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("bananium computer frame", /obj/structure/computerframe/HONKputer, 50, time = 25, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("bananium grenade casing", /obj/item/grenade/bananade/casing, 4, on_floor = 1), \
|
||||
))
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
slot_flags = SLOT_BELT
|
||||
force = 5
|
||||
throwforce = 7
|
||||
item_state = "crowbar"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
materials = list(MAT_METAL=50)
|
||||
drop_sound = 'sound/items/handling/crowbar_drop.ogg'
|
||||
|
||||
@@ -83,6 +83,9 @@
|
||||
if(chunk)
|
||||
if(chunk.seenby.len)
|
||||
for(var/mob/camera/aiEye/A in chunk.seenby)
|
||||
//Checks if the A is to be detected or not
|
||||
if(!A.ai_detector_visible)
|
||||
continue
|
||||
var/turf/detect_turf = get_turf(A)
|
||||
if(get_dist(our_turf, detect_turf) < rangealert)
|
||||
detect_state = PROXIMITY_ON_SCREEN
|
||||
|
||||
@@ -57,4 +57,8 @@
|
||||
|
||||
// Used in a callback that is passed by use_tool into do_after call. Do not override, do not call manually.
|
||||
/obj/item/proc/tool_check_callback(mob/living/user, atom/target, amount, datum/callback/extra_checks)
|
||||
return tool_use_check(user, amount) && (extra_checks && !extra_checks.Invoke())
|
||||
if(!tool_use_check(user, amount))
|
||||
return TRUE
|
||||
if(extra_checks && !extra_checks.Invoke())
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30)
|
||||
resistance_flags = FIRE_PROOF
|
||||
materials = list(MAT_METAL=70, MAT_GLASS=30)
|
||||
materials = list(MAT_METAL = 70, MAT_GLASS = 20)
|
||||
origin_tech = "engineering=1;plasmatech=1"
|
||||
tool_behaviour = TOOL_WELDER
|
||||
toolspeed = 1
|
||||
@@ -52,6 +52,13 @@
|
||||
user.visible_message("<span class='suicide'>[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!</span>")
|
||||
return FIRELOSS
|
||||
|
||||
/obj/item/weldingtool/can_enter_storage(obj/item/storage/S, mob/user)
|
||||
if(tool_enabled)
|
||||
to_chat(user, "<span class='warning'>[S] can't hold [src] while it's lit!</span>")
|
||||
return FALSE
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/obj/item/weldingtool/process()
|
||||
if(tool_enabled)
|
||||
var/turf/T = get_turf(src)
|
||||
@@ -131,7 +138,7 @@
|
||||
|
||||
/obj/item/weldingtool/tool_check_callback(mob/living/user, amount, datum/callback/extra_checks)
|
||||
. = ..()
|
||||
if(. && user)
|
||||
if(!. && user)
|
||||
if(progress_flash_divisor == 0)
|
||||
user.flash_eyes(min(light_intensity, 1))
|
||||
progress_flash_divisor = initial(progress_flash_divisor)
|
||||
|
||||
@@ -61,6 +61,12 @@ LIGHTERS ARE IN LIGHTERS.DM
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/mask/cigarette/can_enter_storage(obj/item/storage/S, mob/user)
|
||||
if(lit)
|
||||
to_chat(user, "<span class='warning'>[S] can't hold [initial(name)] while it's lit!</span>") // initial(name) so it doesn't say "lit" twice in a row
|
||||
return FALSE
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/mask/cigarette/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE)
|
||||
..()
|
||||
|
||||
@@ -64,11 +64,26 @@
|
||||
M.update_inv_l_hand()
|
||||
M.update_inv_r_hand()
|
||||
|
||||
/obj/item/flamethrower/can_enter_storage(obj/item/storage/S, mob/user)
|
||||
if(lit)
|
||||
to_chat(user, "<span class='warning'>[S] can't hold [src] while it's lit!</span>")
|
||||
return FALSE
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/obj/item/flamethrower/afterattack(atom/target, mob/user, flag)
|
||||
. = ..()
|
||||
if(flag)
|
||||
return // too close
|
||||
if(user && user.get_active_hand() == src) // Make sure our user is still holding us
|
||||
if(!user)
|
||||
return
|
||||
if(user.mind?.martial_art?.no_guns)
|
||||
to_chat(user, "<span class='warning'>[user.mind.martial_art.no_guns_message]</span>")
|
||||
return
|
||||
if(HAS_TRAIT(user, TRAIT_CHUNKYFINGERS))
|
||||
to_chat(user, "<span class='warning'>Your meaty finger is far too large for the trigger guard!</span>")
|
||||
return
|
||||
if(user.get_active_hand() == src) // Make sure our user is still holding us
|
||||
var/turf/target_turf = get_turf(target)
|
||||
if(target_turf)
|
||||
var/turflist = getline(user, target_turf)
|
||||
|
||||
@@ -44,11 +44,9 @@
|
||||
update_mob()
|
||||
playsound(loc, 'sound/effects/empulse.ogg', 50, 1)
|
||||
radiation_pulse(src, rad_damage)
|
||||
for(var/turf/T in view(freeze_range, loc))
|
||||
if(isfloorturf(T))
|
||||
var/turf/simulated/F = T
|
||||
F.MakeSlippery(TURF_WET_PERMAFROST)
|
||||
for(var/mob/living/carbon/L in T)
|
||||
L.adjustStaminaLoss(stamina_damage)
|
||||
L.adjust_bodytemperature(-230)
|
||||
for(var/turf/simulated/floor/T in view(freeze_range, loc))
|
||||
T.MakeSlippery(TURF_WET_ICE)
|
||||
for(var/mob/living/carbon/L in T)
|
||||
L.adjustStaminaLoss(stamina_damage)
|
||||
L.adjust_bodytemperature(-230)
|
||||
qdel(src)
|
||||
|
||||
@@ -29,6 +29,13 @@
|
||||
else
|
||||
turn_off_lighter(user)
|
||||
|
||||
/obj/item/lighter/can_enter_storage(obj/item/storage/S, mob/user)
|
||||
if(lit)
|
||||
to_chat(user, "<span class='warning'>[S] can't hold [src] while it's lit!</span>")
|
||||
return FALSE
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/obj/item/lighter/proc/turn_on_lighter(mob/living/user)
|
||||
lit = TRUE
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
@@ -227,6 +234,13 @@
|
||||
matchburnout()
|
||||
. = ..()
|
||||
|
||||
/obj/item/match/can_enter_storage(obj/item/storage/S, mob/user)
|
||||
if(lit)
|
||||
to_chat(user, "<span class='warning'>[S] can't hold [initial(name)] while it's lit!</span>") // initial(name) so it doesn't say "lit" twice in a row
|
||||
return FALSE
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/obj/item/match/attack(mob/living/carbon/M, mob/living/carbon/user)
|
||||
if(!isliving(M))
|
||||
return ..()
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
if(reagents.has_reagent("water", 1) || reagents.has_reagent("cleaner", 1) || reagents.has_reagent("holywater", 1))
|
||||
A.clean_blood()
|
||||
for(var/obj/effect/O in A)
|
||||
if(is_cleanable(O))
|
||||
if(O.is_cleanable())
|
||||
qdel(O)
|
||||
reagents.reaction(A, REAGENT_TOUCH, 10) //10 is the multiplier for the reaction effect. probably needed to wet the floor properly.
|
||||
reagents.remove_any(1) //reaction() doesn't use up the reagents
|
||||
|
||||
@@ -142,6 +142,8 @@
|
||||
/obj/item/rpd/proc/delete_all_pipes(mob/user, turf/T) //Delete all pipes on a turf
|
||||
var/eaten
|
||||
for(var/obj/item/pipe/P in T)
|
||||
if(P.pipe_type == PIPE_CIRCULATOR) //Skip TEG heat circulators, they aren't really pipes
|
||||
continue
|
||||
QDEL_NULL(P)
|
||||
eaten = TRUE
|
||||
for(var/obj/item/pipe_gsensor/G in T)
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
/obj/item/soap/proc/clean_turf(turf/simulated/T)
|
||||
T.clean_blood()
|
||||
for(var/obj/effect/O in T)
|
||||
if(is_cleanable(O))
|
||||
if(O.is_cleanable())
|
||||
qdel(O)
|
||||
|
||||
/obj/item/soap/attack(mob/target as mob, mob/user as mob)
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
|
||||
/obj/item/stock_parts/matter_bin
|
||||
name = "matter bin"
|
||||
desc = "A container for hold compressed matter awaiting re-construction."
|
||||
desc = "A container used to hold compressed matter awaiting re-construction."
|
||||
icon_state = "matter_bin"
|
||||
origin_tech = "materials=1"
|
||||
materials = list(MAT_METAL=80)
|
||||
@@ -145,7 +145,7 @@
|
||||
|
||||
/obj/item/stock_parts/matter_bin/adv
|
||||
name = "advanced matter bin"
|
||||
desc = "A container for hold compressed matter awaiting re-construction."
|
||||
desc = "A container used to hold compressed matter awaiting re-construction."
|
||||
icon_state = "advanced_matter_bin"
|
||||
origin_tech = "materials=3"
|
||||
rating = 2
|
||||
@@ -187,7 +187,7 @@
|
||||
|
||||
/obj/item/stock_parts/matter_bin/super
|
||||
name = "super matter bin"
|
||||
desc = "A container for hold compressed matter awaiting re-construction."
|
||||
desc = "A container used to hold compressed matter awaiting re-construction."
|
||||
icon_state = "super_matter_bin"
|
||||
origin_tech = "materials=4;engineering=4"
|
||||
rating = 3
|
||||
@@ -229,7 +229,7 @@
|
||||
|
||||
/obj/item/stock_parts/matter_bin/bluespace
|
||||
name = "bluespace matter bin"
|
||||
desc = "A container for hold compressed matter awaiting re-construction."
|
||||
desc = "A container used to hold compressed matter awaiting re-construction."
|
||||
icon_state = "bluespace_matter_bin"
|
||||
origin_tech = "materials=6;programming=4;engineering=4"
|
||||
rating = 4
|
||||
|
||||
@@ -230,7 +230,9 @@
|
||||
/obj/item/flashlight/seclite,
|
||||
/obj/item/holosign_creator/security,
|
||||
/obj/item/melee/classic_baton/telescopic,
|
||||
/obj/item/restraints/legcuffs/bola)
|
||||
/obj/item/restraints/legcuffs/bola,
|
||||
/obj/item/clothing/mask/gas/sechailer,
|
||||
/obj/item/spacepod_key)
|
||||
|
||||
/obj/item/storage/belt/security/sec/populate_contents()
|
||||
new /obj/item/flashlight/seclite(src)
|
||||
@@ -447,6 +449,7 @@
|
||||
item_state = "bandolier"
|
||||
storage_slots = 8
|
||||
can_hold = list(/obj/item/ammo_casing/shotgun)
|
||||
display_contents_with_number = TRUE
|
||||
|
||||
/obj/item/storage/belt/bandolier/Initialize(mapload)
|
||||
. = ..()
|
||||
|
||||
@@ -163,7 +163,7 @@
|
||||
/obj/item/storage/proc/show_to(mob/user)
|
||||
if(!user.client)
|
||||
return
|
||||
if(user.s_active != src) // Switching from another container
|
||||
if(user.s_active != src && !isobserver(user))
|
||||
for(var/obj/item/I in src)
|
||||
if(I.on_found(user)) // For mouse traps and such
|
||||
return // If something triggered, don't open the UI
|
||||
@@ -310,6 +310,9 @@
|
||||
if(loc == I)
|
||||
return FALSE //Means the item is already in the storage item
|
||||
|
||||
if(!I.can_enter_storage(src, usr))
|
||||
return FALSE
|
||||
|
||||
if(length(contents) >= storage_slots)
|
||||
if(!stop_messages)
|
||||
to_chat(usr, "<span class='warning'>[I] won't fit in [src], make some space!</span>")
|
||||
|
||||
@@ -670,6 +670,8 @@
|
||||
|
||||
/obj/item/twohanded/singularityhammer/proc/vortex(turf/pull, mob/wielder)
|
||||
for(var/atom/movable/X in orange(5, pull))
|
||||
if(X.move_resist == INFINITY)
|
||||
continue
|
||||
if(X == wielder)
|
||||
continue
|
||||
if((X) && (!X.anchored) && (!ishuman(X)))
|
||||
|
||||
@@ -363,6 +363,7 @@ a {
|
||||
/obj/proc/cult_reveal() //Called by cult reveal spell and chaplain's bible
|
||||
return
|
||||
|
||||
|
||||
/obj/proc/force_eject_occupant(mob/target)
|
||||
// This proc handles safely removing occupant mobs from the object if they must be teleported out (due to being SSD/AFK, by admin teleport, etc) or transformed.
|
||||
// In the event that the object doesn't have an overriden version of this proc to do it, log a runtime so one can be added.
|
||||
|
||||
@@ -69,6 +69,8 @@
|
||||
togglelock(user)
|
||||
|
||||
/obj/structure/closet/secure_closet/AltClick(mob/user)
|
||||
if(opened)
|
||||
return ..()
|
||||
if(Adjacent(user))
|
||||
togglelock(user)
|
||||
|
||||
@@ -78,7 +80,7 @@
|
||||
locked = FALSE
|
||||
icon_state = icon_off
|
||||
flick(icon_broken, src)
|
||||
to_chat(user, "<span class='notice'>You break the lock on \the [src].</span>")
|
||||
to_chat(user, "<span class='notice'>You break the lock on [src].</span>")
|
||||
|
||||
/obj/structure/closet/secure_closet/attack_hand(mob/user)
|
||||
add_fingerprint(user)
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
/obj/structure/closet/syndicate/suits/populate_contents()
|
||||
new /obj/item/clothing/mask/gas/syndicate(src)
|
||||
new /obj/item/clothing/suit/space/hardsuit/syndi(src)
|
||||
new /obj/item/tank/jetpack/oxygen/harness(src)
|
||||
new /obj/item/tank/internals/oxygen/red(src)
|
||||
|
||||
/obj/structure/closet/syndicate/nuclear
|
||||
desc = "It's a storage unit for a Syndicate boarding party."
|
||||
@@ -37,6 +37,7 @@
|
||||
new /obj/item/storage/box/teargas(src)
|
||||
new /obj/item/storage/box/flashbangs(src)
|
||||
new /obj/item/storage/backpack/duffel/syndie/med(src)
|
||||
new /obj/item/tank/jetpack/oxygen/harness(src)
|
||||
new /obj/item/gun/projectile/automatic/shotgun/bulldog(src)
|
||||
new /obj/item/gun/projectile/automatic/shotgun/bulldog(src)
|
||||
new /obj/item/gun/projectile/automatic/shotgun/bulldog(src)
|
||||
@@ -50,7 +51,7 @@
|
||||
/obj/structure/closet/syndicate/sst/populate_contents()
|
||||
new /obj/item/ammo_box/magazine/mm556x45(src)
|
||||
new /obj/item/gun/projectile/automatic/l6_saw(src)
|
||||
new /obj/item/tank/jetpack/oxygen/harness(src)
|
||||
new /obj/item/tank/internals/oxygen/red(src)
|
||||
new /obj/item/storage/belt/military/sst(src)
|
||||
new /obj/item/clothing/glasses/thermal(src)
|
||||
new /obj/item/clothing/shoes/magboots/syndie/advance(src)
|
||||
|
||||
@@ -404,7 +404,7 @@
|
||||
tile.water_act(100, convertHeat(), src)
|
||||
tile.clean_blood(radiation_clean = TRUE)
|
||||
for(var/obj/effect/E in tile)
|
||||
if(is_cleanable(E))
|
||||
if(E.is_cleanable())
|
||||
qdel(E)
|
||||
for(var/A in loc)
|
||||
wash(A)
|
||||
|
||||
@@ -247,6 +247,70 @@ GLOBAL_VAR_INIT(admin_ooc_colour, "#b82e00")
|
||||
if(send)
|
||||
to_chat(target, "<span class='ooc'><span class='looc'>LOOC<span class='prefix'>[prefix]: </span><EM>[display_name][admin_stuff]:</EM> <span class='message'>[msg]</span></span></span>")
|
||||
|
||||
|
||||
// Ported from /tg/, full credit to SpaceManiac and Timberpoes.
|
||||
/client/verb/fit_viewport()
|
||||
set name = "Fit Viewport"
|
||||
set desc = "Fit the size of the map window to match the viewport."
|
||||
set category = "OOC"
|
||||
|
||||
// Fetch aspect ratio
|
||||
var/list/view_size = getviewsize(view)
|
||||
var/aspect_ratio = view_size[1] / view_size[2]
|
||||
|
||||
// Calculate desired pixel width using window size and aspect ratio
|
||||
var/list/sizes = params2list(winget(src, "mainwindow.mainvsplit;mapwindow", "size"))
|
||||
|
||||
// Client closed the window? Some other error? This is unexpected behaviour, let's CRASH with some info.
|
||||
if(!sizes["mapwindow.size"])
|
||||
CRASH("sizes does not contain mapwindow.size key. This means a winget() failed to return what we wanted. --- sizes var: [sizes] --- sizes length: [length(sizes)]")
|
||||
|
||||
var/list/map_size = splittext(sizes["mapwindow.size"], "x")
|
||||
|
||||
// Looks like we didn't expect mapwindow.size to be "ixj" where i and j are numbers.
|
||||
// If we don't get our expected 2 outputs, let's give some useful error info.
|
||||
if(length(map_size) != 2)
|
||||
CRASH("map_size of incorrect length --- map_size var: [map_size] --- map_size length: [length(map_size)]")
|
||||
|
||||
|
||||
var/height = text2num(map_size[2])
|
||||
var/desired_width = round(height * aspect_ratio)
|
||||
if(text2num(map_size[1]) == desired_width)
|
||||
// Nothing to do.
|
||||
return
|
||||
|
||||
var/list/split_size = splittext(sizes["mainwindow.mainvsplit.size"], "x")
|
||||
var/split_width = text2num(split_size[1])
|
||||
|
||||
// Avoid auto-resizing the statpanel and chat into nothing.
|
||||
desired_width = min(desired_width, split_width - 300)
|
||||
|
||||
// Calculate and apply a best estimate
|
||||
// +4 pixels are for the width of the splitter's handle
|
||||
var/pct = 100 * (desired_width + 4) / split_width
|
||||
winset(src, "mainwindow.mainvsplit", "splitter=[pct]")
|
||||
|
||||
// Apply an ever-lowering offset until we finish or fail
|
||||
var/delta
|
||||
for(var/safety in 1 to 10)
|
||||
var/after_size = winget(src, "mapwindow", "size")
|
||||
map_size = splittext(after_size, "x")
|
||||
var/produced_width = text2num(map_size[1])
|
||||
|
||||
if(produced_width == desired_width)
|
||||
// Success!
|
||||
return
|
||||
else if(isnull(delta))
|
||||
// Calculate a probably delta based on the difference
|
||||
delta = 100 * (desired_width - produced_width) / split_width
|
||||
else if((delta > 0 && produced_width > desired_width) || (delta < 0 && produced_width < desired_width))
|
||||
// If we overshot, halve the delta and reverse direction
|
||||
delta = -delta / 2
|
||||
|
||||
pct += delta
|
||||
winset(src, "mainwindow.mainvsplit", "splitter=[pct]")
|
||||
|
||||
|
||||
/mob/proc/get_looc_source()
|
||||
return src
|
||||
|
||||
|
||||
@@ -250,6 +250,11 @@ GLOBAL_LIST_EMPTY(world_topic_handlers)
|
||||
start_log(GLOB.sql_log)
|
||||
start_log(GLOB.chat_debug_log)
|
||||
|
||||
#ifdef REFERENCE_TRACKING
|
||||
GLOB.gc_log = "[GLOB.log_directory]/gc_debug.log"
|
||||
start_log(GLOB.gc_log)
|
||||
#endif
|
||||
|
||||
// This log follows a special format and this path should NOT be used for anything else
|
||||
GLOB.runtime_summary_log = "data/logs/runtime_summary.log"
|
||||
if(fexists(GLOB.runtime_summary_log))
|
||||
|
||||
Reference in New Issue
Block a user