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:
Leshana
2020-03-18 13:28:37 -04:00
committed by Aronai Sieyes
parent 15273a356c
commit f2a582569b
22 changed files with 795 additions and 347 deletions

View File

@@ -15,3 +15,5 @@
#define COLOR_ASSEMBLY_BLUE "#38559E"
#define COLOR_ASSEMBLY_PURPLE "#6F6192"
#define COLOR_ASSEMBLY_HOT_PINK "#FF69B4"
#define COLOR_ASTEROID_ROCK "#735555"

16
code/__defines/overmap.dm Normal file
View 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

View File

@@ -26,6 +26,15 @@
max_z = max(z, 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)
if(isarea(A))
return A

View File

@@ -33,6 +33,20 @@
available_turfs = start_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)
var/datum/gas_mixture/environment = T ? T.return_air() : null
var/pressure = environment ? environment.return_pressure() : 0

View File

@@ -1,6 +1,8 @@
SUBSYSTEM_DEF(events)
name = "Events"
wait = 20
wait = 2 SECONDS
var/tmp/list/currentrun = null
var/list/datum/event/active_events = list()
var/list/datum/event/finished_events = list()
@@ -11,23 +13,37 @@ SUBSYSTEM_DEF(events)
var/datum/event_meta/new_event = new
/datum/controller/subsystem/events/Initialize()
allEvents = typesof(/datum/event) - /datum/event
event_containers = list(
EVENT_LEVEL_MUNDANE = new/datum/event_container/mundane,
EVENT_LEVEL_MODERATE = new/datum/event_container/moderate,
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 ..()
/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)
E.process()
if (MC_TICK_CHECK)
return
for(var/i = EVENT_LEVEL_MUNDANE to EVENT_LEVEL_MAJOR)
var/list/datum/event_container/EC = event_containers[i]
EC.process()
/datum/controller/subsystem/events/stat_entry()
..("E:[active_events.len]")
/datum/controller/subsystem/events/Recover()
if(SSevents.active_events)
active_events |= SSevents.active_events
@@ -35,6 +51,8 @@ SUBSYSTEM_DEF(events)
finished_events |= SSevents.finished_events
/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"
log_debug("Event of '[E.type]' with missing meta-data has completed.")
return
@@ -50,7 +68,7 @@ SUBSYSTEM_DEF(events)
log_debug("Event '[EM.name]' has completed at [stationtime2text()].")
/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
/datum/controller/subsystem/events/proc/RoundEnd()

View File

@@ -81,10 +81,10 @@ SUBSYSTEM_DEF(skybox)
overmap.appearance_flags = RESET_COLOR
res.overlays += overmap
// TODO - Allow events to apply custom overlays to skybox! (Awesome!)
//for(var/datum/event/E in SSevent.active_events)
// if(E.has_skybox_image && E.isRunning && (z in E.affecting_z))
// res.overlays += E.get_skybox_image()
// Allow events to apply custom overlays to skybox! (Awesome!)
for(var/datum/event/E in SSevents.active_events)
if(E.has_skybox_image && E.isRunning && (z in E.affecting_z))
res.overlays += E.get_skybox_image()
return res

View File

@@ -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.
*/
/proc/dust_swarm(var/strength = "weak")
/proc/dust_swarm(var/strength = "weak", var/list/affecting_z)
var/numbers = 1
var/dust_type = /obj/effect/space_dust
switch(strength)
if("weak")
numbers = rand(2,4)
for(var/i = 0 to numbers)
new/obj/effect/space_dust/weak()
numbers = rand(2,4)
dust_type = /obj/effect/space_dust/weak
if("norm")
numbers = rand(5,10)
for(var/i = 0 to numbers)
new/obj/effect/space_dust()
numbers = rand(5,10)
dust_type = /obj/effect/space_dust
if("strong")
numbers = rand(10,15)
for(var/i = 0 to numbers)
new/obj/effect/space_dust/strong()
numbers = rand(10,15)
dust_type = /obj/effect/space_dust/strong
if("super")
numbers = rand(15,25)
for(var/i = 0 to numbers)
new/obj/effect/space_dust/super()
return
numbers = rand(15,25)
dust_type = /obj/effect/space_dust/super
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
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/life = 2 //how many things we hit before qdel(src)
weak
strength = 3
life = 1
/obj/effect/space_dust/weak
strength = 3
life = 1
strong
strength = 1
life = 6
/obj/effect/space_dust/strong
strength = 1
life = 6
super
strength = 1
life = 40
/obj/effect/space_dust/super
strength = 1
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()
..()
var/startx = 0
var/starty = 0
var/endy = 0
var/endx = 0
var/startside = pick(cardinal)
/obj/effect/space_dust/Bumped(atom/A)
Bump(A)
return
switch(startside)
if(NORTH)
starty = world.maxy-(TRANSITIONEDGE+1)
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
/obj/effect/space_dust/ex_act(severity)
qdel(src)
return

View File

@@ -18,21 +18,18 @@
//Meteor spawning global procs
///////////////////////////////
/proc/pick_meteor_start(var/startSide = pick(cardinal))
var/startLevel = pick(using_map.station_levels - using_map.sealed_levels)
var/pickedstart = spaceDebrisStartLoc(startSide, startLevel)
return list(startLevel, pickedstart)
/proc/spawn_meteors(var/number = 10, var/list/meteortypes, var/startSide)
/proc/spawn_meteors(var/number = 10, var/list/meteortypes, var/startSide, var/zlevel)
log_debug("Spawning [number] meteors on the [dir2text(startSide)] of [zlevel]")
for(var/i = 0; i < number; i++)
spawn_meteor(meteortypes, startSide)
spawn_meteor(meteortypes, startSide, zlevel)
/proc/spawn_meteor(var/list/meteortypes, var/startSide)
var/start = pick_meteor_start(startSide)
/proc/spawn_meteor(var/list/meteortypes, var/startSide, var/startLevel)
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 = start[2]
var/turf/pickedstart = spaceDebrisStartLoc(startSide, startLevel)
var/turf/pickedgoal = spaceDebrisFinishLoc(startSide, startLevel)
var/Me = pickweight(meteortypes)

View File

@@ -269,20 +269,23 @@ var/const/enterloopsanity = 100
for(var/obj/O in src)
O.hide(O.hides_under_flooring() && !is_plating())
/turf/proc/AdjacentTurfs()
var/L[] = new()
for(var/turf/simulated/t in oview(src,1))
if(!t.density)
if(!LinkBlocked(src, t) && !TurfBlockedNonWindow(t))
L.Add(t)
return L
/turf/proc/AdjacentTurfs(var/check_blockage = TRUE)
. = list()
for(var/t in (trange(1,src) - src))
var/turf/T = t
if(check_blockage)
if(!T.density)
if(!LinkBlocked(src, T) && !TurfBlockedNonWindow(T))
. += t
else
. += t
/turf/proc/CardinalTurfs()
var/L[] = new()
for(var/turf/simulated/T in AdjacentTurfs())
/turf/proc/CardinalTurfs(var/check_blockage = TRUE)
. = list()
for(var/ad in AdjacentTurfs(check_blockage))
var/turf/T = ad
if(T.x == src.x || T.y == src.y)
L.Add(T)
return L
. += T
/turf/proc/Distance(turf/t)
if(get_dist(src,t) == 1)

View File

@@ -1,51 +1,75 @@
/datum/event/carp_migration
announceWhen = 50
endWhen = 900
startWhen = 0 // Start immediately
announceWhen = 45 // Adjusted by setup
endWhen = 75 // Adjusted by setup
var/carp_cap = 10
var/list/spawned_carp = list()
/datum/event/carp_migration/setup()
announceWhen = rand(40, 60)
endWhen = rand(600,1200)
announceWhen = rand(30, 60) // 1 to 2 minutes
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()
var/announcement = ""
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
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")
/datum/event/carp_migration/start()
if(severity == EVENT_LEVEL_MAJOR)
spawn_fish(landmarks_list.len)
else if(severity == EVENT_LEVEL_MODERATE)
spawn_fish(rand(4, 6)) //12 to 30 carp, in small groups
else
spawn_fish(rand(1, 3), 1, 2) //1 to 6 carp, alone or in pairs
/datum/event/carp_migration/tick()
if(activeFor % 4 != 0)
return // Only process every 8 seconds.
if(count_spawned_carps() < carp_cap && living_observers_present(affecting_z))
spawn_fish(rand(1, severity * 2) - 1, severity, severity * 2)
/datum/event/carp_migration/proc/spawn_fish(var/num_groups, var/group_size_min=3, var/group_size_max=5)
var/list/spawn_locations = list()
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)
/datum/event/carp_migration/proc/spawn_fish(var/num_groups, var/group_size_min, var/group_size_max, var/dir)
if(isnull(dir))
dir = (victim && prob(80)) ? victim.fore_dir : pick(GLOB.cardinal)
var/i = 1
while (i <= num_groups)
var/Z = pick(affecting_z)
var/group_size = rand(group_size_min, group_size_max)
for (var/j = 1, j <= group_size, j++)
spawned_carp.Add(new /mob/living/simple_mob/animal/space/carp/event(spawn_locations[i]))
var/turf/map_center = locate(round(world.maxx/2), round(world.maxy/2), Z)
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++
// 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()
. = ..()
// Clean up carp that died in space for some reason.
spawn(0)
for(var/mob/living/simple_mob/SM in spawned_carp)
if(!SM.stat)
if(SM.stat == DEAD)
var/turf/T = get_turf(SM)
if(istype(T, /turf/space))
if(prob(75))
qdel(SM)
sleep(1)
CHECK_TICK
//
// Overmap version of the event!
//
/datum/event/carp_migration/overmap
announceWhen = 1 // Announce much faster!

View File

@@ -3,13 +3,17 @@
endWhen = 30
/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()
dust_swarm(get_severity())
/datum/event/dust/tick()
if(prob(10))
dust_swarm(severity, affecting_z)
/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()
switch(severity)

View File

@@ -1,28 +1,61 @@
/datum/event/electrical_storm
var/lightsoutAmount = 1
var/lightsoutRange = 25
announceWhen = 0 // Warn them shortly before it begins.
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()
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()
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++)
var/list/possibleEpicentres = list()
for(var/obj/effect/landmark/newEpicentre in landmarks_list)
if(newEpicentre.name == "lightsout" && !(newEpicentre in epicentreList))
possibleEpicentres += newEpicentre
if(possibleEpicentres.len)
epicentreList += pick(possibleEpicentres)
else
break
/datum/event/electrical_storm/tick()
..()
// See if shields can stop it first (It would be nice to port baystation's cooler shield gens perhaps)
// TODO - We need a better shield generator system to handle this properly.
if(!valid_apcs.len)
log_debug("No valid APCs found for electrical storm event ship=[victim]!")
return
var/list/picked_apcs = list()
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
for(var/obj/effect/landmark/epicentre in epicentreList)
for(var/obj/machinery/power/apc/apc in range(epicentre,lightsoutRange))
apc.overload_lighting()
// Decent chance to overload lighting circuit.
if(prob(3 * severity))
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()

View File

@@ -1,3 +1,4 @@
// Event Meta instances represent choices for the event manager to choose for random events.
/datum/event_meta
var/name = ""
var/enabled = 1 // Whether or not the event is available for random selection at all
@@ -39,6 +40,10 @@
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!
var/startWhen = 0 //When in the lifetime to call start().
var/announceWhen = 0 //When in the lifetime to call announce().
@@ -51,6 +56,9 @@
var/endedAt = 0 //When this event ended.
var/processing_active = TRUE
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
@@ -65,6 +73,8 @@
//Allows you to start before announcing or vice versa.
//Only called once.
/datum/event/proc/start()
if(has_skybox_image)
SSskybox.rebuild_skyboxes(affecting_z)
return
//Called when the tick is equal to the announceWhen variable.
@@ -87,6 +97,8 @@
//For example: if(activeFor == myOwnVariable + 30) doStuff()
//Only called once.
/datum/event/proc/end()
if(has_skybox_image)
SSskybox.rebuild_skyboxes(affecting_z)
return
//Returns the latest point of event processing.
@@ -132,9 +144,12 @@
end()
endedAt = world.time
SSevents.active_events -= 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)
// event needs to be responsible for this, as stuff like APLUs currently make their own events for curious reasons
SSevents.active_events += src
@@ -146,5 +161,17 @@
startedAt = world.time
if(!affecting_z)
affecting_z = using_map.station_levels
setup()
..()
/datum/event/Destroy()
victim = null
. = ..()
/datum/event/proc/location_name()
if(victim)
return victim.name
return station_name()

View File

@@ -1,20 +1,51 @@
//This file was auto-corrected by findeclaration.exe on 29/05/2012 15:03:04
/datum/event/ionstorm
has_skybox_image = TRUE
var/botEmagChance = 0 //VOREStation Edit
var/cloud_hueshift
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)
// 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")
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))
continue
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)
if(!(target.z in affecting_z))
continue
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)
target.add_ion_law(law)
target.show_laws()
@@ -31,13 +62,15 @@
/datum/event/ionstorm/tick()
if(botEmagChance)
for(var/mob/living/bot/bot in mob_list)
if(!(bot.z in affecting_z))
continue
if(prob(botEmagChance))
bot.emag_act(1)
/datum/event/ionstorm/end()
spawn(rand(5000,8000))
if(prob(50))
ion_storm_announcement()
if(prob(50))
spawn(rand(5000,8000))
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)

View File

@@ -1,30 +1,45 @@
/datum/event/meteor_wave
startWhen = 5
endWhen = 7
startWhen = 30 // About one minute early warning
endWhen = 60 // Adjusted automatically in tick()
has_skybox_image = TRUE
var/next_meteor = 6
var/waves = 1
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()
waves = 2 + rand(1, severity) //EVENT_LEVEL_MAJOR is 3-5 waves
waves = (2 + rand(1, severity)) * severity
start_side = pick(cardinal)
endWhen = worst_case_end()
/datum/event/meteor_wave/announce()
switch(severity)
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
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()
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)
next_meteor += rand(15, 30) / severity
waves--
endWhen = worst_case_end()
/datum/event/meteor_wave/proc/send_wave()
var/pick_side = prob(80) ? start_side : (prob(50) ? turn(start_side, 90) : turn(start_side, -90))
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()
return activeFor + ((30 / severity) * waves) + 10
@@ -32,9 +47,9 @@
/datum/event/meteor_wave/end()
switch(severity)
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
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()
if(EVENT_LEVEL_MAJOR)
@@ -44,3 +59,41 @@
return meteors_threatening
else
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)

View File

@@ -3,6 +3,7 @@ var/global/const
SKILL_BASIC = 1
SKILL_ADEPT = 2
SKILL_EXPERT = 3
SKILL_PROF = 4
/datum/skill/var
ID = "none" // ID of the skill, used in code

View File

@@ -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
*/

View 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

View 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

View 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")

View 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

View File

@@ -62,6 +62,7 @@
#include "code\__defines\mobs_vr.dm"
#include "code\__defines\nifsoft.dm"
#include "code\__defines\objects.dm"
#include "code\__defines\overmap.dm"
#include "code\__defines\planets.dm"
#include "code\__defines\process_scheduler.dm"
#include "code\__defines\qdel.dm"
@@ -2872,11 +2873,14 @@
#include "code\modules\organs\subtypes\vox.dm"
#include "code\modules\organs\subtypes\vox_vr.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_shuttle.dm"
#include "code\modules\overmap\sectors.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\ship.dm"
#include "code\modules\overmap\ships\computers\computer_shims.dm"