Merge pull request #3914 from Citadel-Station-13/upstream-merge-31947

[MIRROR] Pirate ship event
This commit is contained in:
LetterJay
2017-11-13 11:52:40 -06:00
committed by GitHub
24 changed files with 3029 additions and 37 deletions

File diff suppressed because it is too large Load Diff

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

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)

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"))

View File

@@ -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

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))

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)

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

View File

@@ -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

View File

@@ -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"

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

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)

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")

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"

View File

@@ -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."

View File

@@ -21,7 +21,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))

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

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)

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(..())

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>"

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()

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
strings/pirates.json Normal file
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"
]
}

View File

@@ -318,6 +318,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"
@@ -1390,6 +1391,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"