mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
Ports overmap events from Baystation12
- Move overmap defines to _defines folder. Rename old file to turfs.dm since that is what it contains. - Definition of overmap event objects and the overmap event handler. - Upgrades to SSevents and SSskybox to tie in the overmap events. - Enhancement to /datum/event itself to support affecting_z and victim ship. - Upgrade to the five event types used on the overmap to support new vars. - Upgrade to dust and meteor spawning code to support targeting z-levels.
This commit is contained in:
@@ -14,4 +14,6 @@
|
|||||||
#define COLOR_ASSEMBLY_LBLUE "#5D99BE"
|
#define COLOR_ASSEMBLY_LBLUE "#5D99BE"
|
||||||
#define COLOR_ASSEMBLY_BLUE "#38559E"
|
#define COLOR_ASSEMBLY_BLUE "#38559E"
|
||||||
#define COLOR_ASSEMBLY_PURPLE "#6F6192"
|
#define COLOR_ASSEMBLY_PURPLE "#6F6192"
|
||||||
#define COLOR_ASSEMBLY_HOT_PINK "#FF69B4"
|
#define COLOR_ASSEMBLY_HOT_PINK "#FF69B4"
|
||||||
|
|
||||||
|
#define COLOR_ASTEROID_ROCK "#735555"
|
||||||
|
|||||||
16
code/__defines/overmap.dm
Normal file
16
code/__defines/overmap.dm
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
//How far from the edge of overmap zlevel could randomly placed objects spawn
|
||||||
|
#define OVERMAP_EDGE 2
|
||||||
|
|
||||||
|
#define SHIP_SIZE_TINY 1
|
||||||
|
#define SHIP_SIZE_SMALL 2
|
||||||
|
#define SHIP_SIZE_LARGE 3
|
||||||
|
|
||||||
|
//multipliers for max_speed to find 'slow' and 'fast' speeds for the ship
|
||||||
|
#define SHIP_SPEED_SLOW 1/(40 SECONDS)
|
||||||
|
#define SHIP_SPEED_FAST 3/(20 SECONDS)// 15 speed
|
||||||
|
|
||||||
|
#define OVERMAP_WEAKNESS_NONE 0
|
||||||
|
#define OVERMAP_WEAKNESS_FIRE 1
|
||||||
|
#define OVERMAP_WEAKNESS_EMP 2
|
||||||
|
#define OVERMAP_WEAKNESS_MINING 4
|
||||||
|
#define OVERMAP_WEAKNESS_EXPLOSIVE 8
|
||||||
@@ -26,6 +26,15 @@
|
|||||||
max_z = max(z, max_z)
|
max_z = max(z, max_z)
|
||||||
return max_z
|
return max_z
|
||||||
|
|
||||||
|
/proc/living_observers_present(var/list/zlevels)
|
||||||
|
if(LAZYLEN(zlevels))
|
||||||
|
for(var/mob/M in player_list) //if a tree ticks on the empty zlevel does it really tick
|
||||||
|
if(M.stat != DEAD) //(no it doesn't)
|
||||||
|
var/turf/T = get_turf(M)
|
||||||
|
if(T && (T.z in zlevels))
|
||||||
|
return TRUE
|
||||||
|
return FALSE
|
||||||
|
|
||||||
/proc/get_area(atom/A)
|
/proc/get_area(atom/A)
|
||||||
if(isarea(A))
|
if(isarea(A))
|
||||||
return A
|
return A
|
||||||
|
|||||||
@@ -33,6 +33,20 @@
|
|||||||
available_turfs = start_turfs
|
available_turfs = start_turfs
|
||||||
return pick(available_turfs)
|
return pick(available_turfs)
|
||||||
|
|
||||||
|
// Picks a turf that is clearance tiles away from the map edge given by dir, on z-level Z
|
||||||
|
/proc/pick_random_edge_turf(var/dir, var/Z, var/clearance = TRANSITIONEDGE + 1)
|
||||||
|
if(!dir)
|
||||||
|
return
|
||||||
|
switch(dir)
|
||||||
|
if(NORTH)
|
||||||
|
return locate(rand(clearance, world.maxx - clearance), world.maxy - clearance, Z)
|
||||||
|
if(SOUTH)
|
||||||
|
return locate(rand(clearance, world.maxx - clearance), clearance, Z)
|
||||||
|
if(EAST)
|
||||||
|
return locate(world.maxx - clearance, rand(clearance, world.maxy - clearance), Z)
|
||||||
|
if(WEST)
|
||||||
|
return locate(clearance, rand(clearance, world.maxy - clearance), Z)
|
||||||
|
|
||||||
/proc/is_below_sound_pressure(var/turf/T)
|
/proc/is_below_sound_pressure(var/turf/T)
|
||||||
var/datum/gas_mixture/environment = T ? T.return_air() : null
|
var/datum/gas_mixture/environment = T ? T.return_air() : null
|
||||||
var/pressure = environment ? environment.return_pressure() : 0
|
var/pressure = environment ? environment.return_pressure() : 0
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
SUBSYSTEM_DEF(events)
|
SUBSYSTEM_DEF(events)
|
||||||
name = "Events"
|
name = "Events"
|
||||||
wait = 20
|
wait = 2 SECONDS
|
||||||
|
|
||||||
|
var/tmp/list/currentrun = null
|
||||||
|
|
||||||
var/list/datum/event/active_events = list()
|
var/list/datum/event/active_events = list()
|
||||||
var/list/datum/event/finished_events = list()
|
var/list/datum/event/finished_events = list()
|
||||||
@@ -11,23 +13,37 @@ SUBSYSTEM_DEF(events)
|
|||||||
var/datum/event_meta/new_event = new
|
var/datum/event_meta/new_event = new
|
||||||
|
|
||||||
/datum/controller/subsystem/events/Initialize()
|
/datum/controller/subsystem/events/Initialize()
|
||||||
|
allEvents = typesof(/datum/event) - /datum/event
|
||||||
event_containers = list(
|
event_containers = list(
|
||||||
EVENT_LEVEL_MUNDANE = new/datum/event_container/mundane,
|
EVENT_LEVEL_MUNDANE = new/datum/event_container/mundane,
|
||||||
EVENT_LEVEL_MODERATE = new/datum/event_container/moderate,
|
EVENT_LEVEL_MODERATE = new/datum/event_container/moderate,
|
||||||
EVENT_LEVEL_MAJOR = new/datum/event_container/major
|
EVENT_LEVEL_MAJOR = new/datum/event_container/major
|
||||||
)
|
)
|
||||||
allEvents = typesof(/datum/event) - /datum/event
|
if(global.using_map.use_overmap)
|
||||||
|
GLOB.overmap_event_handler.create_events(global.using_map.overmap_z, global.using_map.overmap_size, global.using_map.overmap_event_areas)
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/datum/controller/subsystem/events/fire(resumed)
|
/datum/controller/subsystem/events/fire(resumed)
|
||||||
for(var/datum/event/E in active_events)
|
if (!resumed)
|
||||||
|
src.currentrun = active_events.Copy()
|
||||||
|
|
||||||
|
//cache for sanic speed (lists are references anyways)
|
||||||
|
var/list/currentrun = src.currentrun
|
||||||
|
while (currentrun.len)
|
||||||
|
var/datum/event/E = currentrun[currentrun.len]
|
||||||
|
currentrun.len--
|
||||||
if(E.processing_active)
|
if(E.processing_active)
|
||||||
E.process()
|
E.process()
|
||||||
|
if (MC_TICK_CHECK)
|
||||||
|
return
|
||||||
|
|
||||||
for(var/i = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR)
|
for(var/i = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR)
|
||||||
var/list/datum/event_container/EC = event_containers[i]
|
var/list/datum/event_container/EC = event_containers[i]
|
||||||
EC.process()
|
EC.process()
|
||||||
|
|
||||||
|
/datum/controller/subsystem/events/stat_entry()
|
||||||
|
..("E:[active_events.len]")
|
||||||
|
|
||||||
/datum/controller/subsystem/events/Recover()
|
/datum/controller/subsystem/events/Recover()
|
||||||
if(SSevents.active_events)
|
if(SSevents.active_events)
|
||||||
active_events |= SSevents.active_events
|
active_events |= SSevents.active_events
|
||||||
@@ -35,6 +51,8 @@ SUBSYSTEM_DEF(events)
|
|||||||
finished_events |= SSevents.finished_events
|
finished_events |= SSevents.finished_events
|
||||||
|
|
||||||
/datum/controller/subsystem/events/proc/event_complete(var/datum/event/E)
|
/datum/controller/subsystem/events/proc/event_complete(var/datum/event/E)
|
||||||
|
active_events -= E
|
||||||
|
|
||||||
if(!E.event_meta || !E.severity) // datum/event is used here and there for random reasons, maintaining "backwards compatibility"
|
if(!E.event_meta || !E.severity) // datum/event is used here and there for random reasons, maintaining "backwards compatibility"
|
||||||
log_debug("Event of '[E.type]' with missing meta-data has completed.")
|
log_debug("Event of '[E.type]' with missing meta-data has completed.")
|
||||||
return
|
return
|
||||||
@@ -50,7 +68,7 @@ SUBSYSTEM_DEF(events)
|
|||||||
log_debug("Event '[EM.name]' has completed at [stationtime2text()].")
|
log_debug("Event '[EM.name]' has completed at [stationtime2text()].")
|
||||||
|
|
||||||
/datum/controller/subsystem/events/proc/delay_events(var/severity, var/delay)
|
/datum/controller/subsystem/events/proc/delay_events(var/severity, var/delay)
|
||||||
var/list/datum/event_container/EC = event_containers[severity]
|
var/datum/event_container/EC = event_containers[severity]
|
||||||
EC.next_event_time += delay
|
EC.next_event_time += delay
|
||||||
|
|
||||||
/datum/controller/subsystem/events/proc/RoundEnd()
|
/datum/controller/subsystem/events/proc/RoundEnd()
|
||||||
|
|||||||
@@ -81,10 +81,10 @@ SUBSYSTEM_DEF(skybox)
|
|||||||
overmap.appearance_flags = RESET_COLOR
|
overmap.appearance_flags = RESET_COLOR
|
||||||
res.overlays += overmap
|
res.overlays += overmap
|
||||||
|
|
||||||
// TODO - Allow events to apply custom overlays to skybox! (Awesome!)
|
// Allow events to apply custom overlays to skybox! (Awesome!)
|
||||||
//for(var/datum/event/E in SSevent.active_events)
|
for(var/datum/event/E in SSevents.active_events)
|
||||||
// if(E.has_skybox_image && E.isRunning && (z in E.affecting_z))
|
if(E.has_skybox_image && E.isRunning && (z in E.affecting_z))
|
||||||
// res.overlays += E.get_skybox_image()
|
res.overlays += E.get_skybox_image()
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|||||||
@@ -7,27 +7,57 @@ No command report on the common version of this event.
|
|||||||
The "dust" will damage the hull of the station causin minor hull breaches.
|
The "dust" will damage the hull of the station causin minor hull breaches.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/proc/dust_swarm(var/strength = "weak")
|
/proc/dust_swarm(var/strength = "weak", var/list/affecting_z)
|
||||||
var/numbers = 1
|
var/numbers = 1
|
||||||
|
var/dust_type = /obj/effect/space_dust
|
||||||
switch(strength)
|
switch(strength)
|
||||||
if("weak")
|
if("weak")
|
||||||
numbers = rand(2,4)
|
numbers = rand(2,4)
|
||||||
for(var/i = 0 to numbers)
|
dust_type = /obj/effect/space_dust/weak
|
||||||
new/obj/effect/space_dust/weak()
|
|
||||||
if("norm")
|
if("norm")
|
||||||
numbers = rand(5,10)
|
numbers = rand(5,10)
|
||||||
for(var/i = 0 to numbers)
|
dust_type = /obj/effect/space_dust
|
||||||
new/obj/effect/space_dust()
|
|
||||||
if("strong")
|
if("strong")
|
||||||
numbers = rand(10,15)
|
numbers = rand(10,15)
|
||||||
for(var/i = 0 to numbers)
|
dust_type = /obj/effect/space_dust/strong
|
||||||
new/obj/effect/space_dust/strong()
|
|
||||||
if("super")
|
if("super")
|
||||||
numbers = rand(15,25)
|
numbers = rand(15,25)
|
||||||
for(var/i = 0 to numbers)
|
dust_type = /obj/effect/space_dust/super
|
||||||
new/obj/effect/space_dust/super()
|
|
||||||
return
|
|
||||||
|
|
||||||
|
var/startside = pick(cardinal)
|
||||||
|
for(var/i = 0 to numbers)
|
||||||
|
var/startx = 0
|
||||||
|
var/starty = 0
|
||||||
|
var/endy = 0
|
||||||
|
var/endx = 0
|
||||||
|
switch(startside)
|
||||||
|
if(NORTH)
|
||||||
|
starty = world.maxy-TRANSITIONEDGE-1
|
||||||
|
startx = rand(TRANSITIONEDGE+1, world.maxx-TRANSITIONEDGE-1)
|
||||||
|
endy = TRANSITIONEDGE
|
||||||
|
endx = rand(TRANSITIONEDGE+1, world.maxx-TRANSITIONEDGE-1)
|
||||||
|
if(EAST)
|
||||||
|
starty = rand(TRANSITIONEDGE+1, world.maxy-TRANSITIONEDGE-1)
|
||||||
|
startx = world.maxx-TRANSITIONEDGE-1
|
||||||
|
endy = rand(TRANSITIONEDGE, world.maxy-TRANSITIONEDGE)
|
||||||
|
endx = TRANSITIONEDGE
|
||||||
|
if(SOUTH)
|
||||||
|
starty = TRANSITIONEDGE+1
|
||||||
|
startx = rand(TRANSITIONEDGE+1, world.maxx-TRANSITIONEDGE-1)
|
||||||
|
endy = world.maxy-TRANSITIONEDGE
|
||||||
|
endx = rand(TRANSITIONEDGE, world.maxx-TRANSITIONEDGE)
|
||||||
|
if(WEST)
|
||||||
|
starty = rand(TRANSITIONEDGE+1, world.maxy-TRANSITIONEDGE-1)
|
||||||
|
startx = TRANSITIONEDGE+1
|
||||||
|
endy = rand(TRANSITIONEDGE, world.maxy-TRANSITIONEDGE)
|
||||||
|
endx = world.maxx-TRANSITIONEDGE
|
||||||
|
|
||||||
|
var/randomz = pick(affecting_z)
|
||||||
|
var/turf/startloc = locate(startx, starty, randomz)
|
||||||
|
var/turf/endloc = locate(endx, endy, randomz)
|
||||||
|
var/obj/effect/space_dust/D = new dust_type(startloc)
|
||||||
|
D.set_dir(GLOB.reverse_dir[startside])
|
||||||
|
walk_towards(D, endloc, 1)
|
||||||
|
|
||||||
/obj/effect/space_dust
|
/obj/effect/space_dust
|
||||||
name = "Space Dust"
|
name = "Space Dust"
|
||||||
@@ -39,96 +69,51 @@ The "dust" will damage the hull of the station causin minor hull breaches.
|
|||||||
var/strength = 2 //ex_act severity number
|
var/strength = 2 //ex_act severity number
|
||||||
var/life = 2 //how many things we hit before qdel(src)
|
var/life = 2 //how many things we hit before qdel(src)
|
||||||
|
|
||||||
weak
|
/obj/effect/space_dust/weak
|
||||||
strength = 3
|
strength = 3
|
||||||
life = 1
|
life = 1
|
||||||
|
|
||||||
strong
|
/obj/effect/space_dust/strong
|
||||||
strength = 1
|
strength = 1
|
||||||
life = 6
|
life = 6
|
||||||
|
|
||||||
super
|
/obj/effect/space_dust/super
|
||||||
strength = 1
|
strength = 1
|
||||||
life = 40
|
life = 40
|
||||||
|
|
||||||
|
/obj/effect/space_dust/Destroy()
|
||||||
|
walk(src, 0) // Because we might have called walk_towards, we must stop the walk loop or BYOND keeps an internal reference to us forever.
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/obj/effect/space_dust/touch_map_edge()
|
||||||
|
qdel(src)
|
||||||
|
|
||||||
|
/obj/effect/space_dust/Bump(atom/A)
|
||||||
|
spawn(0)
|
||||||
|
if(prob(50))
|
||||||
|
for(var/mob/M in range(10, src))
|
||||||
|
if(!M.stat && !istype(M, /mob/living/silicon/ai))
|
||||||
|
shake_camera(M, 3, 1)
|
||||||
|
if (A)
|
||||||
|
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1)
|
||||||
|
|
||||||
|
if(ismob(A))
|
||||||
|
A.ex_act(strength)//This should work for now I guess
|
||||||
|
else if(!istype(A,/obj/machinery/power/emitter) && !istype(A,/obj/machinery/field_generator)) //Protect the singularity from getting released every round!
|
||||||
|
A.ex_act(strength) //Changing emitter/field gen ex_act would make it immune to bombs and C4
|
||||||
|
|
||||||
|
life--
|
||||||
|
if(life <= 0)
|
||||||
|
walk(src,0)
|
||||||
|
qdel(src)
|
||||||
|
return 0
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
New()
|
/obj/effect/space_dust/Bumped(atom/A)
|
||||||
..()
|
Bump(A)
|
||||||
var/startx = 0
|
return
|
||||||
var/starty = 0
|
|
||||||
var/endy = 0
|
|
||||||
var/endx = 0
|
|
||||||
var/startside = pick(cardinal)
|
|
||||||
|
|
||||||
switch(startside)
|
/obj/effect/space_dust/ex_act(severity)
|
||||||
if(NORTH)
|
qdel(src)
|
||||||
starty = world.maxy-(TRANSITIONEDGE+1)
|
return
|
||||||
startx = rand((TRANSITIONEDGE+1), world.maxx-(TRANSITIONEDGE+1))
|
|
||||||
endy = TRANSITIONEDGE
|
|
||||||
endx = rand(TRANSITIONEDGE, world.maxx-TRANSITIONEDGE)
|
|
||||||
if(EAST)
|
|
||||||
starty = rand((TRANSITIONEDGE+1),world.maxy-(TRANSITIONEDGE+1))
|
|
||||||
startx = world.maxx-(TRANSITIONEDGE+1)
|
|
||||||
endy = rand(TRANSITIONEDGE, world.maxy-TRANSITIONEDGE)
|
|
||||||
endx = TRANSITIONEDGE
|
|
||||||
if(SOUTH)
|
|
||||||
starty = (TRANSITIONEDGE+1)
|
|
||||||
startx = rand((TRANSITIONEDGE+1), world.maxx-(TRANSITIONEDGE+1))
|
|
||||||
endy = world.maxy-TRANSITIONEDGE
|
|
||||||
endx = rand(TRANSITIONEDGE, world.maxx-TRANSITIONEDGE)
|
|
||||||
if(WEST)
|
|
||||||
starty = rand((TRANSITIONEDGE+1), world.maxy-(TRANSITIONEDGE+1))
|
|
||||||
startx = (TRANSITIONEDGE+1)
|
|
||||||
endy = rand(TRANSITIONEDGE,world.maxy-TRANSITIONEDGE)
|
|
||||||
endx = world.maxx-TRANSITIONEDGE
|
|
||||||
//VOREStation Edit - No space dust outside of space
|
|
||||||
var/list/z_levels = using_map.station_levels.Copy()
|
|
||||||
for(var/datum/planet/P in SSplanets.planets)
|
|
||||||
z_levels.Remove(P.expected_z_levels)
|
|
||||||
var/z_level = pick(z_levels)
|
|
||||||
//VOREStation Edit End
|
|
||||||
var/goal = locate(endx, endy, z_level)
|
|
||||||
src.x = startx
|
|
||||||
src.y = starty
|
|
||||||
src.z = z_level
|
|
||||||
spawn(0)
|
|
||||||
walk_towards(src, goal, 1)
|
|
||||||
return
|
|
||||||
|
|
||||||
Destroy()
|
|
||||||
walk(src, 0) // Because we might have called walk_towards, we must stop the walk loop or BYOND keeps an internal reference to us forever.
|
|
||||||
return ..()
|
|
||||||
|
|
||||||
touch_map_edge()
|
|
||||||
qdel(src)
|
|
||||||
|
|
||||||
Bump(atom/A)
|
|
||||||
spawn(0)
|
|
||||||
if(prob(50))
|
|
||||||
for(var/mob/M in range(10, src))
|
|
||||||
if(!M.stat && !istype(M, /mob/living/silicon/ai))
|
|
||||||
shake_camera(M, 3, 1)
|
|
||||||
if (A)
|
|
||||||
playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1)
|
|
||||||
|
|
||||||
if(ismob(A))
|
|
||||||
A.ex_act(strength)//This should work for now I guess
|
|
||||||
else if(!istype(A,/obj/machinery/power/emitter) && !istype(A,/obj/machinery/field_generator)) //Protect the singularity from getting released every round!
|
|
||||||
A.ex_act(strength) //Changing emitter/field gen ex_act would make it immune to bombs and C4
|
|
||||||
|
|
||||||
life--
|
|
||||||
if(life <= 0)
|
|
||||||
walk(src,0)
|
|
||||||
qdel(src)
|
|
||||||
return 0
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
Bumped(atom/A)
|
|
||||||
Bump(A)
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
ex_act(severity)
|
|
||||||
qdel(src)
|
|
||||||
return
|
|
||||||
|
|||||||
@@ -18,21 +18,18 @@
|
|||||||
//Meteor spawning global procs
|
//Meteor spawning global procs
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
/proc/pick_meteor_start(var/startSide = pick(cardinal))
|
/proc/spawn_meteors(var/number = 10, var/list/meteortypes, var/startSide, var/zlevel)
|
||||||
var/startLevel = pick(using_map.station_levels - using_map.sealed_levels)
|
log_debug("Spawning [number] meteors on the [dir2text(startSide)] of [zlevel]")
|
||||||
var/pickedstart = spaceDebrisStartLoc(startSide, startLevel)
|
|
||||||
|
|
||||||
return list(startLevel, pickedstart)
|
|
||||||
|
|
||||||
/proc/spawn_meteors(var/number = 10, var/list/meteortypes, var/startSide)
|
|
||||||
for(var/i = 0; i < number; i++)
|
for(var/i = 0; i < number; i++)
|
||||||
spawn_meteor(meteortypes, startSide)
|
spawn_meteor(meteortypes, startSide, zlevel)
|
||||||
|
|
||||||
/proc/spawn_meteor(var/list/meteortypes, var/startSide)
|
/proc/spawn_meteor(var/list/meteortypes, var/startSide, var/startLevel)
|
||||||
var/start = pick_meteor_start(startSide)
|
if(isnull(startSide))
|
||||||
|
startSide = pick(cardinal)
|
||||||
|
if(isnull(startLevel))
|
||||||
|
startLevel = pick(using_map.station_levels - using_map.sealed_levels)
|
||||||
|
|
||||||
var/startLevel = start[1]
|
var/turf/pickedstart = spaceDebrisStartLoc(startSide, startLevel)
|
||||||
var/turf/pickedstart = start[2]
|
|
||||||
var/turf/pickedgoal = spaceDebrisFinishLoc(startSide, startLevel)
|
var/turf/pickedgoal = spaceDebrisFinishLoc(startSide, startLevel)
|
||||||
|
|
||||||
var/Me = pickweight(meteortypes)
|
var/Me = pickweight(meteortypes)
|
||||||
|
|||||||
@@ -269,20 +269,23 @@ var/const/enterloopsanity = 100
|
|||||||
for(var/obj/O in src)
|
for(var/obj/O in src)
|
||||||
O.hide(O.hides_under_flooring() && !is_plating())
|
O.hide(O.hides_under_flooring() && !is_plating())
|
||||||
|
|
||||||
/turf/proc/AdjacentTurfs()
|
/turf/proc/AdjacentTurfs(var/check_blockage = TRUE)
|
||||||
var/L[] = new()
|
. = list()
|
||||||
for(var/turf/simulated/t in oview(src,1))
|
for(var/t in (trange(1,src) - src))
|
||||||
if(!t.density)
|
var/turf/T = t
|
||||||
if(!LinkBlocked(src, t) && !TurfBlockedNonWindow(t))
|
if(check_blockage)
|
||||||
L.Add(t)
|
if(!T.density)
|
||||||
return L
|
if(!LinkBlocked(src, T) && !TurfBlockedNonWindow(T))
|
||||||
|
. += t
|
||||||
|
else
|
||||||
|
. += t
|
||||||
|
|
||||||
/turf/proc/CardinalTurfs()
|
/turf/proc/CardinalTurfs(var/check_blockage = TRUE)
|
||||||
var/L[] = new()
|
. = list()
|
||||||
for(var/turf/simulated/T in AdjacentTurfs())
|
for(var/ad in AdjacentTurfs(check_blockage))
|
||||||
|
var/turf/T = ad
|
||||||
if(T.x == src.x || T.y == src.y)
|
if(T.x == src.x || T.y == src.y)
|
||||||
L.Add(T)
|
. += T
|
||||||
return L
|
|
||||||
|
|
||||||
/turf/proc/Distance(turf/t)
|
/turf/proc/Distance(turf/t)
|
||||||
if(get_dist(src,t) == 1)
|
if(get_dist(src,t) == 1)
|
||||||
|
|||||||
@@ -1,51 +1,75 @@
|
|||||||
/datum/event/carp_migration
|
/datum/event/carp_migration
|
||||||
announceWhen = 50
|
startWhen = 0 // Start immediately
|
||||||
endWhen = 900
|
announceWhen = 45 // Adjusted by setup
|
||||||
|
endWhen = 75 // Adjusted by setup
|
||||||
|
var/carp_cap = 10
|
||||||
var/list/spawned_carp = list()
|
var/list/spawned_carp = list()
|
||||||
|
|
||||||
/datum/event/carp_migration/setup()
|
/datum/event/carp_migration/setup()
|
||||||
announceWhen = rand(40, 60)
|
announceWhen = rand(30, 60) // 1 to 2 minutes
|
||||||
endWhen = rand(600,1200)
|
endWhen += severity * 25
|
||||||
|
carp_cap = 2 + 3 ** severity // No more than this many at once regardless of waves. (5, 11, 29)
|
||||||
|
|
||||||
/datum/event/carp_migration/announce()
|
/datum/event/carp_migration/announce()
|
||||||
var/announcement = ""
|
var/announcement = ""
|
||||||
if(severity == EVENT_LEVEL_MAJOR)
|
if(severity == EVENT_LEVEL_MAJOR)
|
||||||
announcement = "Massive migration of unknown biological entities has been detected near [station_name()], please stand-by."
|
announcement = "Massive migration of unknown biological entities has been detected near [location_name()], please stand-by."
|
||||||
else
|
else
|
||||||
announcement = "Unknown biological [spawned_carp.len == 1 ? "entity has" : "entities have"] been detected near [station_name()], please stand-by."
|
announcement = "Unknown biological [spawned_carp.len == 1 ? "entity has" : "entities have"] been detected near [location_name()], please stand-by."
|
||||||
command_announcement.Announce(announcement, "Lifesign Alert")
|
command_announcement.Announce(announcement, "Lifesign Alert")
|
||||||
|
|
||||||
/datum/event/carp_migration/start()
|
/datum/event/carp_migration/tick()
|
||||||
if(severity == EVENT_LEVEL_MAJOR)
|
if(activeFor % 4 != 0)
|
||||||
spawn_fish(landmarks_list.len)
|
return // Only process every 8 seconds.
|
||||||
else if(severity == EVENT_LEVEL_MODERATE)
|
if(count_spawned_carps() < carp_cap && living_observers_present(affecting_z))
|
||||||
spawn_fish(rand(4, 6)) //12 to 30 carp, in small groups
|
spawn_fish(rand(1, severity * 2) - 1, severity, severity * 2)
|
||||||
else
|
|
||||||
spawn_fish(rand(1, 3), 1, 2) //1 to 6 carp, alone or in pairs
|
|
||||||
|
|
||||||
/datum/event/carp_migration/proc/spawn_fish(var/num_groups, var/group_size_min=3, var/group_size_max=5)
|
/datum/event/carp_migration/proc/spawn_fish(var/num_groups, var/group_size_min, var/group_size_max, var/dir)
|
||||||
var/list/spawn_locations = list()
|
if(isnull(dir))
|
||||||
|
dir = (victim && prob(80)) ? victim.fore_dir : pick(GLOB.cardinal)
|
||||||
for(var/obj/effect/landmark/C in landmarks_list)
|
|
||||||
if(C.name == "carpspawn")
|
|
||||||
spawn_locations.Add(C.loc)
|
|
||||||
spawn_locations = shuffle(spawn_locations)
|
|
||||||
num_groups = min(num_groups, spawn_locations.len)
|
|
||||||
|
|
||||||
var/i = 1
|
var/i = 1
|
||||||
while (i <= num_groups)
|
while (i <= num_groups)
|
||||||
|
var/Z = pick(affecting_z)
|
||||||
var/group_size = rand(group_size_min, group_size_max)
|
var/group_size = rand(group_size_min, group_size_max)
|
||||||
for (var/j = 1, j <= group_size, j++)
|
var/turf/map_center = locate(round(world.maxx/2), round(world.maxy/2), Z)
|
||||||
spawned_carp.Add(new /mob/living/simple_mob/animal/space/carp/event(spawn_locations[i]))
|
var/turf/group_center = pick_random_edge_turf(dir, Z, TRANSITIONEDGE + 2)
|
||||||
|
var/list/turfs = getcircle(group_center, 2)
|
||||||
|
for (var/j = 0, j < group_size, j++)
|
||||||
|
var/mob/living/simple_mob/animal/M = new /mob/living/simple_mob/animal/space/carp/event(turfs[(i % turfs.len) + 1])
|
||||||
|
GLOB.destroyed_event.register(M, src, .proc/on_carp_destruction)
|
||||||
|
spawned_carp.Add(M)
|
||||||
|
M.ai_holder?.give_destination(map_center) // Ask carp to swim towards the middle of the map
|
||||||
|
// TODO - Our throwing systems don't support callbacks. If it ever does, we can throw first to simulate ship speed.
|
||||||
i++
|
i++
|
||||||
|
|
||||||
|
// Counts living carp spawned by this event.
|
||||||
|
/datum/event/carp_migration/proc/count_spawned_carps()
|
||||||
|
. = 0
|
||||||
|
for(var/I in spawned_carp)
|
||||||
|
var/mob/living/simple_mob/animal/M = I
|
||||||
|
if(!QDELETED(M) && M.stat != DEAD)
|
||||||
|
. += 1
|
||||||
|
|
||||||
|
// If carp is bomphed, remove it from the list.
|
||||||
|
/datum/event/carp_migration/proc/on_carp_destruction(var/mob/M)
|
||||||
|
spawned_carp -= M
|
||||||
|
GLOB.destroyed_event.unregister(M, src, .proc/on_carp_destruction)
|
||||||
|
|
||||||
/datum/event/carp_migration/end()
|
/datum/event/carp_migration/end()
|
||||||
|
. = ..()
|
||||||
|
// Clean up carp that died in space for some reason.
|
||||||
spawn(0)
|
spawn(0)
|
||||||
for(var/mob/living/simple_mob/SM in spawned_carp)
|
for(var/mob/living/simple_mob/SM in spawned_carp)
|
||||||
if(!SM.stat)
|
if(SM.stat == DEAD)
|
||||||
var/turf/T = get_turf(SM)
|
var/turf/T = get_turf(SM)
|
||||||
if(istype(T, /turf/space))
|
if(istype(T, /turf/space))
|
||||||
if(prob(75))
|
if(prob(75))
|
||||||
qdel(SM)
|
qdel(SM)
|
||||||
sleep(1)
|
CHECK_TICK
|
||||||
|
|
||||||
|
//
|
||||||
|
// Overmap version of the event!
|
||||||
|
//
|
||||||
|
/datum/event/carp_migration/overmap
|
||||||
|
announceWhen = 1 // Announce much faster!
|
||||||
|
|||||||
@@ -3,13 +3,17 @@
|
|||||||
endWhen = 30
|
endWhen = 30
|
||||||
|
|
||||||
/datum/event/dust/announce()
|
/datum/event/dust/announce()
|
||||||
command_announcement.Announce("Debris resulting from activity on another nearby asteroid is approaching \the [station_name()]", "Dust Alert")
|
if(victim)
|
||||||
|
command_announcement.Announce("The [location_name()] is now passing through a belt of space dust.", "[location_name()] Sensor Array")
|
||||||
|
else
|
||||||
|
command_announcement.Announce("Debris resulting from activity on another nearby asteroid is approaching \the [location_name()]", "Dust Alert")
|
||||||
|
|
||||||
/datum/event/dust/start()
|
/datum/event/dust/tick()
|
||||||
dust_swarm(get_severity())
|
if(prob(10))
|
||||||
|
dust_swarm(severity, affecting_z)
|
||||||
|
|
||||||
/datum/event/dust/end()
|
/datum/event/dust/end()
|
||||||
command_announcement.Announce("\The [station_name()] is no longer in danger of impact from space debris.", "Dust Notice")
|
command_announcement.Announce("\The [location_name()] is no longer in danger of impact from space debris.", "Dust Notice")
|
||||||
|
|
||||||
/datum/event/dust/proc/get_severity()
|
/datum/event/dust/proc/get_severity()
|
||||||
switch(severity)
|
switch(severity)
|
||||||
|
|||||||
@@ -1,28 +1,61 @@
|
|||||||
/datum/event/electrical_storm
|
/datum/event/electrical_storm
|
||||||
var/lightsoutAmount = 1
|
announceWhen = 0 // Warn them shortly before it begins.
|
||||||
var/lightsoutRange = 25
|
startWhen = 30 // 1 minute
|
||||||
|
endWhen = 60 // Set in setup()
|
||||||
|
has_skybox_image = TRUE
|
||||||
|
var/tmp/lightning_color
|
||||||
|
var/tmp/list/valid_apcs // List of valid APCs.
|
||||||
|
|
||||||
|
/datum/event/electrical_storm/get_skybox_image()
|
||||||
|
if(!lightning_color)
|
||||||
|
lightning_color = pick("#ffd98c", "#ebc7ff", "#bdfcff", "#bdd2ff", "#b0ffca", "#ff8178", "#ad74cc")
|
||||||
|
var/image/res = image('icons/skybox/electrobox.dmi', "lightning")
|
||||||
|
res.color = lightning_color
|
||||||
|
res.appearance_flags = RESET_COLOR
|
||||||
|
res.blend_mode = BLEND_ADD
|
||||||
|
return res
|
||||||
|
|
||||||
/datum/event/electrical_storm/announce()
|
/datum/event/electrical_storm/announce()
|
||||||
command_announcement.Announce("An electrical issue has been detected in your area, please repair potential electronic overloads.", "Electrical Alert")
|
..()
|
||||||
|
switch(severity)
|
||||||
|
if(EVENT_LEVEL_MUNDANE)
|
||||||
|
command_announcement.Announce("A minor electrical storm has been detected near the [location_name()]. Please watch out for possible electrical discharges.", "[location_name()] Sensor Array")
|
||||||
|
if(EVENT_LEVEL_MODERATE)
|
||||||
|
command_announcement.Announce("The [location_name()] is about to pass through an electrical storm. Please secure sensitive electrical equipment until the storm passes.", "[location_name()] Sensor Array")
|
||||||
|
if(EVENT_LEVEL_MAJOR)
|
||||||
|
command_announcement.Announce("Alert. A strong electrical storm has been detected in proximity of the [location_name()]. It is recommended to immediately secure sensitive electrical equipment until the storm passes.", "[location_name()] Sensor Array")
|
||||||
|
|
||||||
/datum/event/electrical_storm/start()
|
/datum/event/electrical_storm/start()
|
||||||
var/list/epicentreList = list()
|
..()
|
||||||
|
valid_apcs = list()
|
||||||
|
for(var/obj/machinery/power/apc/A in global.machines)
|
||||||
|
if(A.z in affecting_z)
|
||||||
|
valid_apcs.Add(A)
|
||||||
|
endWhen = (severity * 60) + startWhen
|
||||||
|
|
||||||
for(var/i=1, i <= lightsoutAmount, i++)
|
/datum/event/electrical_storm/tick()
|
||||||
var/list/possibleEpicentres = list()
|
..()
|
||||||
for(var/obj/effect/landmark/newEpicentre in landmarks_list)
|
// See if shields can stop it first (It would be nice to port baystation's cooler shield gens perhaps)
|
||||||
if(newEpicentre.name == "lightsout" && !(newEpicentre in epicentreList))
|
// TODO - We need a better shield generator system to handle this properly.
|
||||||
possibleEpicentres += newEpicentre
|
if(!valid_apcs.len)
|
||||||
if(possibleEpicentres.len)
|
log_debug("No valid APCs found for electrical storm event ship=[victim]!")
|
||||||
epicentreList += pick(possibleEpicentres)
|
return
|
||||||
else
|
var/list/picked_apcs = list()
|
||||||
break
|
for(var/i=0, i< severity * 2, i++) // up to 2/4/6 APCs per tick depending on severity
|
||||||
|
picked_apcs |= pick(valid_apcs)
|
||||||
|
for(var/obj/machinery/power/apc/T in picked_apcs)
|
||||||
|
affect_apc(T)
|
||||||
|
|
||||||
if(!epicentreList.len)
|
/datum/event/electrical_storm/proc/affect_apc(var/obj/machinery/power/apc/T)
|
||||||
|
// Main breaker is turned off. Consider this APC protected.
|
||||||
|
if(!T.operating)
|
||||||
return
|
return
|
||||||
|
|
||||||
for(var/obj/effect/landmark/epicentre in epicentreList)
|
// Decent chance to overload lighting circuit.
|
||||||
for(var/obj/machinery/power/apc/apc in range(epicentre,lightsoutRange))
|
if(prob(3 * severity))
|
||||||
apc.overload_lighting()
|
T.overload_lighting()
|
||||||
|
|
||||||
|
// Relatively small chance to emag the apc as apc_damage event does.
|
||||||
|
if(prob(0.2 * severity))
|
||||||
|
T.emagged = 1
|
||||||
|
T.update_icon()
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// Event Meta instances represent choices for the event manager to choose for random events.
|
||||||
/datum/event_meta
|
/datum/event_meta
|
||||||
var/name = ""
|
var/name = ""
|
||||||
var/enabled = 1 // Whether or not the event is available for random selection at all
|
var/enabled = 1 // Whether or not the event is available for random selection at all
|
||||||
@@ -39,6 +40,10 @@
|
|||||||
|
|
||||||
return total_weight
|
return total_weight
|
||||||
|
|
||||||
|
/datum/event_meta/no_overmap/get_weight() //these events have overmap equivalents, and shouldn't fire randomly if overmap is used
|
||||||
|
return global.using_map.use_overmap ? 0 : ..()
|
||||||
|
|
||||||
|
// Event datums define and execute the actual events themselves.
|
||||||
/datum/event //NOTE: Times are measured in master controller ticks!
|
/datum/event //NOTE: Times are measured in master controller ticks!
|
||||||
var/startWhen = 0 //When in the lifetime to call start().
|
var/startWhen = 0 //When in the lifetime to call start().
|
||||||
var/announceWhen = 0 //When in the lifetime to call announce().
|
var/announceWhen = 0 //When in the lifetime to call announce().
|
||||||
@@ -51,6 +56,9 @@
|
|||||||
var/endedAt = 0 //When this event ended.
|
var/endedAt = 0 //When this event ended.
|
||||||
var/processing_active = TRUE
|
var/processing_active = TRUE
|
||||||
var/datum/event_meta/event_meta = null
|
var/datum/event_meta/event_meta = null
|
||||||
|
var/list/affecting_z = null // List of z-levels to affect, null lets the event choose (usally station_levels)
|
||||||
|
var/has_skybox_image = FALSE // True if SSskybox should query this event for an image to put in the skybox.
|
||||||
|
var/obj/effect/overmap/visitable/ship/victim = null // Ship that triggered this event on itself. Some messages might be different etc.
|
||||||
|
|
||||||
/datum/event/nothing
|
/datum/event/nothing
|
||||||
|
|
||||||
@@ -65,6 +73,8 @@
|
|||||||
//Allows you to start before announcing or vice versa.
|
//Allows you to start before announcing or vice versa.
|
||||||
//Only called once.
|
//Only called once.
|
||||||
/datum/event/proc/start()
|
/datum/event/proc/start()
|
||||||
|
if(has_skybox_image)
|
||||||
|
SSskybox.rebuild_skyboxes(affecting_z)
|
||||||
return
|
return
|
||||||
|
|
||||||
//Called when the tick is equal to the announceWhen variable.
|
//Called when the tick is equal to the announceWhen variable.
|
||||||
@@ -87,6 +97,8 @@
|
|||||||
//For example: if(activeFor == myOwnVariable + 30) doStuff()
|
//For example: if(activeFor == myOwnVariable + 30) doStuff()
|
||||||
//Only called once.
|
//Only called once.
|
||||||
/datum/event/proc/end()
|
/datum/event/proc/end()
|
||||||
|
if(has_skybox_image)
|
||||||
|
SSskybox.rebuild_skyboxes(affecting_z)
|
||||||
return
|
return
|
||||||
|
|
||||||
//Returns the latest point of event processing.
|
//Returns the latest point of event processing.
|
||||||
@@ -132,9 +144,12 @@
|
|||||||
end()
|
end()
|
||||||
|
|
||||||
endedAt = world.time
|
endedAt = world.time
|
||||||
SSevents.active_events -= src
|
|
||||||
SSevents.event_complete(src)
|
SSevents.event_complete(src)
|
||||||
|
|
||||||
|
//Called during building of skybox to get overlays
|
||||||
|
/datum/event/proc/get_skybox_image()
|
||||||
|
return
|
||||||
|
|
||||||
/datum/event/New(var/datum/event_meta/EM)
|
/datum/event/New(var/datum/event_meta/EM)
|
||||||
// event needs to be responsible for this, as stuff like APLUs currently make their own events for curious reasons
|
// event needs to be responsible for this, as stuff like APLUs currently make their own events for curious reasons
|
||||||
SSevents.active_events += src
|
SSevents.active_events += src
|
||||||
@@ -146,5 +161,17 @@
|
|||||||
|
|
||||||
startedAt = world.time
|
startedAt = world.time
|
||||||
|
|
||||||
|
if(!affecting_z)
|
||||||
|
affecting_z = using_map.station_levels
|
||||||
|
|
||||||
setup()
|
setup()
|
||||||
..()
|
..()
|
||||||
|
|
||||||
|
/datum/event/Destroy()
|
||||||
|
victim = null
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
/datum/event/proc/location_name()
|
||||||
|
if(victim)
|
||||||
|
return victim.name
|
||||||
|
return station_name()
|
||||||
|
|||||||
@@ -1,20 +1,51 @@
|
|||||||
//This file was auto-corrected by findeclaration.exe on 29/05/2012 15:03:04
|
//This file was auto-corrected by findeclaration.exe on 29/05/2012 15:03:04
|
||||||
|
|
||||||
/datum/event/ionstorm
|
/datum/event/ionstorm
|
||||||
|
has_skybox_image = TRUE
|
||||||
var/botEmagChance = 0 //VOREStation Edit
|
var/botEmagChance = 0 //VOREStation Edit
|
||||||
|
var/cloud_hueshift
|
||||||
var/list/players = list()
|
var/list/players = list()
|
||||||
|
|
||||||
/datum/event/ionstorm/announce()
|
/datum/event/ionstorm/get_skybox_image()
|
||||||
|
if(!cloud_hueshift)
|
||||||
|
cloud_hueshift = color_rotation(rand(-3, 3) * 15)
|
||||||
|
var/image/res = image('icons/skybox/ionbox.dmi', "ions")
|
||||||
|
res.color = cloud_hueshift
|
||||||
|
res.appearance_flags = RESET_COLOR
|
||||||
|
res.blend_mode = BLEND_ADD
|
||||||
|
return res
|
||||||
|
|
||||||
|
/datum/event/ionstorm/setup()
|
||||||
endWhen = rand(500, 1500)
|
endWhen = rand(500, 1500)
|
||||||
|
|
||||||
|
// Interestingly enough, announce() actually *DOES* this event for some reason.
|
||||||
|
/datum/event/ionstorm/announce()
|
||||||
// command_alert("The station has entered an ion storm. Monitor all electronic equipment for malfunctions", "Anomaly Alert")
|
// command_alert("The station has entered an ion storm. Monitor all electronic equipment for malfunctions", "Anomaly Alert")
|
||||||
for (var/mob/living/carbon/human/player in player_list)
|
for (var/mob/living/carbon/human/player in player_list)
|
||||||
if( !player.mind || player_is_antag(player.mind, only_offstation_roles = 1) || player.client.inactivity > MinutesToTicks(10))
|
if( !player.mind || player_is_antag(player.mind, only_offstation_roles = 1) || player.client.inactivity > MinutesToTicks(10))
|
||||||
continue
|
continue
|
||||||
players += player.real_name
|
players += player.real_name
|
||||||
|
|
||||||
|
// Flomph synthetics
|
||||||
|
for(var/mob/living/carbon/S in living_mob_list)
|
||||||
|
if (!S.isSynthetic())
|
||||||
|
continue
|
||||||
|
if(!(S.z in affecting_z))
|
||||||
|
continue
|
||||||
|
var/area/A = get_area(S)
|
||||||
|
if(!A || A.flags & RAD_SHIELDED) // Rad shielding will protect from ions too
|
||||||
|
continue
|
||||||
|
to_chat(S, "<span class='warning'>Your integrated sensors detect an ionospheric anomaly. Your systems will be impacted as you begin a partial restart.</span>")
|
||||||
|
var/ionbug = rand(3, 9)
|
||||||
|
S.confused += ionbug
|
||||||
|
S.eye_blurry += (ionbug - 1)
|
||||||
|
|
||||||
|
// Ionize silicon mobs
|
||||||
for (var/mob/living/silicon/ai/target in silicon_mob_list)
|
for (var/mob/living/silicon/ai/target in silicon_mob_list)
|
||||||
|
if(!(target.z in affecting_z))
|
||||||
|
continue
|
||||||
var/law = target.generate_ion_law()
|
var/law = target.generate_ion_law()
|
||||||
to_chat(target, "<font color='red'><b>You have detected a change in your laws information:</b></font>")
|
to_chat(target, "<span class='danger'>You have detected a change in your laws information:</span>")
|
||||||
to_chat(target, law)
|
to_chat(target, law)
|
||||||
target.add_ion_law(law)
|
target.add_ion_law(law)
|
||||||
target.show_laws()
|
target.show_laws()
|
||||||
@@ -31,13 +62,15 @@
|
|||||||
/datum/event/ionstorm/tick()
|
/datum/event/ionstorm/tick()
|
||||||
if(botEmagChance)
|
if(botEmagChance)
|
||||||
for(var/mob/living/bot/bot in mob_list)
|
for(var/mob/living/bot/bot in mob_list)
|
||||||
|
if(!(bot.z in affecting_z))
|
||||||
|
continue
|
||||||
if(prob(botEmagChance))
|
if(prob(botEmagChance))
|
||||||
bot.emag_act(1)
|
bot.emag_act(1)
|
||||||
|
|
||||||
/datum/event/ionstorm/end()
|
/datum/event/ionstorm/end()
|
||||||
spawn(rand(5000,8000))
|
if(prob(50))
|
||||||
if(prob(50))
|
spawn(rand(5000,8000))
|
||||||
ion_storm_announcement()
|
command_announcement.Announce("It has come to our attention that \the [location_name()] passed through an ion storm. Please monitor all electronic equipment for malfunctions.", "Anomaly Alert")
|
||||||
|
|
||||||
/*
|
/*
|
||||||
/proc/IonStorm(botEmagChance = 10)
|
/proc/IonStorm(botEmagChance = 10)
|
||||||
|
|||||||
@@ -1,30 +1,45 @@
|
|||||||
/datum/event/meteor_wave
|
/datum/event/meteor_wave
|
||||||
startWhen = 5
|
startWhen = 30 // About one minute early warning
|
||||||
endWhen = 7
|
endWhen = 60 // Adjusted automatically in tick()
|
||||||
|
has_skybox_image = TRUE
|
||||||
var/next_meteor = 6
|
var/next_meteor = 6
|
||||||
var/waves = 1
|
var/waves = 1
|
||||||
var/start_side
|
var/start_side
|
||||||
|
var/next_meteor_lower = 10
|
||||||
|
var/next_meteor_upper = 20
|
||||||
|
|
||||||
|
/datum/event/meteor_wave/get_skybox_image()
|
||||||
|
var/image/res = image('icons/skybox/rockbox.dmi', "rockbox")
|
||||||
|
res.color = COLOR_ASTEROID_ROCK
|
||||||
|
res.appearance_flags = RESET_COLOR
|
||||||
|
return res
|
||||||
|
|
||||||
/datum/event/meteor_wave/setup()
|
/datum/event/meteor_wave/setup()
|
||||||
waves = 2 + rand(1, severity) //EVENT_LEVEL_MAJOR is 3-5 waves
|
waves = (2 + rand(1, severity)) * severity
|
||||||
start_side = pick(cardinal)
|
start_side = pick(cardinal)
|
||||||
endWhen = worst_case_end()
|
endWhen = worst_case_end()
|
||||||
|
|
||||||
/datum/event/meteor_wave/announce()
|
/datum/event/meteor_wave/announce()
|
||||||
switch(severity)
|
switch(severity)
|
||||||
if(EVENT_LEVEL_MAJOR)
|
if(EVENT_LEVEL_MAJOR)
|
||||||
command_announcement.Announce("Meteors have been detected on collision course with \the [station_name()].", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg')
|
command_announcement.Announce("Meteors have been detected on collision course with \the [location_name()].", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg')
|
||||||
else
|
else
|
||||||
command_announcement.Announce("\The [station_name()] is now in a meteor shower.", "Meteor Alert")
|
command_announcement.Announce("\The [location_name()] is now in a meteor shower.", "Meteor Alert")
|
||||||
|
|
||||||
/datum/event/meteor_wave/tick()
|
/datum/event/meteor_wave/tick()
|
||||||
if(waves && activeFor >= next_meteor)
|
if(waves && activeFor >= next_meteor)
|
||||||
var/pick_side = prob(80) ? start_side : (prob(50) ? turn(start_side, 90) : turn(start_side, -90))
|
send_wave()
|
||||||
|
|
||||||
spawn() spawn_meteors(severity * rand(1,2), get_meteors(), pick_side)
|
/datum/event/meteor_wave/proc/send_wave()
|
||||||
next_meteor += rand(15, 30) / severity
|
var/pick_side = prob(80) ? start_side : (prob(50) ? turn(start_side, 90) : turn(start_side, -90))
|
||||||
waves--
|
|
||||||
endWhen = worst_case_end()
|
spawn() spawn_meteors(get_wave_size(), get_meteors(), pick_side, pick(affecting_z))
|
||||||
|
next_meteor += rand(next_meteor_lower, next_meteor_upper) / severity
|
||||||
|
waves--
|
||||||
|
endWhen = worst_case_end()
|
||||||
|
|
||||||
|
/datum/event/meteor_wave/proc/get_wave_size()
|
||||||
|
return severity * rand(2, 3)
|
||||||
|
|
||||||
/datum/event/meteor_wave/proc/worst_case_end()
|
/datum/event/meteor_wave/proc/worst_case_end()
|
||||||
return activeFor + ((30 / severity) * waves) + 10
|
return activeFor + ((30 / severity) * waves) + 10
|
||||||
@@ -32,9 +47,9 @@
|
|||||||
/datum/event/meteor_wave/end()
|
/datum/event/meteor_wave/end()
|
||||||
switch(severity)
|
switch(severity)
|
||||||
if(EVENT_LEVEL_MAJOR)
|
if(EVENT_LEVEL_MAJOR)
|
||||||
command_announcement.Announce("\The [station_name()] has cleared the meteor storm.", "Meteor Alert")
|
command_announcement.Announce("\The [location_name()] has cleared the meteor storm.", "Meteor Alert")
|
||||||
else
|
else
|
||||||
command_announcement.Announce("\The [station_name()] has cleared the meteor shower", "Meteor Alert")
|
command_announcement.Announce("\The [location_name()] has cleared the meteor shower", "Meteor Alert")
|
||||||
|
|
||||||
/datum/event/meteor_wave/proc/get_meteors()
|
/datum/event/meteor_wave/proc/get_meteors()
|
||||||
if(EVENT_LEVEL_MAJOR)
|
if(EVENT_LEVEL_MAJOR)
|
||||||
@@ -44,3 +59,41 @@
|
|||||||
return meteors_threatening
|
return meteors_threatening
|
||||||
else
|
else
|
||||||
return meteors_normal
|
return meteors_normal
|
||||||
|
|
||||||
|
|
||||||
|
/datum/event/meteor_wave/overmap
|
||||||
|
next_meteor_lower = 5
|
||||||
|
next_meteor_upper = 10
|
||||||
|
next_meteor = 0
|
||||||
|
|
||||||
|
/datum/event/meteor_wave/overmap/tick()
|
||||||
|
if(victim && !victim.is_still()) // Meteors mostly fly in your face
|
||||||
|
start_side = prob(90) ? victim.fore_dir : pick(GLOB.cardinal)
|
||||||
|
else //Unless you're standing still
|
||||||
|
start_side = pick(GLOB.cardinal)
|
||||||
|
..()
|
||||||
|
|
||||||
|
/datum/event/meteor_wave/overmap/get_wave_size()
|
||||||
|
. = ..()
|
||||||
|
if(!victim)
|
||||||
|
return
|
||||||
|
var/skill = victim.get_helm_skill()
|
||||||
|
var/speed = victim.get_speed()
|
||||||
|
if(skill >= SKILL_PROF)
|
||||||
|
. = round(. * 0.5)
|
||||||
|
if(victim.is_still()) //Standing still means less shit flies your way
|
||||||
|
. = round(. * 0.1)
|
||||||
|
if(speed < SHIP_SPEED_SLOW) //Slow and steady
|
||||||
|
. = round(. * 0.5)
|
||||||
|
if(speed > SHIP_SPEED_FAST) //Sanic stahp
|
||||||
|
. *= 2
|
||||||
|
|
||||||
|
//Smol ship evasion
|
||||||
|
if(victim.vessel_size < SHIP_SIZE_LARGE && speed < SHIP_SPEED_FAST)
|
||||||
|
var/skill_needed = SKILL_PROF
|
||||||
|
if(speed < SHIP_SPEED_SLOW)
|
||||||
|
skill_needed = SKILL_ADEPT
|
||||||
|
if(victim.vessel_size < SHIP_SIZE_SMALL)
|
||||||
|
skill_needed = skill_needed - 1
|
||||||
|
if(skill >= max(skill_needed, victim.skill_needed))
|
||||||
|
. = round(. * 0.5)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ var/global/const
|
|||||||
SKILL_BASIC = 1
|
SKILL_BASIC = 1
|
||||||
SKILL_ADEPT = 2
|
SKILL_ADEPT = 2
|
||||||
SKILL_EXPERT = 3
|
SKILL_EXPERT = 3
|
||||||
|
SKILL_PROF = 4
|
||||||
|
|
||||||
/datum/skill/var
|
/datum/skill/var
|
||||||
ID = "none" // ID of the skill, used in code
|
ID = "none" // ID of the skill, used in code
|
||||||
|
|||||||
@@ -1,145 +0,0 @@
|
|||||||
//How far from the edge of overmap zlevel could randomly placed objects spawn
|
|
||||||
#define OVERMAP_EDGE 2
|
|
||||||
|
|
||||||
#define SHIP_SIZE_TINY 1
|
|
||||||
#define SHIP_SIZE_SMALL 2
|
|
||||||
#define SHIP_SIZE_LARGE 3
|
|
||||||
|
|
||||||
//multipliers for max_speed to find 'slow' and 'fast' speeds for the ship
|
|
||||||
#define SHIP_SPEED_SLOW 1/(40 SECONDS)
|
|
||||||
#define SHIP_SPEED_FAST 3/(20 SECONDS)// 15 speed
|
|
||||||
|
|
||||||
#define OVERMAP_WEAKNESS_NONE 0
|
|
||||||
#define OVERMAP_WEAKNESS_FIRE 1
|
|
||||||
#define OVERMAP_WEAKNESS_EMP 2
|
|
||||||
#define OVERMAP_WEAKNESS_MINING 4
|
|
||||||
#define OVERMAP_WEAKNESS_EXPLOSIVE 8
|
|
||||||
|
|
||||||
//Dimension of overmap (squares 4 lyfe)
|
|
||||||
var/global/list/map_sectors = list()
|
|
||||||
|
|
||||||
/area/overmap/
|
|
||||||
name = "System Map"
|
|
||||||
icon_state = "start"
|
|
||||||
requires_power = 0
|
|
||||||
base_turf = /turf/unsimulated/map
|
|
||||||
|
|
||||||
/turf/unsimulated/map
|
|
||||||
icon = 'icons/turf/space.dmi'
|
|
||||||
icon_state = "map"
|
|
||||||
initialized = FALSE // TODO - Fix unsimulated turf initialization so this override is not necessary!
|
|
||||||
|
|
||||||
/turf/unsimulated/map/edge
|
|
||||||
opacity = 1
|
|
||||||
density = 1
|
|
||||||
|
|
||||||
/turf/unsimulated/map/Initialize()
|
|
||||||
. = ..()
|
|
||||||
name = "[x]-[y]"
|
|
||||||
var/list/numbers = list()
|
|
||||||
|
|
||||||
if(x == 1 || x == global.using_map.overmap_size)
|
|
||||||
numbers += list("[round(y/10)]","[round(y%10)]")
|
|
||||||
if(y == 1 || y == global.using_map.overmap_size)
|
|
||||||
numbers += "-"
|
|
||||||
if(y == 1 || y == global.using_map.overmap_size)
|
|
||||||
numbers += list("[round(x/10)]","[round(x%10)]")
|
|
||||||
|
|
||||||
for(var/i = 1 to numbers.len)
|
|
||||||
var/image/I = image('icons/effects/numbers.dmi',numbers[i])
|
|
||||||
I.pixel_x = 5*i - 2
|
|
||||||
I.pixel_y = world.icon_size/2 - 3
|
|
||||||
if(y == 1)
|
|
||||||
I.pixel_y = 3
|
|
||||||
I.pixel_x = 5*i + 4
|
|
||||||
if(y == global.using_map.overmap_size)
|
|
||||||
I.pixel_y = world.icon_size - 9
|
|
||||||
I.pixel_x = 5*i + 4
|
|
||||||
if(x == 1)
|
|
||||||
I.pixel_x = 5*i - 2
|
|
||||||
if(x == global.using_map.overmap_size)
|
|
||||||
I.pixel_x = 5*i + 2
|
|
||||||
add_overlay(I)
|
|
||||||
|
|
||||||
//list used to track which zlevels are being 'moved' by the proc below
|
|
||||||
var/list/moving_levels = list()
|
|
||||||
//Proc to 'move' stars in spess
|
|
||||||
//yes it looks ugly, but it should only fire when state actually change.
|
|
||||||
//null direction stops movement
|
|
||||||
proc/toggle_move_stars(zlevel, direction)
|
|
||||||
if(!zlevel)
|
|
||||||
return
|
|
||||||
|
|
||||||
if (moving_levels["[zlevel]"] != direction)
|
|
||||||
moving_levels["[zlevel]"] = direction
|
|
||||||
|
|
||||||
var/list/spaceturfs = block(locate(1, 1, zlevel), locate(world.maxx, world.maxy, zlevel))
|
|
||||||
for(var/turf/space/T in spaceturfs)
|
|
||||||
T.toggle_transit(direction)
|
|
||||||
CHECK_TICK
|
|
||||||
/*
|
|
||||||
//list used to cache empty zlevels to avoid nedless map bloat
|
|
||||||
var/list/cached_space = list()
|
|
||||||
|
|
||||||
proc/overmap_spacetravel(var/turf/space/T, var/atom/movable/A)
|
|
||||||
var/obj/effect/map/M = map_sectors["[T.z]"]
|
|
||||||
if (!M)
|
|
||||||
return
|
|
||||||
var/mapx = M.x
|
|
||||||
var/mapy = M.y
|
|
||||||
var/nx = 1
|
|
||||||
var/ny = 1
|
|
||||||
var/nz = M.map_z
|
|
||||||
|
|
||||||
if(T.x <= TRANSITIONEDGE)
|
|
||||||
nx = world.maxx - TRANSITIONEDGE - 2
|
|
||||||
ny = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
|
|
||||||
mapx = max(1, mapx-1)
|
|
||||||
|
|
||||||
else if (A.x >= (world.maxx - TRANSITIONEDGE - 1))
|
|
||||||
nx = TRANSITIONEDGE + 2
|
|
||||||
ny = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
|
|
||||||
mapx = min(world.maxx, mapx+1)
|
|
||||||
|
|
||||||
else if (T.y <= TRANSITIONEDGE)
|
|
||||||
ny = world.maxy - TRANSITIONEDGE -2
|
|
||||||
nx = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
|
|
||||||
mapy = max(1, mapy-1)
|
|
||||||
|
|
||||||
else if (A.y >= (world.maxy - TRANSITIONEDGE - 1))
|
|
||||||
ny = TRANSITIONEDGE + 2
|
|
||||||
nx = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
|
|
||||||
mapy = min(world.maxy, mapy+1)
|
|
||||||
|
|
||||||
testing("[A] moving from [M] ([M.x], [M.y]) to ([mapx],[mapy]).")
|
|
||||||
|
|
||||||
var/turf/map = locate(mapx,mapy,OVERMAP_ZLEVEL)
|
|
||||||
var/obj/effect/map/TM = locate() in map
|
|
||||||
if(TM)
|
|
||||||
nz = TM.map_z
|
|
||||||
testing("Destination: [TM]")
|
|
||||||
else
|
|
||||||
if(cached_space.len)
|
|
||||||
var/obj/effect/map/sector/temporary/cache = cached_space[cached_space.len]
|
|
||||||
cached_space -= cache
|
|
||||||
nz = cache.map_z
|
|
||||||
cache.x = mapx
|
|
||||||
cache.y = mapy
|
|
||||||
testing("Destination: *cached* [TM]")
|
|
||||||
else
|
|
||||||
world.maxz++
|
|
||||||
nz = world.maxz
|
|
||||||
TM = new /obj/effect/map/sector/temporary(mapx, mapy, nz)
|
|
||||||
testing("Destination: *new* [TM]")
|
|
||||||
|
|
||||||
var/turf/dest = locate(nx,ny,nz)
|
|
||||||
if(dest)
|
|
||||||
A.loc = dest
|
|
||||||
|
|
||||||
if(istype(M, /obj/effect/map/sector/temporary))
|
|
||||||
var/obj/effect/map/sector/temporary/source = M
|
|
||||||
if (source.can_die())
|
|
||||||
testing("Catching [M] for future use")
|
|
||||||
source.loc = null
|
|
||||||
cached_space += source
|
|
||||||
*/
|
|
||||||
163
code/modules/overmap/events/event_handler.dm
Normal file
163
code/modules/overmap/events/event_handler.dm
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
GLOBAL_DATUM_INIT(overmap_event_handler, /decl/overmap_event_handler, new)
|
||||||
|
|
||||||
|
/decl/overmap_event_handler
|
||||||
|
var/list/hazard_by_turf
|
||||||
|
var/list/ship_events
|
||||||
|
|
||||||
|
/decl/overmap_event_handler/New()
|
||||||
|
..()
|
||||||
|
hazard_by_turf = list()
|
||||||
|
ship_events = list()
|
||||||
|
|
||||||
|
// Populates overmap with random events! Should be called once at startup at some point.
|
||||||
|
/decl/overmap_event_handler/proc/create_events(var/z_level, var/overmap_size, var/number_of_events)
|
||||||
|
// Acquire the list of not-yet utilized overmap turfs on this Z-level
|
||||||
|
var/list/overmap_turfs = block(locate(OVERMAP_EDGE, OVERMAP_EDGE, z_level), locate(overmap_size - OVERMAP_EDGE, overmap_size - OVERMAP_EDGE, z_level))
|
||||||
|
var/list/candidate_turfs = list()
|
||||||
|
for(var/Trf in overmap_turfs)
|
||||||
|
var/turf/T = Trf
|
||||||
|
if(!(locate(/obj/effect/overmap/visitable) in T))
|
||||||
|
candidate_turfs += T
|
||||||
|
|
||||||
|
for(var/i = 1 to number_of_events)
|
||||||
|
if(!candidate_turfs.len)
|
||||||
|
break
|
||||||
|
var/overmap_event_type = pick(subtypesof(/datum/overmap_event))
|
||||||
|
var/datum/overmap_event/datum_spawn = new overmap_event_type
|
||||||
|
log_debug("Generating cloud of [datum_spawn.count] [datum_spawn] overmap event hazards")
|
||||||
|
|
||||||
|
var/list/event_turfs = acquire_event_turfs(datum_spawn.count, datum_spawn.radius, candidate_turfs, datum_spawn.continuous)
|
||||||
|
candidate_turfs -= event_turfs
|
||||||
|
|
||||||
|
for(var/event_turf in event_turfs)
|
||||||
|
var/type = pick(datum_spawn.hazards)
|
||||||
|
new type(event_turf)
|
||||||
|
|
||||||
|
qdel(datum_spawn)//idk help how do I do this better?
|
||||||
|
|
||||||
|
/decl/overmap_event_handler/proc/acquire_event_turfs(var/number_of_turfs, var/distance_from_origin, var/list/candidate_turfs, var/continuous = TRUE)
|
||||||
|
number_of_turfs = min(number_of_turfs, candidate_turfs.len)
|
||||||
|
candidate_turfs = candidate_turfs.Copy() // Not this proc's responsibility to adjust the given lists
|
||||||
|
|
||||||
|
var/origin_turf = pick(candidate_turfs)
|
||||||
|
var/list/selected_turfs = list(origin_turf)
|
||||||
|
var/list/selection_turfs = list(origin_turf)
|
||||||
|
candidate_turfs -= origin_turf
|
||||||
|
|
||||||
|
while(selection_turfs.len && selected_turfs.len < number_of_turfs)
|
||||||
|
var/selection_turf = pick(selection_turfs)
|
||||||
|
var/random_neighbour = get_random_neighbour(selection_turf, candidate_turfs, continuous, distance_from_origin)
|
||||||
|
|
||||||
|
if(random_neighbour)
|
||||||
|
candidate_turfs -= random_neighbour
|
||||||
|
selected_turfs += random_neighbour
|
||||||
|
if(get_dist(origin_turf, random_neighbour) < distance_from_origin)
|
||||||
|
selection_turfs += random_neighbour
|
||||||
|
else
|
||||||
|
selection_turfs -= selection_turf
|
||||||
|
|
||||||
|
return selected_turfs
|
||||||
|
|
||||||
|
/decl/overmap_event_handler/proc/get_random_neighbour(var/turf/origin_turf, var/list/candidate_turfs, var/continuous = TRUE, var/range)
|
||||||
|
var/fitting_turfs
|
||||||
|
if(continuous)
|
||||||
|
fitting_turfs = origin_turf.CardinalTurfs(FALSE)
|
||||||
|
else
|
||||||
|
fitting_turfs = trange(range, origin_turf)
|
||||||
|
fitting_turfs = shuffle(fitting_turfs)
|
||||||
|
for(var/turf/T in fitting_turfs)
|
||||||
|
if(T in candidate_turfs)
|
||||||
|
return T
|
||||||
|
|
||||||
|
/decl/overmap_event_handler/proc/start_hazard(var/obj/effect/overmap/visitable/ship/ship, var/obj/effect/overmap/event/hazard)//make these accept both hazards or events
|
||||||
|
if(!(ship in ship_events))
|
||||||
|
ship_events += ship
|
||||||
|
|
||||||
|
for(var/event_type in hazard.events)
|
||||||
|
if(is_event_active(ship, event_type, hazard.difficulty))//event's already active, don't bother
|
||||||
|
continue
|
||||||
|
var/datum/event_meta/EM = new(hazard.difficulty, "Overmap event - [hazard.name]", event_type, add_to_queue = FALSE, is_one_shot = TRUE)
|
||||||
|
var/datum/event/E = new event_type(EM)
|
||||||
|
E.startWhen = 0
|
||||||
|
E.endWhen = INFINITY
|
||||||
|
// TODO - Leshana - Note: event.setup() is called before these are set!
|
||||||
|
E.affecting_z = ship.map_z
|
||||||
|
E.victim = ship
|
||||||
|
LAZYADD(ship_events[ship], E)
|
||||||
|
|
||||||
|
/decl/overmap_event_handler/proc/stop_hazard(var/obj/effect/overmap/visitable/ship/ship, var/obj/effect/overmap/event/hazard)
|
||||||
|
for(var/event_type in hazard.events)
|
||||||
|
var/datum/event/E = is_event_active(ship, event_type, hazard.difficulty)
|
||||||
|
if(E)
|
||||||
|
E.kill()
|
||||||
|
LAZYREMOVE(ship_events[ship], E)
|
||||||
|
|
||||||
|
/decl/overmap_event_handler/proc/is_event_active(var/ship, var/event_type, var/severity)
|
||||||
|
if(!ship_events[ship]) return
|
||||||
|
for(var/datum/event/E in ship_events[ship])
|
||||||
|
if(E.type == event_type && E.severity == severity)
|
||||||
|
return E
|
||||||
|
|
||||||
|
/decl/overmap_event_handler/proc/on_turf_entered(var/turf/new_loc, var/obj/effect/overmap/visitable/ship/ship, var/old_loc)
|
||||||
|
if(!istype(ship))
|
||||||
|
return
|
||||||
|
if(new_loc == old_loc)
|
||||||
|
return
|
||||||
|
|
||||||
|
for(var/obj/effect/overmap/event/E in hazard_by_turf[new_loc])
|
||||||
|
start_hazard(ship, E)
|
||||||
|
|
||||||
|
/decl/overmap_event_handler/proc/on_turf_exited(var/turf/old_loc, var/obj/effect/overmap/visitable/ship/ship, var/new_loc)
|
||||||
|
if(!istype(ship))
|
||||||
|
return
|
||||||
|
if(new_loc == old_loc)
|
||||||
|
return
|
||||||
|
|
||||||
|
for(var/obj/effect/overmap/event/E in hazard_by_turf[old_loc])
|
||||||
|
if(is_event_included(hazard_by_turf[new_loc], E))
|
||||||
|
continue // If new turf has the same event as well... keep it going!
|
||||||
|
stop_hazard(ship, E)
|
||||||
|
|
||||||
|
/decl/overmap_event_handler/proc/update_hazards(var/turf/T)//catch all updater
|
||||||
|
if(!istype(T))
|
||||||
|
return
|
||||||
|
|
||||||
|
var/list/active_hazards = list()
|
||||||
|
for(var/obj/effect/overmap/event/E in T)
|
||||||
|
if(is_event_included(active_hazards, E, TRUE))
|
||||||
|
continue
|
||||||
|
active_hazards += E
|
||||||
|
|
||||||
|
if(!active_hazards.len)
|
||||||
|
hazard_by_turf -= T
|
||||||
|
else
|
||||||
|
hazard_by_turf |= T
|
||||||
|
hazard_by_turf[T] = active_hazards
|
||||||
|
|
||||||
|
for(var/obj/effect/overmap/visitable/ship/ship in T)
|
||||||
|
for(var/datum/event/E in ship_events[ship])
|
||||||
|
if(is_event_in_turf(E, T))
|
||||||
|
continue
|
||||||
|
E.kill()
|
||||||
|
LAZYREMOVE(ship_events[ship], E)
|
||||||
|
|
||||||
|
for(var/obj/effect/overmap/event/E in active_hazards)
|
||||||
|
start_hazard(ship, E)
|
||||||
|
|
||||||
|
/decl/overmap_event_handler/proc/is_event_in_turf(var/datum/event/E, var/turf/T)
|
||||||
|
for(var/obj/effect/overmap/event/hazard in hazard_by_turf[T])
|
||||||
|
if(E in hazard.events && E.severity == hazard.difficulty)
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/decl/overmap_event_handler/proc/is_event_included(var/list/hazards, var/obj/effect/overmap/event/E, var/equal_or_better)//this proc is only used so it can break out of 2 loops cleanly
|
||||||
|
for(var/obj/effect/overmap/event/A in hazards)
|
||||||
|
if(istype(A, E.type) || istype(E, A.type))
|
||||||
|
if(same_entries(A.events, E.events))
|
||||||
|
if(equal_or_better)
|
||||||
|
if(A.difficulty >= E.difficulty)
|
||||||
|
return TRUE
|
||||||
|
else
|
||||||
|
hazards -= A // TODO - Improve this SPAGHETTI CODE! Done only when called from update_hazards. ~Leshana
|
||||||
|
else
|
||||||
|
if(A.difficulty == E.difficulty)
|
||||||
|
return TRUE
|
||||||
49
code/modules/overmap/events/generation.dm
Normal file
49
code/modules/overmap/events/generation.dm
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
** /datum/overmap_event - Descriptors of how/what to spawn during overmap event generation
|
||||||
|
*/
|
||||||
|
|
||||||
|
//These now are basically only used to spawn hazards. Will be useful when we need to spawn group of moving hazards
|
||||||
|
/datum/overmap_event
|
||||||
|
var/name = "map event"
|
||||||
|
var/radius = 2 // Radius of the spawn circle around chosen epicenter
|
||||||
|
var/count = 6 // How many hazards to spawn
|
||||||
|
var/hazards // List (or single) typepath of hazard to spawn
|
||||||
|
var/continuous = TRUE //if it should form continous blob, or can have gaps
|
||||||
|
|
||||||
|
/datum/overmap_event/meteor
|
||||||
|
name = "asteroid field"
|
||||||
|
count = 15
|
||||||
|
radius = 4
|
||||||
|
continuous = FALSE
|
||||||
|
hazards = /obj/effect/overmap/event/meteor
|
||||||
|
|
||||||
|
/datum/overmap_event/electric
|
||||||
|
name = "electrical storm"
|
||||||
|
count = 11
|
||||||
|
radius = 3
|
||||||
|
hazards = /obj/effect/overmap/event/electric
|
||||||
|
|
||||||
|
/datum/overmap_event/dust
|
||||||
|
name = "dust cloud"
|
||||||
|
count = 16
|
||||||
|
radius = 4
|
||||||
|
hazards = /obj/effect/overmap/event/dust
|
||||||
|
|
||||||
|
/datum/overmap_event/ion
|
||||||
|
name = "ion cloud"
|
||||||
|
count = 8
|
||||||
|
radius = 3
|
||||||
|
hazards = /obj/effect/overmap/event/ion
|
||||||
|
|
||||||
|
/datum/overmap_event/carp
|
||||||
|
name = "carp shoal"
|
||||||
|
count = 8
|
||||||
|
radius = 3
|
||||||
|
continuous = FALSE
|
||||||
|
hazards = /obj/effect/overmap/event/carp
|
||||||
|
|
||||||
|
/datum/overmap_event/carp/major
|
||||||
|
name = "carp school"
|
||||||
|
count = 5
|
||||||
|
radius = 4
|
||||||
|
hazards = /obj/effect/overmap/event/carp/major
|
||||||
86
code/modules/overmap/events/overmap_event.dm
Normal file
86
code/modules/overmap/events/overmap_event.dm
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
** /obj/effect/overmap/event - Actual instances of event hazards on the overmap map
|
||||||
|
*/
|
||||||
|
|
||||||
|
// We don't subtype /obj/effect/overmap/visitable because that'll create sections one can travel to
|
||||||
|
// And with them "existing" on the overmap Z-level things quickly get odd.
|
||||||
|
/obj/effect/overmap/event
|
||||||
|
name = "event"
|
||||||
|
icon = 'icons/obj/overmap.dmi'
|
||||||
|
icon_state = "event"
|
||||||
|
opacity = 1
|
||||||
|
var/list/events // List of event datum paths
|
||||||
|
var/list/event_icon_states // Randomly picked from
|
||||||
|
var/difficulty = EVENT_LEVEL_MODERATE
|
||||||
|
var/weaknesses //if the BSA can destroy them and with what
|
||||||
|
var/list/victims //basically cached events on which Z level
|
||||||
|
|
||||||
|
/obj/effect/overmap/event/Initialize()
|
||||||
|
. = ..()
|
||||||
|
icon_state = pick(event_icon_states)
|
||||||
|
GLOB.overmap_event_handler.update_hazards(loc)
|
||||||
|
|
||||||
|
/obj/effect/overmap/event/Move()
|
||||||
|
var/turf/old_loc = loc
|
||||||
|
. = ..()
|
||||||
|
if(.)
|
||||||
|
GLOB.overmap_event_handler.update_hazards(old_loc)
|
||||||
|
GLOB.overmap_event_handler.update_hazards(loc)
|
||||||
|
|
||||||
|
/obj/effect/overmap/event/forceMove(atom/destination)
|
||||||
|
var/old_loc = loc
|
||||||
|
. = ..()
|
||||||
|
if(.)
|
||||||
|
GLOB.overmap_event_handler.update_hazards(old_loc)
|
||||||
|
GLOB.overmap_event_handler.update_hazards(loc)
|
||||||
|
|
||||||
|
/obj/effect/overmap/event/Destroy()//takes a look at this one as well, make sure everything is A-OK
|
||||||
|
var/turf/T = loc
|
||||||
|
. = ..()
|
||||||
|
GLOB.overmap_event_handler.update_hazards(T)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Definitions for specific types!
|
||||||
|
//
|
||||||
|
|
||||||
|
/obj/effect/overmap/event/meteor
|
||||||
|
name = "asteroid field"
|
||||||
|
events = list(/datum/event/meteor_wave/overmap)
|
||||||
|
event_icon_states = list("meteor1", "meteor2", "meteor3", "meteor4")
|
||||||
|
difficulty = EVENT_LEVEL_MAJOR
|
||||||
|
weaknesses = OVERMAP_WEAKNESS_MINING | OVERMAP_WEAKNESS_EXPLOSIVE
|
||||||
|
|
||||||
|
/obj/effect/overmap/event/electric
|
||||||
|
name = "electrical storm"
|
||||||
|
events = list(/datum/event/electrical_storm)
|
||||||
|
opacity = 0
|
||||||
|
event_icon_states = list("electrical1", "electrical2", "electrical3", "electrical4")
|
||||||
|
difficulty = EVENT_LEVEL_MAJOR
|
||||||
|
weaknesses = OVERMAP_WEAKNESS_EMP
|
||||||
|
|
||||||
|
/obj/effect/overmap/event/dust
|
||||||
|
name = "dust cloud"
|
||||||
|
events = list(/datum/event/dust)
|
||||||
|
event_icon_states = list("dust1", "dust2", "dust3", "dust4")
|
||||||
|
weaknesses = OVERMAP_WEAKNESS_MINING | OVERMAP_WEAKNESS_EXPLOSIVE | OVERMAP_WEAKNESS_FIRE
|
||||||
|
|
||||||
|
/obj/effect/overmap/event/ion
|
||||||
|
name = "ion cloud"
|
||||||
|
events = list(/datum/event/ionstorm)
|
||||||
|
opacity = 0
|
||||||
|
event_icon_states = list("ion1", "ion2", "ion3", "ion4")
|
||||||
|
difficulty = EVENT_LEVEL_MAJOR
|
||||||
|
weaknesses = OVERMAP_WEAKNESS_EMP
|
||||||
|
|
||||||
|
/obj/effect/overmap/event/carp
|
||||||
|
name = "carp shoal"
|
||||||
|
events = list(/datum/event/carp_migration/overmap)
|
||||||
|
opacity = 0
|
||||||
|
difficulty = EVENT_LEVEL_MODERATE
|
||||||
|
event_icon_states = list("carp1", "carp2")
|
||||||
|
weaknesses = OVERMAP_WEAKNESS_EXPLOSIVE | OVERMAP_WEAKNESS_FIRE
|
||||||
|
|
||||||
|
/obj/effect/overmap/event/carp/major
|
||||||
|
name = "carp school"
|
||||||
|
difficulty = EVENT_LEVEL_MAJOR
|
||||||
|
event_icon_states = list("carp3", "carp4")
|
||||||
72
code/modules/overmap/turfs.dm
Normal file
72
code/modules/overmap/turfs.dm
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
//Dimension of overmap (squares 4 lyfe)
|
||||||
|
var/global/list/map_sectors = list()
|
||||||
|
|
||||||
|
/area/overmap/
|
||||||
|
name = "System Map"
|
||||||
|
icon_state = "start"
|
||||||
|
requires_power = 0
|
||||||
|
base_turf = /turf/unsimulated/map
|
||||||
|
|
||||||
|
/turf/unsimulated/map
|
||||||
|
icon = 'icons/turf/space.dmi'
|
||||||
|
icon_state = "map"
|
||||||
|
initialized = FALSE // TODO - Fix unsimulated turf initialization so this override is not necessary!
|
||||||
|
|
||||||
|
/turf/unsimulated/map/edge
|
||||||
|
opacity = 1
|
||||||
|
density = 1
|
||||||
|
|
||||||
|
/turf/unsimulated/map/Initialize()
|
||||||
|
. = ..()
|
||||||
|
name = "[x]-[y]"
|
||||||
|
var/list/numbers = list()
|
||||||
|
|
||||||
|
if(x == 1 || x == global.using_map.overmap_size)
|
||||||
|
numbers += list("[round(y/10)]","[round(y%10)]")
|
||||||
|
if(y == 1 || y == global.using_map.overmap_size)
|
||||||
|
numbers += "-"
|
||||||
|
if(y == 1 || y == global.using_map.overmap_size)
|
||||||
|
numbers += list("[round(x/10)]","[round(x%10)]")
|
||||||
|
|
||||||
|
for(var/i = 1 to numbers.len)
|
||||||
|
var/image/I = image('icons/effects/numbers.dmi',numbers[i])
|
||||||
|
I.pixel_x = 5*i - 2
|
||||||
|
I.pixel_y = world.icon_size/2 - 3
|
||||||
|
if(y == 1)
|
||||||
|
I.pixel_y = 3
|
||||||
|
I.pixel_x = 5*i + 4
|
||||||
|
if(y == global.using_map.overmap_size)
|
||||||
|
I.pixel_y = world.icon_size - 9
|
||||||
|
I.pixel_x = 5*i + 4
|
||||||
|
if(x == 1)
|
||||||
|
I.pixel_x = 5*i - 2
|
||||||
|
if(x == global.using_map.overmap_size)
|
||||||
|
I.pixel_x = 5*i + 2
|
||||||
|
add_overlay(I)
|
||||||
|
|
||||||
|
/turf/unsimulated/map/Entered(var/atom/movable/O, var/atom/oldloc)
|
||||||
|
..()
|
||||||
|
if(istype(O, /obj/effect/overmap/visitable/ship))
|
||||||
|
GLOB.overmap_event_handler.on_turf_entered(src, O, oldloc)
|
||||||
|
|
||||||
|
/turf/unsimulated/map/Exited(var/atom/movable/O, var/atom/newloc)
|
||||||
|
..()
|
||||||
|
if(istype(O, /obj/effect/overmap/visitable/ship))
|
||||||
|
GLOB.overmap_event_handler.on_turf_exited(src, O, newloc)
|
||||||
|
|
||||||
|
//list used to track which zlevels are being 'moved' by the proc below
|
||||||
|
var/list/moving_levels = list()
|
||||||
|
//Proc to 'move' stars in spess
|
||||||
|
//yes it looks ugly, but it should only fire when state actually change.
|
||||||
|
//null direction stops movement
|
||||||
|
proc/toggle_move_stars(zlevel, direction)
|
||||||
|
if(!zlevel)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (moving_levels["[zlevel]"] != direction)
|
||||||
|
moving_levels["[zlevel]"] = direction
|
||||||
|
|
||||||
|
var/list/spaceturfs = block(locate(1, 1, zlevel), locate(world.maxx, world.maxy, zlevel))
|
||||||
|
for(var/turf/space/T in spaceturfs)
|
||||||
|
T.toggle_transit(direction)
|
||||||
|
CHECK_TICK
|
||||||
@@ -62,6 +62,7 @@
|
|||||||
#include "code\__defines\mobs_vr.dm"
|
#include "code\__defines\mobs_vr.dm"
|
||||||
#include "code\__defines\nifsoft.dm"
|
#include "code\__defines\nifsoft.dm"
|
||||||
#include "code\__defines\objects.dm"
|
#include "code\__defines\objects.dm"
|
||||||
|
#include "code\__defines\overmap.dm"
|
||||||
#include "code\__defines\planets.dm"
|
#include "code\__defines\planets.dm"
|
||||||
#include "code\__defines\process_scheduler.dm"
|
#include "code\__defines\process_scheduler.dm"
|
||||||
#include "code\__defines\qdel.dm"
|
#include "code\__defines\qdel.dm"
|
||||||
@@ -2872,11 +2873,14 @@
|
|||||||
#include "code\modules\organs\subtypes\vox.dm"
|
#include "code\modules\organs\subtypes\vox.dm"
|
||||||
#include "code\modules\organs\subtypes\vox_vr.dm"
|
#include "code\modules\organs\subtypes\vox_vr.dm"
|
||||||
#include "code\modules\organs\subtypes\xenos.dm"
|
#include "code\modules\organs\subtypes\xenos.dm"
|
||||||
#include "code\modules\overmap\_defines.dm"
|
|
||||||
#include "code\modules\overmap\overmap_object.dm"
|
#include "code\modules\overmap\overmap_object.dm"
|
||||||
#include "code\modules\overmap\overmap_shuttle.dm"
|
#include "code\modules\overmap\overmap_shuttle.dm"
|
||||||
#include "code\modules\overmap\sectors.dm"
|
#include "code\modules\overmap\sectors.dm"
|
||||||
#include "code\modules\overmap\spacetravel.dm"
|
#include "code\modules\overmap\spacetravel.dm"
|
||||||
|
#include "code\modules\overmap\turfs.dm"
|
||||||
|
#include "code\modules\overmap\events\event_handler.dm"
|
||||||
|
#include "code\modules\overmap\events\generation.dm"
|
||||||
|
#include "code\modules\overmap\events\overmap_event.dm"
|
||||||
#include "code\modules\overmap\ships\landable.dm"
|
#include "code\modules\overmap\ships\landable.dm"
|
||||||
#include "code\modules\overmap\ships\ship.dm"
|
#include "code\modules\overmap\ships\ship.dm"
|
||||||
#include "code\modules\overmap\ships\computers\computer_shims.dm"
|
#include "code\modules\overmap\ships\computers\computer_shims.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user