Skip to content

Commit

Permalink
Merge pull request #31947 from AnturK/yarr
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
optimumtact authored and CitadelStationBot committed Nov 13, 2017
1 parent 3ea8808 commit 43113cd
Show file tree
Hide file tree
Showing 24 changed files with 3,029 additions and 37 deletions.
2,371 changes: 2,371 additions & 0 deletions _maps/templates/pirate_ship.dmm

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions code/__DEFINES/machines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
32 changes: 16 additions & 16 deletions code/__HELPERS/priority_announce.dm
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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>"
Expand All @@ -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)
Expand Down
1 change: 0 additions & 1 deletion code/_globalvars/lists/names.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
Expand Down
14 changes: 14 additions & 0 deletions code/controllers/subsystem/communications.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
28 changes: 27 additions & 1 deletion code/controllers/subsystem/shuttle.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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))
Expand Down
135 changes: 135 additions & 0 deletions code/datums/antagonists/pirate.dm
Original file line number Diff line number Diff line change
@@ -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 changes: 9 additions & 0 deletions code/game/area/areas/shuttles.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
17 changes: 17 additions & 0 deletions code/game/machinery/computer/communications.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
44 changes: 43 additions & 1 deletion code/game/objects/structures/ghost_role_spawners.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
..()
Expand Down Expand Up @@ -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 changes: 14 additions & 0 deletions code/modules/admin/player_panel.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 43113cd

Please sign in to comment.