Files
GS13NG/code/modules/events/pirates.dm
oranges 43113cd9b5 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.
2017-11-13 03:19:38 -06:00

280 lines
8.7 KiB
Plaintext

#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