-
-
Notifications
You must be signed in to change notification settings - Fork 444
/
Copy pathbsa.dm
335 lines (293 loc) · 9.92 KB
/
bsa.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
// Crew has to build a bluespace cannon
// Cargo orders part for high price
// Requires high amount of power
// Requires high level stock parts
/datum/station_goal/bluespace_cannon
name = "Bluespace Artillery"
/datum/station_goal/bluespace_cannon/get_report()
return {"Our military presence is inadequate in your sector.
We need you to construct BSA-[rand(1,99)] Artillery position aboard your station.
Base parts are available for shipping via cargo.
-Nanotrasen Naval Command"}
/datum/station_goal/bluespace_cannon/on_report()
//Unlock BSA parts
var/datum/supply_pack/engineering/bsa/P = SSshuttle.supply_packs[/datum/supply_pack/engineering/bsa]
P.special_enabled = TRUE
/datum/station_goal/bluespace_cannon/check_completion()
if(..())
return TRUE
var/obj/machinery/bsa/full/B = locate()
if(B && !B.stat)
return TRUE
return FALSE
/obj/machinery/bsa
icon = 'icons/obj/machines/particle_accelerator.dmi'
density = TRUE
anchored = TRUE
/obj/machinery/bsa/wrench_act(mob/living/user, obj/item/I)
default_unfasten_wrench(user, I, 10)
return TRUE
/obj/machinery/bsa/back
name = "Bluespace Artillery Generator"
desc = "Generates cannon pulse. Needs to be linked with a fusor."
icon_state = "power_box"
/obj/machinery/bsa/back/multitool_act(mob/living/user, obj/item/I)
if(!multitool_check_buffer(user, I)) //make sure it has a data buffer
return
multitool_set_buffer(user, I, src)
to_chat(user, span_notice("You store linkage information in [I]'s buffer."))
return TRUE
/obj/machinery/bsa/front
name = "Bluespace Artillery Bore"
desc = "Do not stand in front of cannon during operation. Needs to be linked with a fusor."
icon_state = "emitter_center"
/obj/machinery/bsa/front/multitool_act(mob/living/user, obj/item/I)
if(!multitool_check_buffer(user, I)) //make sure it has a data buffer
return
multitool_set_buffer(user, I, src)
to_chat(user, span_notice("You store linkage information in [I]'s buffer."))
return TRUE
/obj/machinery/bsa/middle
name = "Bluespace Artillery Fusor"
desc = "Contents classified by Nanotrasen Naval Command. Needs to be linked with the other BSA parts using multitool."
icon_state = "fuel_chamber"
var/obj/machinery/bsa/back/back
var/obj/machinery/bsa/front/front
/obj/machinery/bsa/middle/multitool_act(mob/living/user, obj/item/I)
if(!multitool_check_buffer(user, I))
return
var/atom/buffer_atom = multitool_get_buffer(user, I)
if(buffer_atom)
if(istype(buffer_atom, /obj/machinery/bsa/back))
back = buffer_atom
multitool_set_buffer(null)
to_chat(user, span_notice("You link [src] with [back]."))
else if(istype(buffer_atom, /obj/machinery/bsa/front))
front = buffer_atom
multitool_set_buffer(null)
to_chat(user, span_notice("You link [src] with [front]."))
else
to_chat(user, span_warning("[I]'s data buffer is empty!"))
return TRUE
/obj/machinery/bsa/middle/proc/check_completion()
if(!front || !back)
return "No linked parts detected!"
if(!front.anchored || !back.anchored || !anchored)
return "Linked parts unwrenched!"
if(front.y != y || back.y != y || !(front.x > x && back.x < x || front.x < x && back.x > x) || front.z != z || back.z != z)
return "Parts misaligned!"
if(!has_space())
return "Not enough free space!"
if(is_reebe(z))
return text2ratvar("Not on my watch")
/obj/machinery/bsa/middle/proc/has_space()
var/cannon_dir = get_cannon_direction()
var/x_min
var/x_max
switch(cannon_dir)
if(EAST)
x_min = x - 4 //replace with defines later
x_max = x + 6
if(WEST)
x_min = x + 4
x_max = x - 6
for(var/turf/T in block(locate(x_min,y-1,z),locate(x_max,y+1,z)))
if(T.density || isspaceturf(T))
return FALSE
return TRUE
/obj/machinery/bsa/middle/proc/get_cannon_direction()
if(front.x > x && back.x < x)
return EAST
else if(front.x < x && back.x > x)
return WEST
/obj/machinery/bsa/full
name = "Bluespace Artillery"
desc = "Long range bluespace artillery."
icon = 'icons/obj/lavaland/cannon.dmi'
icon_state = "orbital_cannon1"
var/static/mutable_appearance/top_layer
var/ex_power = 3
var/power_used_per_shot = 2000000 //enough to kil standard apc - todo : make this use wires instead and scale explosion power with it
var/ready
pixel_y = -32
pixel_x = -192
bound_width = 352
bound_x = -192
appearance_flags = NONE //Removes default TILE_BOUND
/obj/machinery/bsa/full/wrench_act(mob/living/user, obj/item/I)
return FALSE
/obj/machinery/bsa/full/proc/get_front_turf()
switch(dir)
if(WEST)
return locate(x - 7,y,z)
if(EAST)
return locate(x + 4,y,z)
return get_turf(src)
/obj/machinery/bsa/full/proc/get_back_turf()
switch(dir)
if(WEST)
return locate(x + 4,y,z)
if(EAST)
return locate(x - 6,y,z)
return get_turf(src)
/obj/machinery/bsa/full/proc/get_target_turf()
switch(dir)
if(WEST)
return locate(1,y,z)
if(EAST)
return locate(world.maxx,y,z)
return get_turf(src)
/obj/machinery/bsa/full/Initialize(mapload, cannon_direction = WEST)
. = ..()
top_layer = top_layer || mutable_appearance(icon, layer = ABOVE_MOB_LAYER)
switch(cannon_direction)
if(WEST)
setDir(WEST)
pixel_x = -192
top_layer.icon_state = "top_west"
icon_state = "cannon_west"
if(EAST)
setDir(EAST)
top_layer.icon_state = "top_east"
icon_state = "cannon_east"
add_overlay(top_layer)
reload()
/obj/machinery/bsa/full/proc/fire(mob/user, turf/bullseye)
if(!ready)
return
var/turf/point = get_front_turf()
for(var/turf/T in getline(get_step(point,dir),get_target_turf()))
SSexplosions.highturf += T //also fucks everything else on the turf
point.Beam(get_target_turf(),icon_state="bsa_beam",time=50,maxdistance = world.maxx) //ZZZAP
new /obj/effect/temp_visual/bsa_splash(point, dir)
if(user.client)
SSachievements.unlock_achievement(/datum/achievement/cargo/bsa, user.client)
message_admins("[ADMIN_LOOKUPFLW(user)] has launched an artillery strike.")
log_game("[key_name(user)] has fired the bluespace artillery") // yogs
explosion(bullseye,ex_power,ex_power*2,ex_power*4)
reload()
/obj/machinery/bsa/full/proc/reload()
ready = FALSE
use_power(power_used_per_shot)
addtimer(CALLBACK(src,"ready_cannon"),600)
/obj/machinery/bsa/full/proc/ready_cannon()
ready = TRUE
/obj/structure/filler
name = "big machinery part"
density = TRUE
anchored = TRUE
invisibility = INVISIBILITY_ABSTRACT
var/obj/machinery/parent
/obj/structure/filler/ex_act()
return
/obj/machinery/computer/bsa_control
name = "bluespace artillery control"
var/obj/machinery/bsa/full/cannon
var/notice
var/target
use_power = NO_POWER_USE
circuit = /obj/item/circuitboard/computer/bsa_control
icon = 'icons/obj/machines/particle_accelerator.dmi'
icon_state = "control_boxp"
var/area_aim = FALSE //should also show areas for targeting
/obj/machinery/computer/bsa_control/ui_state(mob/user)
return GLOB.physical_state
/obj/machinery/computer/bsa_control/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "BluespaceArtillery", name)
ui.open()
/obj/machinery/computer/bsa_control/ui_data()
var/list/data = list()
data["ready"] = cannon ? cannon.ready : FALSE
data["connected"] = cannon
data["notice"] = notice
data["unlocked"] = GLOB.bsa_unlock
if(target)
data["target"] = get_target_name()
return data
/obj/machinery/computer/bsa_control/ui_act(action, params)
if(..())
return
switch(action)
if("build")
cannon = deploy()
. = TRUE
if("fire")
fire(usr)
. = TRUE
if("recalibrate")
calibrate(usr)
. = TRUE
update_appearance()
/obj/machinery/computer/bsa_control/proc/calibrate(mob/user)
if(!GLOB.bsa_unlock)
return
var/list/gps_locators = list()
for(var/datum/component/gps/G in GLOB.GPS_list) //nulls on the list somehow
if(G.tracking)
gps_locators[G.gpstag] = G
var/list/options = gps_locators
if(area_aim)
options += GLOB.teleportlocs
var/victim = tgui_input_list(user, "Select target", "Artillery Targeting", options)
if(isnull(victim))
return
if(isnull(options[victim]))
return
target = options[victim]
log_game("[key_name(user)] has aimed the bluespace artillery strike at [target].")
/obj/machinery/computer/bsa_control/proc/get_target_name()
if(istype(target, /area))
return get_area_name(target, TRUE)
else if(istype(target, /obj/item/gps))
var/obj/item/gps/G = target
return G.gpstag
else if(istype(target, /datum/component/gps))
var/datum/component/gps/G = target
return G.gpstag
/obj/machinery/computer/bsa_control/proc/get_impact_turf()
if(obj_flags & EMAGGED)
return get_turf(src)
else if(istype(target, /area))
return pick(get_area_turfs(target))
else if(istype(target, /obj/item/gps))
return get_turf(target)
else if(istype(target, /datum/component/gps))
var/datum/component/gps/G = target
return get_turf(G.parent)
/**
* Fires the BSA (duh) if it has power
*
* If its target is the [pirate gps] [/obj/item/gps/pirate], it'll just fire at the edge of the map then call the [GPS' on_shoot proc] [/obj/item/gps/pirate/proc/on_shoot]
*
* Arguments:
* * user - The [/mob] that fired the cannon, assumed to exist and will *probably* runtime without it.
*/
/obj/machinery/computer/bsa_control/proc/fire(mob/user)
if(cannon.stat)
notice = "Cannon unpowered!"
return
notice = null
var/turf/target_turf = get_impact_turf()
cannon.fire(user, target_turf)
/obj/machinery/computer/bsa_control/proc/deploy(force=FALSE)
var/obj/machinery/bsa/full/prebuilt = locate() in range(7) //In case of adminspawn
if(prebuilt)
return prebuilt
var/obj/machinery/bsa/middle/centerpiece = locate() in range(7)
if(!centerpiece)
notice = "No BSA parts detected nearby."
return null
notice = centerpiece.check_completion()
if(notice)
return null
//Totally nanite construction system not an immersion breaking spawning
var/datum/effect_system/fluid_spread/smoke/fourth_wall_guard = new
fourth_wall_guard.set_up(4, location = get_turf(centerpiece))
fourth_wall_guard.start()
var/obj/machinery/bsa/full/cannon = new(get_turf(centerpiece),centerpiece.get_cannon_direction())
qdel(centerpiece.front)
qdel(centerpiece.back)
qdel(centerpiece)
return cannon