Advertisement
Guest User

Untitled

a guest
Mar 15th, 2019
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 32.00 KB | None | 0 0
  1. //marine_ferry.dm
  2. //by MadSnailDisease 12/29/16
  3. //This is essentially a heavy rewrite of standard shuttle/ferry code that allows for the new backend system in shuttle_backend.dm
  4. //Front-end this should look exactly the same, save for a minor timing difference (about 1-3 deciseconds)
  5. //Some of this code is ported from the previous shuttle system and modified for these purposes.
  6.  
  7.  
  8. /*
  9. /client/verb/TestAlmayerEvac()
  10. set name = "Test Almayer Evac"
  11.  
  12. for(var/datum/shuttle/ferry/marine/M in shuttle_controller.process_shuttles)
  13. if(M.info_tag == "Almayer Evac" || M.info_tag == "Alt Almayer Evac")
  14. spawn(1)
  15. M.short_jump()
  16. to_chat(world, "LAUNCHED THING WITH TAG [M.shuttle_tag]")
  17. else if(M.info_tag == "Almayer Dropship")
  18. spawn(1)
  19. M.short_jump()
  20. to_chat(world, "LAUNCHED THING WITH TAG [M.shuttle_tag]")
  21. to_chat(else world, "did not launch thing with tag [M.shuttle_tag]")
  22. */
  23.  
  24. /datum/shuttle/ferry/marine
  25. var/shuttle_tag //Unique ID for finding which landmarks to use
  26. var/info_tag //Identifies which coord datums to copy
  27. var/list/info_datums = list()
  28. //For now it's just one location all around, but that can be adjusted.
  29. var/locs_dock = list()
  30. var/locs_move = list()
  31. var/locs_land = list()
  32. var/turf/loc_attack
  33. var/attackable = 0
  34. var/attacked = 0
  35. //Could be a list, but I don't see a reason considering shuttles aren't bloated with variables.
  36. var/sound_target = 136//Where the sound will originate from. Must be a list index, usually the center bottom (engines).
  37. var/sound/sound_takeoff = 'sound/effects/engine_startup.ogg'//Takeoff sounds.
  38. var/sound/sound_landing = 'sound/effects/engine_landing.ogg'//Landing sounds.
  39. var/sound/sound_moving //Movement sounds, usually not applicable.
  40. var/sound/sound_misc //Anything else, like escape pods.
  41. var/obj/structure/dropship_equipment/list/equipments = list()
  42.  
  43. //Copy of about 650-700 lines down for elevators
  44. var/list/controls = list() //Used to announce failure
  45. var/list/main_doors = list() //Used to check failure
  46. var/fail_flavortext = "<span class='warning'>Could not launch the dropship due to blockage in the rear door.</span>"
  47.  
  48. //Full documentation 650-700 lines down by the copy for elevators
  49. /datum/shuttle/ferry/marine/preflight_checks()
  50.  
  51. if(!main_doors.len && !controls.len)
  52. var/turf/T_src = pick(locs_dock)
  53. var/list/turfs = get_shuttle_turfs(T_src, info_datums)
  54. for(var/turf/T in turfs)
  55. for(var/obj/machinery/M in T)
  56. if(istype(M, /obj/machinery/computer/shuttle_control))
  57. controls += M
  58. else if(istype(M, /obj/machinery/door/airlock/multi_tile/almayer/dropshiprear))
  59. main_doors += M
  60.  
  61. for(var/obj/machinery/door/airlock/multi_tile/almayer/dropshiprear/D in main_doors)
  62. for(var/obj/vehicle/multitile/M in D.loc)
  63. if(M) return 0
  64.  
  65. for(var/turf/T in D.get_filler_turfs())
  66. for(var/obj/vehicle/multitile/M in T)
  67. if(M) return 0
  68.  
  69. //No return 1 here in case future elevators have multiple multi_tile doors
  70.  
  71. return 1
  72.  
  73.  
  74. /datum/shuttle/ferry/marine/announce_preflight_failure()
  75. for(var/obj/machinery/computer/shuttle_control/control in controls)
  76. playsound(control, 'sound/effects/adminhelp-error.ogg', 20) //Arbitrary notification sound
  77. control.visible_message(fail_flavortext)
  78. return //Kill it so as not to repeat
  79.  
  80. /datum/shuttle/ferry/marine/proc/load_datums()
  81. if(!(info_tag in s_info))
  82. message_admins("<span class=warning>Error with shuttles: Shuttle tag does not exist. Code: MSD10.\n WARNING: DROPSHIP LAUNCH WILL PROBABLY FAIL</span>")
  83. log_admin("Error with shuttles: Shuttle tag does not exist. Code: MSD10.")
  84.  
  85. var/list/L = s_info[info_tag]
  86. info_datums = L.Copy()
  87.  
  88. /datum/shuttle/ferry/marine/proc/launch_crash(var/user)
  89. if(!can_launch()) return //There's another computer trying to launch something
  90.  
  91. in_use = user
  92. process_state = FORCE_CRASH
  93.  
  94. /datum/shuttle/ferry/marine/proc/hijack(mob/living/carbon/Xenomorph/M)
  95. if(!queen_locked) //we have not hijacked it yet
  96. if(world.time < SHUTTLE_LOCK_TIME_LOCK)
  97. to_chat(M, "<span class='xenodanger'>You can't mobilize the strength to hijack the shuttle yet. Please wait another [round((SHUTTLE_LOCK_TIME_LOCK-world.time)/600)] minutes before trying again.</span>")
  98. return
  99. to_chat(M, "<span class='xenonotice'>You interact with the machine and disable remote control.</span>")
  100. xeno_message("<span class='xenoannounce'>We have wrested away remote control of the metal bird! Rejoice!</span>",3,M.hivenumber)
  101. last_locked = world.time
  102. queen_locked = TRUE
  103.  
  104. /datum/shuttle/ferry/marine/proc/door_override(mob/living/carbon/Xenomorph/M)
  105. if(!door_override)
  106. to_chat(M, "<span class='xenonotice'>You override the doors.</span>")
  107. xeno_message("<span class='xenoannounce'>The doors of the metal bird have been overridden! Rejoice!</span>",3,M.hivenumber)
  108. last_door_override = world.time
  109. door_override = TRUE
  110.  
  111. var/ship_id = "sh_dropship1"
  112. if(shuttle_tag == "[MAIN_SHIP_NAME] Dropship 2")
  113. ship_id = "sh_dropship2"
  114.  
  115. for(var/obj/machinery/door/airlock/dropship_hatch/D in machines)
  116. if(D.id == ship_id)
  117. D.unlock()
  118.  
  119. var/obj/machinery/door/airlock/multi_tile/almayer/reardoor
  120. switch(ship_id)
  121. if("sh_dropship1")
  122. for(var/obj/machinery/door/airlock/multi_tile/almayer/dropshiprear/ds1/D in machines)
  123. reardoor = D
  124. if("sh_dropship2")
  125. for(var/obj/machinery/door/airlock/multi_tile/almayer/dropshiprear/ds2/D in machines)
  126. reardoor = D
  127.  
  128. reardoor.unlock()
  129.  
  130. /*
  131. Please ensure that long_jump() and short_jump() are only called from here. This applies to subtypes as well.
  132. Doing so will ensure that multiple jumps cannot be initiated in parallel.
  133. */
  134. /datum/shuttle/ferry/marine/process()
  135.  
  136. switch(process_state)
  137. if (WAIT_LAUNCH)
  138. if(!preflight_checks())
  139. announce_preflight_failure()
  140. process_state = IDLE_STATE
  141. return .
  142. if (skip_docking_checks() || docking_controller.can_launch())
  143.  
  144. //to_chat(world, "shuttle/ferry/process: area_transition=[area_transition], travel_time=[travel_time]")
  145. if (move_time) long_jump()
  146. else short_jump()
  147.  
  148. process_state = WAIT_ARRIVE
  149.  
  150. if (FORCE_CRASH)
  151. if(move_time) long_jump_crash()
  152. else short_jump() //If there's no move time, we are doing this normally
  153.  
  154. process_state = WAIT_ARRIVE
  155.  
  156. if (FORCE_LAUNCH)
  157. if (move_time) long_jump()
  158. else short_jump()
  159.  
  160. process_state = WAIT_ARRIVE
  161.  
  162. if (WAIT_ARRIVE)
  163. if (moving_status == SHUTTLE_IDLE)
  164. dock()
  165. in_use = null //release lock
  166. process_state = WAIT_FINISH
  167.  
  168. if (WAIT_FINISH)
  169. if (skip_docking_checks() || docking_controller.docked() || world.time > last_dock_attempt_time + DOCK_ATTEMPT_TIMEOUT)
  170. process_state = IDLE_STATE
  171. arrived()
  172.  
  173. /datum/shuttle/ferry/marine/long_jump()
  174. set waitfor = 0
  175.  
  176. if(moving_status != SHUTTLE_IDLE) return
  177.  
  178. moving_status = SHUTTLE_WARMUP
  179. if(transit_optimized)
  180. recharging = round(recharge_time * SHUTTLE_OPTIMIZE_FACTOR_RECHARGE) //Optimized flight plan means less recharge time
  181. else
  182. recharging = recharge_time //Prevent the shuttle from moving again until it finishes recharging
  183.  
  184. for(var/obj/structure/dropship_equipment/fuel/cooling_system/CS in equipments)
  185. recharging = round(recharging * SHUTTLE_COOLING_FACTOR_RECHARGE) //cooling system reduces recharge time
  186. break
  187.  
  188. //START: Heavy lifting backend
  189.  
  190. //Simple pick() process for now, but this should be changed later.
  191. var/turf/T_src = pick(locs_dock)
  192. var/src_rot = locs_dock[T_src]
  193. var/turf/T_int = pick(locs_move)//int stands for interim
  194. var/int_rot = locs_move[T_int]
  195. var/turf/T_trg = pick(locs_land)
  196. var/trg_rot = locs_land[T_trg]
  197.  
  198. if(transit_gun_mission)//gun mission makes you land back where you started.
  199. T_trg = T_src
  200. trg_rot = src_rot
  201.  
  202. if(!istype(T_src) || !istype(T_int) || !istype(T_trg))
  203. message_admins("<span class=warning>Error with shuttles: Reference turfs not correctly instantiated. Code: MSD02.\n <font size=10>WARNING: DROPSHIP LAUNCH WILL FAIL</font></span>")
  204. log_admin("Error with shuttles: Reference turfs not correctly instantiated. Code: MSD02.")
  205.  
  206. //Switch the landmarks, to swap docking and landing locs, so we can move back and forth.
  207. if(!transit_gun_mission) //gun mission makes you land back where you started. no need to swap dock and land turfs.
  208. locs_dock -= T_src
  209. locs_land -= T_trg
  210. locs_dock |= T_trg
  211. locs_land |= T_src
  212.  
  213. //END: Heavy lifting backend
  214.  
  215. if (moving_status != SHUTTLE_WARMUP)
  216. recharging = 0
  217. return //someone cancelled the launch
  218.  
  219. var/travel_time = 0
  220. if(transit_gun_mission)
  221. travel_time = move_time * 10 //fire missions not made shorter by optimization.
  222. else
  223. if(transit_optimized)
  224. travel_time = move_time * 10 * SHUTTLE_OPTIMIZE_FACTOR_TRAVEL
  225. else
  226. travel_time = move_time * 10
  227.  
  228. for(var/X in equipments)
  229. var/obj/structure/dropship_equipment/E = X
  230. if(istype(E, /obj/structure/dropship_equipment/fuel/fuel_enhancer))
  231. travel_time = round(travel_time * SHUTTLE_FUEL_ENHANCE_FACTOR_TRAVEL) //fuel enhancer reduces travel time
  232. break
  233.  
  234. //START: Heavy lifting backend
  235.  
  236. var/list/turfs_src = get_shuttle_turfs(T_src, info_datums) //Which turfs are we moving?
  237.  
  238. playsound(turfs_src[sound_target], sound_takeoff, 60, 0)
  239.  
  240. sleep(warmup_time*10) //Warming up
  241.  
  242. moving_status = SHUTTLE_INTRANSIT
  243.  
  244. for(var/X in equipments)
  245. var/obj/structure/dropship_equipment/E = X
  246. E.on_launch()
  247.  
  248. close_doors(turfs_src) //Close the doors
  249.  
  250. target_turf = T_int
  251. target_rotation = int_rot
  252. shuttle_turfs = turfs_src
  253.  
  254. // Hand the move off to the shuttle_controller
  255. move_scheduled = 1
  256.  
  257. // Wait for move to be completed
  258. while (move_scheduled)
  259. sleep(10)
  260.  
  261. var/list/turfs_int = get_shuttle_turfs(T_int, info_datums) //Interim turfs
  262. var/list/turfs_trg = get_shuttle_turfs(T_trg, info_datums) //Final destination turfs <insert bad jokey reference here>
  263.  
  264. close_doors(turfs_int) // adding this for safety.
  265.  
  266. var/list/lightssource = get_landing_lights(T_src)
  267. for(var/obj/machinery/landinglight/F in lightssource)
  268. if(F.id == shuttle_tag)
  269. F.turn_off()
  270.  
  271. attackable = 1
  272. var/checktime = travel_time / 10
  273. var/iterator
  274. // checks 10 times per flight if the dropship has been attacked
  275. for(iterator = 0, iterator<11, iterator++)
  276. sleep(checktime)
  277. if(attacked)
  278. shoot_down(trg_rot, turfs_int)
  279. attackable = 0
  280. return
  281. attackable = 0
  282.  
  283.  
  284. if(EvacuationAuthority.dest_status >= NUKE_EXPLOSION_IN_PROGRESS) return FALSE //If a nuke is in progress, don't attempt a landing.
  285.  
  286. playsound(turfs_int[sound_target], sound_landing, 60, 0)
  287. playsound(turfs_trg[sound_target], sound_landing, 60, 0)
  288.  
  289. var/list/lightsdest = get_landing_lights(T_trg)
  290. for(var/obj/machinery/landinglight/F in lightsdest)
  291. if(F.id == shuttle_tag)
  292. F.turn_on()
  293.  
  294. sleep(100) //Wait for it to finish.
  295.  
  296. if(EvacuationAuthority.dest_status == NUKE_EXPLOSION_FINISHED) return FALSE //If a nuke finished, don't land.
  297.  
  298. target_turf = T_trg
  299. target_rotation = trg_rot
  300. shuttle_turfs = turfs_int
  301.  
  302. // Hand the move off to the shuttle_controller
  303. move_scheduled = 1
  304.  
  305. // Wait for move to be completed
  306. while (move_scheduled)
  307. sleep(10)
  308.  
  309. //Now that we've landed, assuming some rotation including 0, we need to make sure it doesn't fuck up when we go back
  310. locs_move[T_int] = -1*trg_rot
  311. if(!transit_gun_mission)
  312. locs_dock[T_trg] = src_rot
  313. locs_land[T_src] = trg_rot
  314.  
  315. //We have to get these again so we can close the doors
  316. //We didn't need to do it before since they hadn't moved yet
  317. turfs_trg = get_shuttle_turfs(T_trg, info_datums)
  318.  
  319. open_doors(turfs_trg) //And now open the doors
  320.  
  321. //END: Heavy lifting backend
  322.  
  323. for(var/X in equipments)
  324. var/obj/structure/dropship_equipment/E = X
  325. E.on_arrival()
  326.  
  327. moving_status = SHUTTLE_IDLE
  328.  
  329. if(!transit_gun_mission) //we're back where we started, no location change.
  330. location = !location
  331.  
  332. transit_optimized = 0 //De-optimize the flight plans
  333. transit_gun_mission = 0 //no longer on a fire mission.
  334.  
  335. //Simple, cheap ticker
  336. if(recharge_time)
  337. while(recharging > 0)
  338. recharging--
  339. sleep(1)
  340.  
  341. //Starts out exactly the same as long_jump()
  342. //Differs in the target selection and later things enough to merit it's own proc
  343. //The backend for landmarks should be in it's own proc, but I use too many vars resulting from the backend to save much space
  344. /datum/shuttle/ferry/marine/proc/long_jump_crash()
  345. set waitfor = 0
  346.  
  347. if(moving_status != SHUTTLE_IDLE) return
  348.  
  349. moving_status = SHUTTLE_WARMUP
  350. if(transit_optimized)
  351. recharging = round(recharge_time * SHUTTLE_OPTIMIZE_FACTOR_RECHARGE) //Optimized flight plan means less recharge time
  352. else
  353. recharging = recharge_time //Prevent the shuttle from moving again until it finishes recharging
  354.  
  355. //START: Heavy lifting backend
  356. var/turf/T_src = pick(locs_dock)
  357. var/src_rot = locs_dock[T_src]
  358. var/turf/T_int = pick(locs_move)//int stands for interim
  359. var/turf/T_trg = pick(shuttle_controller.locs_crash)
  360.  
  361. for(var/X in equipments)
  362. var/obj/structure/dropship_equipment/E = X
  363. if(istype(E, /obj/structure/dropship_equipment/adv_comp/docking))
  364. var/list/crash_turfs = list()
  365. for(var/turf/TU in shuttle_controller.locs_crash)
  366. if(istype(get_area(TU), /area/almayer/hallways/hangar))
  367. crash_turfs += TU
  368. if(crash_turfs.len) T_trg = pick(crash_turfs)
  369. else message_admins("\blue no crash turf found in Almayer Hangar, contact coders.")
  370. break
  371.  
  372. if(!istype(T_src) || !istype(T_int) || !istype(T_trg))
  373. message_admins("<span class=warning>Error with shuttles: Reference turfs not correctly instantiated. Code: MSD04.\n WARNING: DROPSHIP LAUNCH WILL FAIL</span>")
  374. log_admin("Error with shuttles: Reference turfs not correctly instantiated. Code: MSD04.")
  375.  
  376. shuttle_controller.locs_crash -= T_trg
  377.  
  378. //END: Heavy lifting backend
  379.  
  380. if (moving_status == SHUTTLE_IDLE)
  381. recharging = 0
  382. return //someone canceled the launch
  383.  
  384. var/travel_time = 0
  385. travel_time = DROPSHIP_CRASH_TRANSIT_DURATION * 10
  386.  
  387. //START: Heavy lifting backend
  388.  
  389. var/list/turfs_src = get_shuttle_turfs(T_src, info_datums) //Which turfs are we moving?
  390. playsound(turfs_src[sound_target], sound_takeoff, 60, 0)
  391.  
  392. sleep(warmup_time*10) //Warming up
  393.  
  394. moving_status = SHUTTLE_INTRANSIT
  395.  
  396. for(var/X in equipments)
  397. var/obj/structure/dropship_equipment/E = X
  398. E.on_launch()
  399.  
  400. close_doors(turfs_src) //Close the doors
  401.  
  402. target_turf = T_int
  403. target_rotation = 0
  404. shuttle_turfs = turfs_src
  405.  
  406. // Hand the move off to the shuttle_controller
  407. move_scheduled = 1
  408.  
  409. // Wait for move to be completed
  410. while (move_scheduled)
  411. sleep(10)
  412.  
  413. var/list/turfs_int = get_shuttle_turfs(T_int, info_datums) //Interim turfs
  414.  
  415. close_doors(turfs_int) // adding this for safety.
  416.  
  417. var/list/lights = get_landing_lights(T_src)
  418. for(var/obj/machinery/landinglight/F in lights)
  419. if(F.id == shuttle_tag)
  420. F.turn_off()
  421.  
  422. // sanity checking
  423. var/datum/hive_status/hive = hive_datum[XENO_HIVE_NORMAL]
  424. var/list/left_behind = list()
  425. var/list/with_queen = list()
  426. for(var/mob/living/carbon/Xenomorph/xeno in living_xeno_list)
  427. if(xeno.hivenumber != XENO_HIVE_NORMAL) continue
  428. if(xeno.loc.z == hive.living_xeno_queen.loc.z || xeno.loc.z in MAIN_SHIP_AND_DROPSHIPS_Z_LEVELS) // yes loc because of vent crawling, xeno must be with queen or on round end Z levels
  429. with_queen += xeno
  430. else
  431. left_behind += xeno
  432. if(with_queen.len > left_behind.len) // to stop solo-suiciding by queens
  433. ticker.mode.stored_larva = 0
  434. for(var/mob/living/carbon/Xenomorph/about_to_die in left_behind)
  435. to_chat(about_to_die, "<span class='xenoannounce'>The Queen has left without you, you quickly find a hiding place to enter hibernation as you lose touch with the hive mind.</span>")
  436. cdel(about_to_die) // just delete them
  437. for(var/mob/living/carbon/potential_host in living_mob_list)
  438. if(potential_host.loc.z != 1) continue // ground level
  439. if(potential_host.status_flags & XENO_HOST) // a host
  440. for(var/obj/item/alien_embryo/embryo in potential_host)
  441. cdel(embryo)
  442. for(var/mob/living/carbon/Xenomorph/Larva/larva in potential_host)
  443. cdel(larva)
  444.  
  445. sleep(travel_time) //Wait while we fly, but give extra time for crashing announcements etc
  446.  
  447. if(EvacuationAuthority.dest_status >= NUKE_EXPLOSION_IN_PROGRESS) return FALSE //If a nuke is in progress, don't attempt a landing.
  448.  
  449. //This is where things change and shit gets real
  450.  
  451. command_announcement.Announce("DROPSHIP ON COLLISION COURSE. CRASH IMMINENT." , "EMERGENCY", new_sound='sound/AI/dropship_emergency.ogg')
  452.  
  453. playsound(turfs_int[sound_target], sound_landing, 60, 0)
  454.  
  455. sleep(85)
  456.  
  457. if(EvacuationAuthority.dest_status == NUKE_EXPLOSION_FINISHED) return FALSE //If a nuke finished, don't land.
  458.  
  459. shake_cameras(turfs_int) //shake for 1.5 seconds before crash, 0.5 after
  460.  
  461. for(var/obj/machinery/power/apc/A in machines) //break APCs
  462. if(A.z != T_trg.z) continue
  463. if(prob(A.crash_break_probability))
  464. A.overload_lighting()
  465. A.set_broken()
  466.  
  467. var/turf/sploded
  468. for(var/j=0; j<10; j++)
  469. sploded = locate(T_trg.x + rand(-5, 15), T_trg.y + rand(-5, 25), T_trg.z)
  470. //Fucking. Kaboom.
  471. explosion(sploded, 0, 5, 10, 0)
  472. sleep(3)
  473.  
  474. explosion(get_turf(HangarLowerElevator), 0, 3, 5, 0)
  475. var/datum/shuttle/ferry/hangar/hangarelevator = shuttle_controller.shuttles["Hangar"]
  476. hangarelevator.process_state = FORCE_CRASH
  477.  
  478. for(var/mob/living/carbon/M in mob_list) //knock down mobs
  479. if(M.z != T_trg.z) continue
  480. if(M.buckled)
  481. to_chat(M, "\red You are jolted against [M.buckled]!")
  482. shake_camera(M, 3, 1)
  483. else
  484. to_chat(M, "\red The floor jolts under your feet!")
  485. shake_camera(M, 10, 1)
  486. M.KnockDown(3)
  487.  
  488. enter_allowed = 0 //No joining after dropship crash
  489.  
  490. var/list/turfs_trg = get_shuttle_turfs(T_trg, info_datums) //Final destination turfs <insert bad jokey reference here>
  491.  
  492. target_turf = T_trg
  493. target_rotation = src_rot
  494. shuttle_turfs = turfs_int
  495.  
  496. // Hand the move off to the shuttle_controller
  497. move_scheduled = 1
  498.  
  499. // Wait for move to be completed
  500. while (move_scheduled)
  501. sleep(10)
  502.  
  503. //We have to get these again so we can close the doors
  504. //We didn't need to do it before since the hadn't moved yet
  505. turfs_trg = get_shuttle_turfs(T_trg, info_datums)
  506.  
  507. for(var/X in equipments)
  508. var/obj/structure/dropship_equipment/E = X
  509. E.on_arrival()
  510.  
  511. open_doors_crashed(turfs_trg) //And now open the doors
  512.  
  513. //Stolen from events.dm. WARNING: This code is old as hell
  514. for (var/obj/machinery/power/apc/APC in machines)
  515. if(APC.z == MAIN_SHIP_Z_LEVEL || APC.z == LOW_ORBIT_Z_LEVEL)
  516. APC.ion_act()
  517. for (var/obj/machinery/power/smes/SMES in machines)
  518. if(SMES.z == MAIN_SHIP_Z_LEVEL || SMES.z == LOW_ORBIT_Z_LEVEL)
  519. SMES.ion_act()
  520.  
  521. if(security_level < SEC_LEVEL_RED) //automatically set security level to red.
  522. set_security_level(SEC_LEVEL_RED, TRUE)
  523.  
  524. //END: Heavy lifting backend
  525.  
  526. sleep(100)
  527. moving_status = SHUTTLE_CRASHED
  528.  
  529.  
  530.  
  531. /datum/shuttle/ferry/marine/short_jump()
  532.  
  533. if(moving_status != SHUTTLE_IDLE) return
  534.  
  535. //START: Heavy lifting backend
  536.  
  537. var/turf/T_src = pick(locs_dock)
  538. var/turf/T_trg = pick(locs_land)
  539. var/trg_rot = locs_land[T_trg]
  540.  
  541. //Switch the landmarks so we can do this again
  542. if(!istype(T_src) || !istype(T_trg))
  543. message_admins("<span class=warning>Error with shuttles: Ref turfs are null. Code: MSD15.\n WARNING: DROPSHIPS MAY NO LONGER BE OPERABLE</span>")
  544. log_admin("Error with shuttles: Ref turfs are null. Code: MSD15.")
  545. return FALSE
  546.  
  547. locs_dock -= T_src
  548. locs_land -= T_trg
  549. locs_dock |= T_trg
  550. locs_land |= T_src
  551.  
  552. //END: Heavy lifting backend
  553.  
  554. moving_status = SHUTTLE_WARMUP
  555.  
  556. sleep(warmup_time*10)
  557.  
  558. if (moving_status == SHUTTLE_IDLE)
  559. return //someone cancelled the launch
  560.  
  561. moving_status = SHUTTLE_INTRANSIT //shouldn't matter but just to be safe
  562.  
  563. for(var/X in equipments)
  564. var/obj/structure/dropship_equipment/E = X
  565. E.on_launch()
  566.  
  567. var/list/turfs_src = get_shuttle_turfs(T_src, info_datums)
  568. move_shuttle_to(T_trg, null, turfs_src, 0, trg_rot, src)
  569.  
  570. for(var/X in equipments)
  571. var/obj/structure/dropship_equipment/E = X
  572. E.on_arrival()
  573.  
  574. moving_status = SHUTTLE_IDLE
  575.  
  576. location = !location
  577.  
  578.  
  579. /datum/shuttle/ferry/marine/close_doors(var/list/L)
  580.  
  581. var/i //iterator
  582. var/turf/T
  583.  
  584. for(i in L)
  585. T = i
  586. if(!istype(T)) continue
  587.  
  588. //I know an iterator is faster, but this broke for some reason when I used it so I won't argue
  589. for(var/obj/machinery/door/poddoor/shutters/transit/ST in T)
  590. if(!istype(ST)) continue
  591. if(!ST.density)
  592. //"But MadSnailDisease!", you say, "Don't use spawn! Use sleep() and waitfor instead!
  593. //Well you would be right if close() were different, but alas it is not.
  594. //Without spawn(), it closes each door one at a time.
  595. //"Well then why not change the proc itself?"
  596. //Excellent question!
  597. //Because when you open doors by Bumped() it would have you fly through before the animation is complete
  598. spawn(0)
  599. ST.close()
  600. break
  601.  
  602. //Elevators
  603. if (iselevator)
  604. for(var/obj/machinery/door/airlock/A in T)
  605. if(!istype(A)) continue
  606. if(!A.density)
  607. spawn(0)
  608. A.close()
  609. A.lock()
  610. else
  611. A.lock() //We need this here since it's important to lock and update AFTER its closed
  612. break
  613. else
  614. for(var/obj/machinery/door/airlock/dropship_hatch/M in T)
  615. if(M.locked && M.density)
  616. continue // jobs done
  617. else if(!M.locked && M.density)
  618. M.lock() // closed but not locked yet
  619. continue
  620. else
  621. spawn(0)
  622. M.unlock()
  623. sleep(1)
  624. M.close(1)
  625. sleep(M.openspeed + 1)
  626. M.lock()
  627.  
  628. for(var/obj/machinery/door/airlock/multi_tile/almayer/dropshiprear/D in T)
  629. if(!D.locked && D.density)
  630. D.lock() // closed but not locked yet
  631. else if(D.locked && !D.density)
  632. spawn(0)
  633. D.unlock()
  634. sleep(1)
  635. D.close()
  636. sleep(D.openspeed + 1) // let it close
  637. D.lock() // THEN lock it
  638. else
  639. spawn(0)
  640. D.close()
  641. sleep(D.openspeed + 1)
  642. D.lock()
  643.  
  644. /datum/shuttle/ferry/marine/open_doors(var/list/L)
  645. var/i //iterator
  646. var/turf/T
  647.  
  648. for(i in L)
  649. T = i
  650. if(!istype(T)) continue
  651.  
  652. //Just so marines can't land with shutters down and turtle the rasputin
  653. for(var/obj/machinery/door/poddoor/shutters/P in T)
  654. if(!istype(P)) continue
  655. if(P.density)
  656. spawn(0)
  657. P.open()
  658. //No break since transit shutters are the same parent type
  659.  
  660. if (iselevator)
  661. for(var/obj/machinery/door/airlock/A in T)
  662. if(!istype(A)) continue
  663. if(A.locked)
  664. A.unlock()
  665. if(A.density)
  666. spawn(0)
  667. A.open()
  668. break
  669. else
  670. for(var/obj/machinery/door/airlock/dropship_hatch/M in T)
  671. M.unlock()
  672.  
  673. for(var/obj/machinery/door/airlock/multi_tile/almayer/dropshiprear/D in T)
  674. D.unlock()
  675.  
  676.  
  677.  
  678. /datum/shuttle/ferry/marine/proc/open_doors_crashed(var/list/L)
  679.  
  680. var/i //iterator
  681. var/turf/T
  682.  
  683. for(i in L)
  684. T = i
  685. if(!istype(T)) continue
  686.  
  687. if(istype(T, /turf/closed/wall))
  688. var/turf/closed/wall/W = T
  689. if(prob(20)) W.thermitemelt()
  690. else if(prob(25)) W.take_damage(W.damage_cap) //It should leave a girder
  691. continue
  692.  
  693. //Just so marines can't land with shutters down and turtle the rasputin
  694. for(var/obj/machinery/door/poddoor/shutters/P in T)
  695. if(!istype(P)) continue
  696. if(P.density)
  697. spawn(0)
  698. P.open()
  699. //No break since transit shutters are the same parent type
  700.  
  701. for(var/obj/structure/mineral_door/resin/R in T)
  702. if(istype(R))
  703. cdel(R) //This is all that it's dismantle() does so this is okay
  704. break
  705.  
  706. for(var/obj/machinery/door/airlock/dropship_hatch/M in T)
  707. cdel(M)
  708.  
  709. for(var/obj/machinery/door/airlock/multi_tile/almayer/dropshiprear/D in T)
  710. cdel(D)
  711.  
  712. /datum/shuttle/ferry/marine/proc/shake_cameras(var/list/L)
  713.  
  714. var/i //iterator
  715. var/j
  716. var/turf/T
  717. var/mob/M
  718.  
  719. for(i in L)
  720. T = i
  721. if(!istype(T)) continue
  722.  
  723. for(j in T)
  724. M = j
  725. if(!istype(M)) continue
  726. shake_camera(M, 30, 1)
  727.  
  728. /client/proc/force_shuttle()
  729. set name = "Force Dropship"
  730. set desc = "Force a dropship to launch"
  731. set category = "Admin"
  732.  
  733. var/tag = input("Which dropship should be force launched?", "Select a dropship:") as null|anything in list("Dropship 1", "Dropship 2")
  734. if(!tag) return
  735. var/crash = 0
  736. switch(alert("Would you like to force a crash?", , "Yes", "No", "Cancel"))
  737. if("Yes") crash = 1
  738. if("No") crash = 0
  739. else return
  740.  
  741. var/datum/shuttle/ferry/marine/dropship = shuttle_controller.shuttles[MAIN_SHIP_NAME + " " + tag]
  742. if(!dropship)
  743. to_chat(src, "<span class='danger'>Error: Attempted to force a dropship launch but the shuttle datum was null. Code: MSD_FSV_DIN</span>")
  744. log_admin("Error: Attempted to force a dropship launch but the shuttle datum was null. Code: MSD_FSV_DIN")
  745. return
  746.  
  747. if(crash && dropship.location != 1)
  748. switch(alert("Error: Shuttle is on the ground. Proceed with standard launch anyways?", , "Yes", "No"))
  749. if("Yes")
  750. dropship.process_state = WAIT_LAUNCH
  751. log_admin("[usr] ([usr.key]) forced a [dropship.iselevator? "elevator" : "shuttle"] using the Force Dropship verb")
  752. if("No")
  753. to_chat(src, "<span class='warning'>Aborting shuttle launch.</span>")
  754. return
  755. else if(crash)
  756. dropship.process_state = FORCE_CRASH
  757. else
  758. dropship.process_state = WAIT_LAUNCH
  759.  
  760.  
  761. /* QUICK INHERITANCE THING FOR ELEVATORS
  762. NOTE: Elevators do NOT use the above system, they inherit from /datum/shuttle/ferry not /datum/shuttle/ferry/marine */
  763.  
  764. /datum/shuttle/ferry/elevator
  765. var/list/controls = list() //Used to announce failure
  766. var/list/main_doors = list() //Used to check failure
  767. var/fail_flavortext = "<span class='warning'>Could not move the elevator due to blockage in the main door.</span>"
  768.  
  769. /datum/shuttle/ferry/elevator/New()
  770. ..()
  771. for(var/obj/machinery/M in get_location_area(location))
  772. if(istype(M, /obj/machinery/computer/shuttle_control))
  773. controls += M
  774. else if(istype(M, /obj/machinery/door/airlock/multi_tile/))
  775. main_doors += M
  776.  
  777. //Kinda messy proc, but the best solution to prevent shearing of multitile vehicles
  778. //Alternatives include:
  779. //1. A ticker that verifies that all multi_tile vics aren't out of wack
  780. // -Two problems here, intersection of movement and verication would cause issues and this idea is dumb and expensive
  781. //2. Somewhere in the shuttle_backend, every time you move a multi_tile vic hitbox or root, tell the vic to update when the move completes
  782. // -Issues here are that this is not atomic at all and vics get left behind unless the entirety of them is on the shuttle/elevator,
  783. // plus then part of the vic would be in space since elevators leave that behind
  784. /datum/shuttle/ferry/elevator/preflight_checks()
  785. for(var/obj/machinery/door/airlock/multi_tile/E in main_doors)
  786. //If there is part of a multitile vic in any of the turfs the door occupies, cancel
  787. //An argument can be made for tanks being allowed to block the door, but
  788. // that would make this already relatively expensive and inefficent even more so
  789. // --MadSnailDisease
  790. for(var/obj/vehicle/multitile/M in E.loc)
  791. if(M) return 0
  792.  
  793. for(var/turf/T in E.locs) //For some reason elevators use different multidoor code, this should work though
  794. for(var/obj/vehicle/multitile/M in T)
  795. if(M) return 0
  796.  
  797. //No return 1 here in case future elevators have multiple multi_tile doors
  798.  
  799. return 1
  800.  
  801.  
  802. /datum/shuttle/ferry/elevator/announce_preflight_failure()
  803. for(var/obj/machinery/computer/shuttle_control/control in controls)
  804. playsound(control, 'sound/effects/adminhelp-error.ogg', 20) //Arbitrary notification sound
  805. control.visible_message(fail_flavortext)
  806. return //Kill it so as not to repeat
  807.  
  808. /obj/effect/landmark/crs
  809. var/turf/site
  810. invisibility = 0
  811.  
  812. /obj/effect/landmark/crs/New()
  813. ..()
  814. site = get_turf(src)
  815. sleep(5)
  816. for(var/datum/shuttle/ferry/marine/M in shuttle_controller.process_shuttles)
  817. if(M.info_tag == "Almayer Dropship")
  818. M.loc_attack = site
  819. message_admins("[site] has been set to be the crashsite.")
  820. cdel(src)
  821.  
  822. /obj/effect/landmark/crs/crashsite
  823. name = "custom crashsite"
  824.  
  825. // this probably belongs in a .dm for adminverbs but I'm keeping it here for simplicity sake for this application
  826. /datum/admins/proc/attack_dropship()
  827. set category = "Fun"
  828. set name = "Attack Dropship"
  829. set desc = "Attack a Dropship and make it crash!"
  830.  
  831. if(!check_rights(R_FUN))
  832. return
  833.  
  834. var/shuttletag = input("Which dropship should be attacked?", "Select a dropship:") as null|anything in list("USS Almayer Dropship 1", "USS Almayer Dropship 2")
  835. if(!shuttletag) return
  836. for(var/datum/shuttle/ferry/marine/M in shuttle_controller.process_shuttles)
  837. if(M.shuttle_tag == "[shuttletag]")
  838. if((M.attackable == 1) && (M.loc_attack))
  839. M.attacked = 1
  840. message_admins("[key_name_admin(usr)] has attacked the [shuttletag].")
  841. else if(!M.loc_attack)
  842. message_admins("[key_name_admin(usr)] tried attacking [shuttletag] but no crashsite has been set.")
  843. else
  844. message_admins("[key_name_admin(usr)] tried attacking [shuttletag] but failed since it isn't currently attackable.")
  845.  
  846. /datum/shuttle/ferry/marine/proc/shoot_down(trgrot, shuttleturfs)
  847. // Set the crash landing site
  848. target_turf = loc_attack
  849. target_rotation = trgrot
  850. shuttle_turfs = shuttleturfs
  851. var/list/turfs_trg = get_shuttle_turfs(loc_attack, info_datums)
  852. var/sound/missile1 = 'sound/misc/missile1.ogg' // 5.2 seconds long
  853. var/sound/missile2 = 'sound/misc/missile2.ogg' // 4 seconds long
  854. var/sound/explode = 'sound/effects/Explosion1.ogg'
  855. var/sound/smokesound = 'sound/effects/smoke.ogg'
  856.  
  857. // Dramatic effects!
  858. var/datum/effect_system/smoke_spread/bad/smoke = new /datum/effect_system/smoke_spread/bad
  859. var/datum/effect_system/spark_spread/spark = new /datum/effect_system/spark_spread
  860.  
  861. var/dsname //there has to be a better way to do this...
  862. if(shuttle_tag == "USS Almayer Dropship 1")
  863. dsname = "Alamo"
  864. else
  865. dsname = "Normandy"
  866.  
  867. playsound(shuttle_turfs[98], missile1, 60, 0) // turf 98 is below the intercom in the center
  868. sleep(45)
  869. command_announcement.Announce("SAM Launch detected! Missile inbound to Dropship [dsname]. Recommending evasive maneuvers.", "Radar Warning!", new_sound = 'sound/misc/notice1.ogg')
  870. playsound(shuttle_turfs[98], missile2, 60, 0) // missile inbound!
  871. sleep(38)
  872. playsound(shuttle_turfs[98], explode, 60, 0) // no damaging explosion, just the sound. Though you can easily create some grenade-level explosions in the ship if you really want.
  873.  
  874. // Bunch of effects
  875. smoke.set_up(1, 0, shuttle_turfs[137], null, 6) // turf 137 is bottom left seats
  876. smoke.start()
  877. playsound(shuttle_turfs[137], smokesound, 25, 1, 4)
  878. smoke.set_up(1, 0, shuttle_turfs[64], null, 6) // 64 is just above right hatch
  879. smoke.start()
  880. playsound(shuttle_turfs[64], smokesound, 25, 1, 4)
  881. spark.set_up(5, 3, shuttle_turfs[98])
  882. spark.start()
  883. sleep(1)
  884. spark.set_up(5, 3, shuttle_turfs[37])
  885. spark.start()
  886. sleep(1)
  887. spark.set_up(5, 3, shuttle_turfs[20]) // right between the pilots
  888. spark.start()
  889.  
  890.  
  891. for(var/turf/T in shuttle_turfs)
  892. for(var/atom/movable/A in T)
  893. if(ismob(A) && iscarbon(A))
  894. var/mob/living/carbon/M = A
  895. // chance to unbuckle people
  896. if(M.buckled && prob(50))
  897. M.buckled.unbuckle()
  898. shake_camera(M, 2, 2)
  899. if(!M.buckled)
  900. M.KnockDown(3)
  901. if(prob(50))
  902. step_rand(M, 1) // fling them around maybe
  903. else if(!A.anchored)
  904. step_rand(A, 1) // throw everything not bolted down around!
  905. if(prob(50))
  906. step_rand(A, 1)
  907.  
  908. sleep(10)
  909. playsound(shuttle_turfs[sound_target], sound_landing, 60, 0) // 10 seconds till impact
  910. sleep(60)
  911.  
  912. shake_cameras(shuttle_turfs) // 2 second shake
  913. smoke.set_up(1, 0, shuttle_turfs[98], null, 6)
  914. smoke.start()
  915. spark.set_up(5, 3, shuttle_turfs[37])
  916. spark.start()
  917. sleep(20)
  918. spark.set_up(5, 3, shuttle_turfs[64])
  919. spark.start()
  920. shake_cameras(shuttle_turfs)
  921. sleep(20)
  922. spark.set_up(5, 3, shuttle_turfs[137])
  923. spark.start()
  924. shake_cameras(shuttle_turfs)
  925.  
  926. var/turf/sploded // Copied from the xeno crash
  927. for(var/j=0; j<10; j++)
  928. sploded = locate(target_turf.x + rand(-5, 15), target_turf.y + rand(-5, 15), target_turf.z)
  929. explosion(sploded, 0, 5, 10, 0)
  930. sleep(3)
  931.  
  932. // Hand the move off to the shuttle_controller
  933. move_scheduled = 1
  934.  
  935. // Wait for move to be completed
  936. while (move_scheduled)
  937. sleep(10)
  938.  
  939. open_doors_crashed(turfs_trg)
  940.  
  941. sleep(100)
  942. moving_status = SHUTTLE_CRASHED
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement