Merge pull request #31947 from AnturK/yarr

How does this work:
Station receives a communication extorting current cargo point, if they answer yes the points are just gone and nothing of interest happens.

If station refuses to pay or is silent for 3 minutes, pirate shuttle spawns somewhere in space.

    There's an internal GPS onboard so crew will always be able to follow the shuttle.
    Crew of 3, moderately armed. (Balance pending)
    Shuttle engines have 3 minute cooldown between jumps.
    Special shuttle equipment will block cargo and emergency shuttles from leaving and slowly steal the points.
This commit is contained in:
oranges
2017-11-13 22:18:37 +13:00
committed by CitadelStationBot
parent 3ea8808201
commit 43113cd9b5
24 changed files with 3029 additions and 37 deletions
File diff suppressed because it is too large Load Diff
+3
View File
@@ -84,3 +84,6 @@
#define SUPERMATTER_DANGER 4 // Integrity < 50%
#define SUPERMATTER_EMERGENCY 5 // Integrity < 25%
#define SUPERMATTER_DELAMINATING 6 // Pretty obvious.
//R&D Snowflakes
#define RD_CONSOLE_LOCKED_SCREEN 0.2
+16 -16
View File
@@ -1,4 +1,4 @@
/proc/priority_announce(text, title = "", sound = 'sound/ai/attention.ogg', type)
/proc/priority_announce(text, title = "", sound = 'sound/ai/attention.ogg', type , sender_override)
if(!text)
return
@@ -13,13 +13,18 @@
GLOB.news_network.SubmitArticle(text, "Captain's Announcement", "Station Announcements", null)
else
announcement += "<h1 class='alert'>[command_name()] Update</h1>"
if(!sender_override)
announcement += "<h1 class='alert'>[command_name()] Update</h1>"
else
announcement += "<h1 class='alert'>[sender_override]</h1>"
if (title && length(title) > 0)
announcement += "<br><h2 class='alert'>[html_encode(title)]</h2>"
if(title == "")
GLOB.news_network.SubmitArticle(text, "Central Command Update", "Station Announcements", null)
else
GLOB.news_network.SubmitArticle(title + "<br><br>" + text, "Central Command", "Station Announcements", null)
if(!sender_override)
if(title == "")
GLOB.news_network.SubmitArticle(text, "Central Command Update", "Station Announcements", null)
else
GLOB.news_network.SubmitArticle(title + "<br><br>" + text, "Central Command", "Station Announcements", null)
announcement += "<br><span class='alert'>[html_encode(text)]</span><br>"
announcement += "<br>"
@@ -38,16 +43,11 @@
if(announce)
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg')
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && (C.z in GLOB.station_z_levels))
var/obj/item/paper/P = new /obj/item/paper(C.loc)
P.name = "paper - '[title]'"
P.info = text
var/datum/comm_message/message = new
message.title = title
message.content = text
C.add_message(message)
P.update_icon()
var/datum/comm_message/M = new
M.title = title
M.content = text
SScommunications.send_message(M)
/proc/minor_announce(message, title = "Attention:", alert)
if(!message)
-1
View File
@@ -19,7 +19,6 @@ GLOBAL_LIST_INIT(nightmare_names, world.file2list("strings/names/nightmare.txt")
GLOBAL_LIST_INIT(megacarp_first_names, world.file2list("strings/names/megacarp1.txt"))
GLOBAL_LIST_INIT(megacarp_last_names, world.file2list("strings/names/megacarp2.txt"))
GLOBAL_LIST_INIT(verbs, world.file2list("strings/names/verbs.txt"))
GLOBAL_LIST_INIT(adjectives, world.file2list("strings/names/adjectives.txt"))
GLOBAL_LIST_INIT(dream_strings, world.file2list("strings/dreamstrings.txt"))
@@ -28,5 +28,19 @@ SUBSYSTEM_DEF(communications)
log_talk(user,"[key_name(user)] has made a priority announcement: [input]",LOGSAY)
message_admins("[key_name_admin(user)] has made a priority announcement.")
/datum/controller/subsystem/communications/proc/send_message(datum/comm_message/sending,print = TRUE,unique = FALSE)
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && (C.z in GLOB.station_z_levels))
if(unique)
C.add_message(sending)
else //We copy the message for each console, answers and deletions won't be shared
var/datum/comm_message/M = new(sending.title,sending.content,sending.possible_answers.Copy())
C.add_message(M)
if(print)
var/obj/item/paper/P = new /obj/item/paper(C.loc)
P.name = "paper - '[sending.title]'"
P.info = sending.content
P.update_icon()
#undef COMMUNICATION_COOLDOWN
#undef COMMUNICATION_COOLDOWN_AI
+27 -1
View File
@@ -28,7 +28,9 @@ SUBSYSTEM_DEF(shuttle)
var/emergencyCallAmount = 0 //how many times the escape shuttle was called
var/emergencyNoEscape
var/emergencyNoRecall = FALSE
var/list/hostileEnvironments = list()
var/list/hostileEnvironments = list() //Things blocking escape shuttle from leaving
var/list/tradeBlockade = list() //Things blocking cargo from leaving.
var/supplyBlocked = FALSE
//supply shuttle stuff
var/obj/docking_port/mobile/supply/supply
@@ -335,6 +337,30 @@ SUBSYSTEM_DEF(shuttle)
hostileEnvironments -= bad
checkHostileEnvironment()
/datum/controller/subsystem/shuttle/proc/registerTradeBlockade(datum/bad)
tradeBlockade[bad] = TRUE
checkTradeBlockade()
/datum/controller/subsystem/shuttle/proc/clearTradeBlockade(datum/bad)
tradeBlockade -= bad
checkTradeBlockade()
/datum/controller/subsystem/shuttle/proc/checkTradeBlockade()
for(var/datum/d in tradeBlockade)
if(!istype(d) || QDELETED(d))
tradeBlockade -= d
supplyBlocked = tradeBlockade.len
if(supplyBlocked && (supply.mode == SHUTTLE_IGNITING))
supply.mode = SHUTTLE_STRANDED
supply.timer = null
//Make all cargo consoles speak up
if(!supplyBlocked && (supply.mode == SHUTTLE_STRANDED))
supply.mode = SHUTTLE_DOCKED
//Make all cargo consoles speak up
/datum/controller/subsystem/shuttle/proc/checkHostileEnvironment()
for(var/datum/d in hostileEnvironments)
if(!istype(d) || QDELETED(d))
+135
View File
@@ -0,0 +1,135 @@
/datum/antagonist/pirate
name = "Space Pirate"
job_rank = ROLE_TRAITOR
var/datum/objective_team/pirate/crew
/datum/antagonist/pirate/greet()
to_chat(owner, "<span class='boldannounce'>You are a Space Pirate!</span>")
to_chat(owner, "<B>The station refused to pay for your protection, protect the ship, siphon the credits from the station and raid it for even more loot.</B>")
owner.announce_objectives()
/datum/antagonist/pirate/get_team()
return crew
/datum/antagonist/pirate/create_team(datum/objective_team/pirate/new_team)
if(!new_team)
for(var/datum/antagonist/pirate/P in GLOB.antagonists)
if(P.crew)
new_team = P.crew
if(!new_team)
crew = new /datum/objective_team/pirate
crew.forge_objectives()
return
if(!istype(new_team))
stack_trace("Wrong team type passed to [type] initialization.")
crew = new_team
/datum/antagonist/pirate/on_gain()
if(crew)
owner.objectives |= crew.objectives
. = ..()
/datum/antagonist/pirate/on_removal()
if(crew)
owner.objectives -= crew.objectives
. = ..()
/datum/objective_team/pirate
name = "Pirate crew"
var/list/objectives = list()
/datum/objective_team/pirate/proc/forge_objectives()
var/datum/objective/loot/getbooty = new()
getbooty.team = src
getbooty.storage_area = locate(/area/shuttle/pirate/vault) in GLOB.sortedAreas
getbooty.update_initial_value()
getbooty.update_explanation_text()
objectives += getbooty
for(var/datum/mind/M in members)
M.objectives |= objectives
GLOBAL_LIST_INIT(pirate_loot_cache, typecacheof(list(
/obj/structure/reagent_dispensers/beerkeg,
/mob/living/simple_animal/parrot,
/obj/item/stack/sheet/mineral/gold,
/obj/item/stack/sheet/mineral/diamond,
/obj/item/stack/spacecash,
/obj/item/melee/sabre,)))
/datum/objective/loot
var/area/storage_area //Place where we we will look for the loot.
explanation_text = "Acquire valuable loot and store it in designated area."
var/target_value = 50000
var/initial_value = 0 //Things in the vault at spawn time do not count
/datum/objective/loot/update_explanation_text()
if(storage_area)
explanation_text = "Acquire loot and store [target_value] of credits worth in [storage_area.name]."
/datum/objective/loot/proc/loot_listing()
//Lists notable loot.
if(!storage_area)
return "Nothing"
var/list/loot_table = list()
for(var/atom/movable/AM in storage_area.GetAllContents())
if(is_type_in_typecache(AM,GLOB.pirate_loot_cache))
var/lootname = AM.name
var/count = 1
if(istype(AM,/obj/item/stack)) //Ugh.
var/obj/item/stack/S = AM
lootname = S.singular_name
count = S.amount
if(!loot_table[lootname])
loot_table[lootname] = count
else
loot_table[lootname] += count
var/text = ""
for(var/key in loot_table)
var/amount = loot_table[key]
text += "[amount] [key][amount > 1 ? "s":""], "
return text
/datum/objective/loot/proc/get_loot_value()
if(!storage_area)
return 0
var/value = 0
for(var/turf/T in storage_area.contents)
value += export_item_and_contents(T,TRUE, TRUE, dry_run = TRUE)
return value - initial_value
/datum/objective/loot/proc/update_initial_value()
initial_value = get_loot_value()
/datum/objective/loot/check_completion()
return ..() || get_loot_value() >= target_value
//These need removal ASAP as everything is converted to datum antags.
/datum/game_mode/proc/auto_declare_completion_pirates()
var/list/datum/mind/pirates = get_antagonists(/datum/antagonist/pirate)
var/datum/objective_team/pirate/crew
var/text = ""
if(pirates.len)
text += "<br><b>Space Pirates were:</b>"
for(var/datum/mind/M in pirates)
text += printplayer(M)
if(!crew)
var/datum/antagonist/pirate/P = M.has_antag_datum(/datum/antagonist/pirate)
crew = P.crew
if(crew)
text += "<br>Loot stolen: "
var/datum/objective/loot/L = locate() in crew.objectives
text += L.loot_listing()
text += "<br>Total loot value : [L.get_loot_value()]/[L.target_value] credits"
var/all_dead = TRUE
for(var/datum/mind/M in crew.members)
if(considered_alive(M))
all_dead = FALSE
break
if(L.check_completion() && !all_dead)
text += "<br><font color='green'><b>The pirate crew was successful!</b></font>"
else
text += "<br><span class='boldannounce'>The pirate crew has failed.</span>"
to_chat(world, text)
+9
View File
@@ -108,3 +108,12 @@
/area/shuttle/syndicate_scout
name = "Syndicate Scout"
blob_allowed = FALSE
/area/shuttle/pirate
name = "Pirate Shuttle"
blob_allowed = FALSE
requires_power = TRUE
/area/shuttle/pirate/vault
name = "Pirate Shuttle Vault"
requires_power = FALSE
@@ -230,6 +230,10 @@
if(!currmsg || !answer || currmsg.possible_answers.len < answer)
state = STATE_MESSAGELIST
currmsg.answered = answer
log_game("[key_name(usr)] answered [currmsg.title] comm message. Answer : [currmsg.answered]")
if(currmsg)
currmsg.answer_callback.Invoke()
state = STATE_VIEWMESSAGE
if("status")
state = STATE_STATUSDISPLAY
@@ -359,6 +363,9 @@
if(!aicurrmsg || !answer || aicurrmsg.possible_answers.len < answer)
aistate = STATE_MESSAGELIST
aicurrmsg.answered = answer
log_game("[key_name(usr)] answered [currmsg.title] comm message. Answer : [currmsg.answered]")
if(aicurrmsg.answer_callback)
aicurrmsg.answer_callback.Invoke()
aistate = STATE_VIEWMESSAGE
if("ai-status")
aistate = STATE_STATUSDISPLAY
@@ -733,3 +740,13 @@
var/content
var/list/possible_answers = list()
var/answered
var/datum/callback/answer_callback
/datum/comm_message/New(new_title,new_content,new_possible_answers)
..()
if(title)
title = new_title
if(content)
content = new_content
if(new_possible_answers)
possible_answers = new_possible_answers
@@ -168,7 +168,8 @@
return
log_game("[user.ckey] golem-swapped into [src]")
user.visible_message("<span class='notice'>A faint light leaves [user], moving to [src] and animating it!</span>","<span class='notice'>You leave your old body behind, and transfer into [src]!</span>")
create(ckey = user.ckey, flavour = FALSE, name = user.real_name)
show_flavour = FALSE
create(ckey = user.ckey,name = user.real_name)
user.death()
return
..()
@@ -526,3 +527,44 @@
/obj/effect/mob_spawn/human/oldsci/Destroy()
new/obj/structure/showcase/machinery/oldpod/used(drop_location())
return ..()
#define PIRATE_NAMES_FILE "pirates.json"
/obj/effect/mob_spawn/human/pirate
name = "space pirate sleeper"
desc = "A cryo sleeper smelling faintly of rum."
random = TRUE
icon = 'icons/obj/cryogenic2.dmi'
icon_state = "sleeper"
mob_name = "a space pirate"
mob_species = /datum/species/human
outfit = /datum/outfit/pirate/space
roundstart = FALSE
death = FALSE
anchored = TRUE
density = FALSE
show_flavour = FALSE //Flavour only exists for spawners menu
flavour_text = "<font size=3><b>Y</b></font><b>ou are a space pirate. The station refused to pay for your protection, protect the ship, siphon the credits from the station and raid it for even more loot.</b>"
assignedrole = "Space Pirate"
var/rank = "Mate"
/obj/effect/mob_spawn/human/pirate/special(mob/living/new_spawn)
new_spawn.fully_replace_character_name(new_spawn.real_name,generate_pirate_name())
new_spawn.mind.add_antag_datum(/datum/antagonist/pirate)
/obj/effect/mob_spawn/human/pirate/proc/generate_pirate_name()
var/beggings = strings(PIRATE_NAMES_FILE, "beginnings")
var/endings = strings(PIRATE_NAMES_FILE, "endings")
return "[rank] [pick(beggings)][pick(endings)]"
/obj/effect/mob_spawn/human/pirate/Destroy()
new/obj/structure/showcase/machinery/oldpod/used(drop_location())
return ..()
/obj/effect/mob_spawn/human/pirate/captain
rank = "Captain"
outfit = /datum/outfit/pirate/space/captain
/obj/effect/mob_spawn/human/pirate/gunner
rank = "Gunner"
+14
View File
@@ -607,6 +607,20 @@
dat += "<td><A href='?priv_msg=[blob.key]'>PM</A></td></tr>"
dat += "</table>"
var/list/pirates = get_antagonists(/datum/antagonist/pirate)
if(pirates.len > 0)
dat += "<br><table cellspacing=5><tr><td><B>Pirates</B></td><td></td></tr>"
for(var/datum/mind/N in pirates)
var/mob/M = N.current
if(!M)
dat += "<tr><td><a href='?_src_=vars;[HrefToken()];Vars=\ref[N]'>[N.name]([N.key])</a><i>No body.</i></td>"
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
else
dat += "<tr><td><a href='?_src_=holder;[HrefToken()];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == DEAD ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
if(istype(SSticker.mode, /datum/game_mode/monkey))
var/datum/game_mode/monkey/mode = SSticker.mode
+5 -4
View File
@@ -4,6 +4,8 @@
/obj/effect/mob_spawn
name = "Unknown"
density = TRUE
anchored = TRUE
var/mob_type = null
var/mob_name = ""
var/mob_gender = null
@@ -21,8 +23,7 @@
var/burn_damage = 0
var/mob_color //Change the mob's color
var/assignedrole
density = TRUE
anchored = TRUE
var/show_flavour = TRUE
var/banType = "lavaland"
/obj/effect/mob_spawn/attack_ghost(mob/user)
@@ -60,7 +61,7 @@
/obj/effect/mob_spawn/proc/equip(mob/M)
return
/obj/effect/mob_spawn/proc/create(ckey, flavour = TRUE, name)
/obj/effect/mob_spawn/proc/create(ckey, name)
var/mob/living/M = new mob_type(get_turf(src)) //living mobs only
if(!random)
M.real_name = mob_name ? mob_name : M.name
@@ -80,7 +81,7 @@
if(ckey)
M.ckey = ckey
if(flavour)
if(show_flavour)
to_chat(M, "[flavour_text]")
var/datum/mind/MM = M.mind
if(objectives)
+13 -2
View File
@@ -8,6 +8,7 @@
var/safety_warning = "For safety reasons the automated supply shuttle \
cannot transport live organisms, classified nuclear weaponry or \
homing beacons."
var/blockade_warning = "Bluespace instability detected. Shuttle movement impossible."
light_color = "#E2853D"//orange
@@ -54,8 +55,12 @@
data["docked"] = SSshuttle.supply.mode == SHUTTLE_IDLE
data["loan"] = !!SSshuttle.shuttle_loan
data["loan_dispatched"] = SSshuttle.shuttle_loan && SSshuttle.shuttle_loan.dispatched
data["message"] = SSshuttle.centcom_message || "Remember to stamp and send back the supply manifests."
var/message = "Remember to stamp and send back the supply manifests."
if(SSshuttle.centcom_message)
message = SSshuttle.centcom_message
if(SSshuttle.supplyBlocked)
message = blockade_warning
data["message"] = message
data["supplies"] = list()
for(var/pack in SSshuttle.supply_packs)
var/datum/supply_pack/P = SSshuttle.supply_packs[pack]
@@ -102,6 +107,9 @@
if(!SSshuttle.supply.canMove())
say(safety_warning)
return
if(SSshuttle.supplyBlocked)
say(blockade_warning)
return
if(SSshuttle.supply.getDockedId() == "supply_home")
SSshuttle.supply.emagged = emagged
SSshuttle.supply.contraband = contraband
@@ -116,6 +124,9 @@
if("loan")
if(!SSshuttle.shuttle_loan)
return
if(SSshuttle.supplyBlocked)
say(blockade_warning)
return
else if(SSshuttle.supply.mode != SHUTTLE_IDLE)
return
else if(SSshuttle.supply.getDockedId() != "supply_away")
+22 -4
View File
@@ -78,20 +78,38 @@
suit_store = /obj/item/gun/energy/laser/bluetag
/datum/outfit/pirate
name = "Pirate"
name = "Space Pirate"
uniform = /obj/item/clothing/under/pirate
shoes = /obj/item/clothing/shoes/sneakers/brown
suit = /obj/item/clothing/suit/pirate
head = /obj/item/clothing/head/bandana
glasses = /obj/item/clothing/glasses/eyepatch
r_hand = /obj/item/melee/transforming/energy/sword/pirate
/datum/outfit/pirate/space
name = "Space Pirate"
suit = /obj/item/clothing/suit/space/pirate
head = /obj/item/clothing/head/helmet/space/pirate/bandana
mask = /obj/item/clothing/mask/breath
suit_store = /obj/item/tank/internals/oxygen
ears = /obj/item/device/radio/headset/syndicate
id = /obj/item/card/id
/datum/outfit/pirate/space/captain
head = /obj/item/clothing/head/helmet/space/pirate
/datum/outfit/pirate/post_equip(mob/living/carbon/human/H)
H.faction |= "pirate"
var/obj/item/device/radio/R = H.ears
if(R)
R.set_frequency(GLOB.SYND_FREQ)
R.freqlock = 1
var/obj/item/card/id/W = H.wear_id
if(W)
W.registered_name = H.real_name
W.update_label(H.real_name)
/datum/outfit/tunnel_clown
name = "Tunnel Clown"
@@ -137,10 +137,16 @@ Contains:
item_state = "pirate"
armor = list(melee = 30, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30, fire = 60, acid = 75)
flags_1 = STOPSPRESSUREDMAGE_1
flags_inv = HIDEHAIR
strip_delay = 40
equip_delay_other = 20
flags_cover = HEADCOVERSEYES
/obj/item/clothing/head/helmet/space/pirate/bandana
name = "pirate bandana"
icon_state = "bandana"
item_state = "bandana"
/obj/item/clothing/suit/space/pirate
name = "pirate coat"
desc = "Yarr."
+1 -1
View File
@@ -22,7 +22,7 @@
priority_announce("Due to [cause], [plural] [name] have [movement] \
into the [location].", "Migration Alert",
'sound/effects/mousesqueek.ogg', 100, 1)
'sound/effects/mousesqueek.ogg')
/datum/round_event/mice_migration/start()
SSsqueak.trigger_migration(rand(minimum_mice, maximum_mice))
+280
View File
@@ -0,0 +1,280 @@
#define LOOT_LOCATOR_COOLDOWN 150
/datum/round_event_control/pirates
name = "Space Pirates"
typepath = /datum/round_event/pirates
weight = 8
max_occurrences = 1
min_players = 10
earliest_start = 30 MINUTES
gamemode_blacklist = list("nuclear")
/datum/round_event/pirates
startWhen = 60 //2 minutes to answer
var/datum/comm_message/threat
var/payoff = 0
var/paid_off = FALSE
var/ship_name = "Space Privateers Association"
var/shuttle_spawned = FALSE
/datum/round_event/pirates/setup()
ship_name = pick(strings(PIRATE_NAMES_FILE, "ship_names"))
/datum/round_event/pirates/announce()
priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", 'sound/ai/commandreport.ogg')
if(!control) //Means this is false alarm, todo : explicit checks instead of using announceWhen
return
threat = new
payoff = round(SSshuttle.points * 0.80)
threat.title = "Business proposition"
threat.content = "This is [ship_name]. Pay up [payoff] credits or you'll walk the plank."
threat.possible_answers = list("We'll pay.","No way.")
threat.answer_callback = CALLBACK(src,.proc/answered)
SScommunications.send_message(threat,unique = TRUE)
/datum/round_event/pirates/proc/answered()
if(threat && threat.answered == 1)
if(SSshuttle.points >= payoff)
SSshuttle.points -= payoff
priority_announce("Thanks for the credits, landlubbers.",sender_override = ship_name)
paid_off = TRUE
return
else
priority_announce("Trying to cheat us ? You'll regret this!",sender_override = ship_name)
if(!shuttle_spawned)
spawn_shuttle()
/datum/round_event/pirates/start()
if(!paid_off && !shuttle_spawned)
spawn_shuttle()
/datum/round_event/pirates/proc/spawn_shuttle()
shuttle_spawned = TRUE
var/list/candidates = pollGhostCandidates("Do you wish to be considered for pirate crew ?", ROLE_TRAITOR)
shuffle_inplace(candidates)
var/datum/map_template/pirate_event_ship/ship = new
var/x = rand(TRANSITIONEDGE,world.maxx - TRANSITIONEDGE - ship.width)
var/y = rand(TRANSITIONEDGE,world.maxy - TRANSITIONEDGE - ship.height)
var/z = ZLEVEL_EMPTY_SPACE
var/turf/T = locate(x,y,z)
if(!T)
CRASH("Pirate event found no turf to load in")
if(!ship.load(T))
CRASH("Loading pirate ship failed!")
for(var/turf/A in ship.get_affected_turfs(T))
for(var/obj/effect/mob_spawn/human/pirate/spawner in A)
if(candidates.len > 0)
var/mob/M = candidates[1]
spawner.create(M.ckey)
candidates -= M
else
notify_ghosts("Space pirates are waking up!", source = spawner, action=NOTIFY_ATTACK, flashwindow = FALSE)
priority_announce("Unidentified armed ship detected near the station.")
//Shuttle equipment
/obj/machinery/shuttle_scrambler
name = "Data Siphon"
desc = "This heap of machinery steals credits and data from unprotected systems and locks down cargo shuttles."
icon = 'icons/obj/machines/dominator.dmi'
icon_state = "dominator"
density = TRUE
anchored = TRUE
var/active = FALSE
var/obj/item/device/gps/gps
var/credits_stored = 0
var/siphon_per_tick = 5
/obj/machinery/shuttle_scrambler/Initialize(mapload)
. = ..()
gps = new/obj/item/device/gps/internal/pirate(src)
gps.tracking = FALSE
update_icon()
/obj/machinery/shuttle_scrambler/process()
if(active)
if(z in GLOB.station_z_levels)
var/siphoned = min(SSshuttle.points,siphon_per_tick)
SSshuttle.points -= siphoned
credits_stored += siphoned
steal_tech()
else
return
else
STOP_PROCESSING(SSobj,src)
/obj/machinery/shuttle_scrambler/proc/toggle_on(mob/user)
SSshuttle.registerTradeBlockade(src)
gps.tracking = TRUE
active = TRUE
to_chat(user,"<span class='notice'>You toggle [src] [active ? "on":"off"].</span>")
to_chat(user,"<span class='warning'>The scrambling signal can be now tracked by gps.</span>")
START_PROCESSING(SSobj,src)
/obj/machinery/shuttle_scrambler/interact(mob/user)
if(!active)
if(alert(user, "Turning the scrambler on will make the shuttle trackable by GPS. Are you sure you want to do it ?", "Scrambler", "Yes", "Cancel") == "Cancel")
return
if(active || !user.canUseTopic(src))
return
toggle_on(user)
update_icon()
send_notification()
else
dump_loot(user)
//20% to sap tech levels on unlocked consoles
/obj/machinery/shuttle_scrambler/proc/steal_tech()
if(!prob(20))
return
var/datum/tech/target_tech = pick(subtypesof(/datum/tech))
var/target_id = initial(target_tech.id)
for(var/obj/machinery/computer/rdconsole/C in GLOB.machines)
if(C.screen == RD_CONSOLE_LOCKED_SCREEN || C.stat & (NOPOWER|BROKEN))
continue
var/datum/research/files = C.files
files.LowerTech(target_id,1)
new /obj/effect/temp_visual/emp(get_turf(C))
for(var/obj/machinery/r_n_d/server/S in GLOB.machines)
if(S.stat & (NOPOWER|BROKEN))
continue
var/datum/research/files = S.files
files.LowerTech(target_id,1)
new /obj/effect/temp_visual/emp(get_turf(S))
/obj/machinery/shuttle_scrambler/proc/dump_loot(mob/user)
if(credits_stored < 200)
to_chat(user,"<span class='notice'>Not enough credits to retrieve.</span>")
return
while(credits_stored >= 200)
new /obj/item/stack/spacecash/c200(drop_location())
credits_stored -= 200
to_chat(user,"<span class='notice'>You retrieve the siphoned credits!</span>")
/obj/machinery/shuttle_scrambler/proc/send_notification()
priority_announce("Data theft signal detected, source registered on local gps units.")
/obj/machinery/shuttle_scrambler/proc/toggle_off(mob/user)
SSshuttle.clearTradeBlockade(src)
gps.tracking = FALSE
active = FALSE
STOP_PROCESSING(SSobj,src)
/obj/machinery/shuttle_scrambler/update_icon()
if(active)
icon_state = "dominator-blue"
else
icon_state = "dominator"
/obj/machinery/shuttle_scrambler/Destroy()
toggle_off()
QDEL_NULL(gps)
return ..()
/datum/map_template/pirate_event_ship
name = "Pirate Ship"
mappath = "_maps/templates/pirate_ship.dmm"
/obj/item/device/gps/internal/pirate
gpstag = "Nautical Signal"
desc = "You can hear shanties over the static."
/obj/machinery/computer/shuttle/pirate
name = "pirate shuttle console"
shuttleId = "pirateship"
icon_screen = "syndishuttle"
icon_keyboard = "syndie_key"
light_color = LIGHT_COLOR_RED
possible_destinations = "pirateship_away;pirateship_home;pirateship_custom"
/obj/machinery/computer/camera_advanced/shuttle_docker/syndicate/pirate
name = "pirate shuttle navigation computer"
desc = "Used to designate a precise transit location for the pirate shuttle."
shuttleId = "pirateship"
station_lock_override = TRUE
shuttlePortId = "pirateship_custom"
shuttlePortName = "custom location"
x_offset = 9
y_offset = 0
/obj/docking_port/mobile/pirate
name = "pirate shuttle"
id = "pirateship"
var/engines_cooling = FALSE
var/engine_cooldown = 3 MINUTES
/obj/docking_port/mobile/pirate/getStatusText()
. = ..()
if(engines_cooling)
return "[.] - Engines cooling."
/obj/docking_port/mobile/pirate/dock(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
. = ..()
if(. == DOCKING_SUCCESS && new_dock.z != ZLEVEL_TRANSIT)
engines_cooling = TRUE
addtimer(CALLBACK(src,.proc/reset_cooldown),engine_cooldown,TIMER_UNIQUE)
/obj/docking_port/mobile/pirate/proc/reset_cooldown()
engines_cooling = FALSE
/obj/docking_port/mobile/pirate/canMove()
if(engines_cooling)
return FALSE
return ..()
/obj/machinery/suit_storage_unit/pirate
suit_type = /obj/item/clothing/suit/space
helmet_type = /obj/item/clothing/head/helmet/space
mask_type = /obj/item/clothing/mask/breath
storage_type = /obj/item/tank/internals/oxygen
/obj/machinery/loot_locator
name = "Booty Locator"
desc = "This sophisticated machine scans the nearby space for items of value."
icon = 'icons/obj/machines/research.dmi'
icon_state = "tdoppler"
density = TRUE
anchored = TRUE
var/cooldown = 0
var/result_count = 3 //Show X results.
/obj/machinery/proc/display_current_value()
var/area/current = get_area(src)
var/value = 0
for(var/turf/T in current.contents)
value += export_item_and_contents(T,TRUE, TRUE, dry_run = TRUE)
say("Current vault value : [value] credits.")
/obj/machinery/loot_locator/interact(mob/user)
if(world.time <= cooldown)
to_chat(user,"<span class='warning'>[src] is recharging.</span>")
return
cooldown = world.time + LOOT_LOCATOR_COOLDOWN
display_current_value()
var/list/results = list()
for(var/atom/movable/AM in world)
if(is_type_in_typecache(AM,GLOB.pirate_loot_cache))
if(AM.z in GLOB.station_z_levels)
if(get_area(AM) == get_area(src)) //Should this be variable ?
continue
results += AM
CHECK_TICK
if(!results.len)
say("No valuables located. Try again later.")
else
for(var/i in 1 to result_count)
if(!results.len)
return
var/atom/movable/AM = pick_n_take(results)
var/area/loot_area = get_area(AM)
say("Located: [AM.name] at [loot_area.name]")
#undef LOOT_LOCATOR_COOLDOWN
+2 -2
View File
@@ -387,8 +387,8 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
/mob/proc/reagent_check(datum/reagent/R) // utilized in the species code
return 1
/proc/notify_ghosts(var/message, var/ghost_sound = null, var/enter_link = null, var/atom/source = null, var/mutable_appearance/alert_overlay = null, var/action = NOTIFY_JUMP, flashwindow = TRUE) //Easy notification of ghosts.
if(SSatoms.initialized != INITIALIZATION_INNEW_REGULAR) //don't notify for objects created during a map load
/proc/notify_ghosts(var/message, var/ghost_sound = null, var/enter_link = null, var/atom/source = null, var/mutable_appearance/alert_overlay = null, var/action = NOTIFY_JUMP, flashwindow = TRUE, ignore_mapload = TRUE) //Easy notification of ghosts.
if(ignore_mapload && SSatoms.initialized != INITIALIZATION_INNEW_REGULAR) //don't notify for objects created during a map load
return
for(var/mob/dead/observer/O in GLOB.player_list)
if(O.client)
+10 -1
View File
@@ -315,10 +315,19 @@
/obj/machinery/computer/turbine_computer/Initialize()
. = ..()
return INITIALIZE_HINT_LATELOAD
/obj/machinery/computer/turbine_computer/LateInitialize()
locate_machinery()
/obj/machinery/computer/turbine_computer/locate_machinery()
compressor = locate(/obj/machinery/power/compressor) in range(5, src)
if(id)
for(var/obj/machinery/power/compressor/C in GLOB.machines)
if(C.comp_id == id)
compressor = C
return
else
compressor = locate(/obj/machinery/power/compressor) in range(5, src)
/obj/machinery/computer/turbine_computer/attack_hand(var/mob/user as mob)
if(..())
+1 -2
View File
@@ -28,7 +28,6 @@ won't update every console in existence) but it's more of a hassle to do. Also,
*/
/obj/machinery/computer/rdconsole
name = "R&D Console"
icon_screen = "rdcomp"
@@ -660,7 +659,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
if(0.1)
dat += "<div class='statusDisplay'>Processing and Updating Database...</div>"
if(0.2)
if(RD_CONSOLE_LOCKED_SCREEN)
dat += "<div class='statusDisplay'>SYSTEM LOCKED</div>"
dat += "<A href='?src=[REF(src)];lock=1.6'>Unlock</A>"
+6
View File
@@ -134,6 +134,12 @@ research holder datum.
/datum/research/proc/FindDesignByID(id)
return known_designs[id]
/datum/research/proc/LowerTech(tech_id,value)
var/datum/tech/T = known_tech[tech_id]
T.level = max(initial(T.level),T.level - value)
known_designs.Cut()
RefreshResearch()
//Autolathe files
/datum/research/autolathe/New()
+1 -2
View File
@@ -13,8 +13,7 @@
/obj/machinery/computer/shuttle/attack_hand(mob/user)
if(..(user))
return
src.add_fingerprint(usr)
add_fingerprint(usr)
var/list/options = params2list(possible_destinations)
var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId)
var/dat = "Status: [M ? M.getStatusText() : "*Missing*"]<br><br>"
+31
View File
@@ -0,0 +1,31 @@
{
"beginnings":[
"Star",
"Oort",
"Comet",
"Pulsar",
"Plasma",
"Void",
"Space",
"Solar",
"Laser",
"Ion"
],
"endings":[
"keel",
"beard",
"bilge",
"hull",
"hook",
"flag",
"deck",
"salt",
"knot",
"fish",
"helm"
],
"ship_names":[
"Space Queen's Revenge",
"Syndicate Privateer"
]
}
+2
View File
@@ -317,6 +317,7 @@
#include "code\datums\antagonists\devil.dm"
#include "code\datums\antagonists\internal_affairs.dm"
#include "code\datums\antagonists\ninja.dm"
#include "code\datums\antagonists\pirate.dm"
#include "code\datums\antagonists\revolution.dm"
#include "code\datums\antagonists\wizard.dm"
#include "code\datums\components\_component.dm"
@@ -1389,6 +1390,7 @@
#include "code\modules\events\mice_migration.dm"
#include "code\modules\events\nightmare.dm"
#include "code\modules\events\operative.dm"
#include "code\modules\events\pirates.dm"
#include "code\modules\events\portal_storm.dm"
#include "code\modules\events\prison_break.dm"
#include "code\modules\events\processor_overload.dm"