Overhaul of random events

This commit is contained in:
ZomgPonies
2013-09-25 23:22:32 -04:00
parent 900a3526bf
commit 2ffdf37166
45 changed files with 5290 additions and 105 deletions
+183
View File
@@ -0,0 +1,183 @@
//Anomalies, used for events. Note that these DO NOT work by themselves; their procs are called by the event datum.
/obj/effect/anomaly
name = "anomaly"
icon = 'icons/effects/effects.dmi'
desc = "A mysterious anomaly, seen commonly only in the region of space that the station orbits..."
icon_state = "bhole3"
unacidable = 1
density = 0
anchored = 1
luminosity = 3
var/obj/item/device/assembly/signaler/anomaly/aSignal = null
/obj/effect/anomaly/New()
SetLuminosity(initial(luminosity))
aSignal = new(src)
aSignal.code = rand(1,100)
aSignal.frequency = rand(1200, 1599)
if(IsMultiple(aSignal.frequency, 2))//signaller frequencies are always uneven!
aSignal.frequency++
/obj/effect/anomaly/proc/anomalyEffect()
if(prob(50))
step(src,pick(alldirs))
/obj/effect/anomaly/proc/anomalyNeutralize()
new /obj/effect/effect/bad_smoke(loc)
for(var/atom/movable/O in src)
O.loc = src.loc
del(src)
/obj/effect/anomaly/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/device/analyzer))
user << "<span class='notice'>Analyzing... [src]'s unstable field is fluctuating along frequency [aSignal.code]:[format_frequency(aSignal.frequency)].</span>"
///////////////////////
/obj/effect/anomaly/grav
name = "gravitational anomaly"
icon_state = "shield2"
density = 1
var/boing = 0
/obj/effect/anomaly/grav/New()
..()
aSignal.origin_tech = "magnets=5;powerstorage=4"
/obj/effect/anomaly/grav/anomalyEffect()
..()
boing = 1
for(var/obj/O in orange(4, src))
if(!O.anchored)
step_towards(O,src)
for(var/mob/living/M in orange(4, src))
step_towards(M,src)
/obj/effect/anomaly/grav/Bump(mob/A)
gravShock(A)
return
/obj/effect/anomaly/grav/Bumped(mob/A)
gravShock(A)
return
/obj/effect/anomaly/grav/proc/gravShock(var/mob/A)
if(boing && isliving(A) && !A.stat)
A.Weaken(2)
var/atom/target = get_edge_target_turf(A, get_dir(src, get_step_away(A, src)))
A.throw_at(target, 5, 1)
boing = 0
return
/////////////////////
/obj/effect/anomaly/flux
name = "flux wave anomaly"
icon_state = "electricity2"
/obj/effect/anomaly/flux/New()
..()
aSignal.origin_tech = "powerstorage=5;programming=3;plasmatech=2"
/////////////////////
/obj/effect/anomaly/bluespace
name = "bluespace anomaly"
icon = 'icons/obj/projectiles.dmi'
icon_state = "bluespace"
density = 1
/obj/effect/anomaly/bluespace/New()
..()
aSignal.origin_tech = "bluespace=5;magnets=3;powerstorage=2"
/obj/effect/anomaly/bluespace/Bumped(atom/A)
if(isliving(A))
do_teleport(A, locate(A.x, A.y, A.z), 10)
return
/////////////////////
/obj/effect/anomaly/pyro
name = "pyroclastic anomaly"
icon_state = "mustard"
/obj/effect/anomaly/pyro/New()
..()
aSignal.origin_tech = "plasmatech=5;powerstorage=3;biotech=3"
/obj/effect/anomaly/pyro/anomalyEffect()
..()
var/turf/simulated/T = get_turf(src)
if(istype(T))
var/datum/gas_mixture/payload = new
payload.toxins = 30
T.zone.air.merge(payload)
T.hotspot_expose(1000, CELL_VOLUME)
// T.atmos_spawn_air("fire", 3)
/////////////////////
/obj/effect/anomaly/bhole
name = "vortex anomaly"
icon_state = "bhole3"
desc = "That's a nice station you have there. It'd be a shame if something happened to it."
/obj/effect/anomaly/bhole/New()
..()
aSignal.origin_tech = "materials=5;combat=4;engineering=3"
/obj/effect/anomaly/bhole/anomalyEffect()
..()
if(!isturf(loc)) //blackhole cannot be contained inside anything. Weird stuff might happen
del(src)
return
grav(rand(0,3), rand(2,3), 50, 25)
//Throwing stuff around!
for(var/obj/O in orange(1,src))
if(!O.anchored)
var/mob/living/target = locate() in view(5,src)
if(!target)
return
O.throw_at(target, 5, 10)
return
else
O.ex_act(2)
/obj/effect/anomaly/bhole/proc/grav(var/r, var/ex_act_force, var/pull_chance, var/turf_removal_chance)
for(var/t = -r, t < r, t++)
affect_coord(x+t, y-r, ex_act_force, pull_chance, turf_removal_chance)
affect_coord(x-t, y+r, ex_act_force, pull_chance, turf_removal_chance)
affect_coord(x+r, y+t, ex_act_force, pull_chance, turf_removal_chance)
affect_coord(x-r, y-t, ex_act_force, pull_chance, turf_removal_chance)
return
/obj/effect/anomaly/bhole/proc/affect_coord(var/x, var/y, var/ex_act_force, var/pull_chance, var/turf_removal_chance)
//Get turf at coordinate
var/turf/T = locate(x, y, z)
if(isnull(T)) return
//Pulling and/or ex_act-ing movable atoms in that turf
if(prob(pull_chance))
for(var/obj/O in T.contents)
if(O.anchored)
O.ex_act(ex_act_force)
else
step_towards(O,src)
for(var/mob/living/M in T.contents)
step_towards(M,src)
//Damaging the turf
if( T && istype(T,/turf/simulated) && prob(turf_removal_chance) )
T.ex_act(ex_act_force)
return
+4 -2
View File
@@ -96,6 +96,7 @@
layer = 2.7
health = 3
var/amount_grown = -1
var/grow_as = null
var/obj/machinery/atmospherics/unary/vent_pump/entry_vent
var/travelling_in_vent = 0
New()
@@ -186,8 +187,9 @@
if(isturf(loc) && amount_grown > 0)
amount_grown += rand(0,2)
if(amount_grown >= 100)
var/spawn_type = pick(typesof(/mob/living/simple_animal/hostile/giant_spider))
new spawn_type(src.loc)
if(!grow_as)
grow_as = pick(typesof(/mob/living/simple_animal/hostile/giant_spider))
new grow_as(src.loc)
del(src)
/obj/effect/decal/cleanable/spiderling_remains
+5 -1
View File
@@ -579,7 +579,11 @@ var/global/floorIsLava = 0
<BR>
<A href='?src=\ref[src];secretsfun=gravity'>Toggle station artificial gravity</A><BR>
<A href='?src=\ref[src];secretsfun=wave'>Spawn a wave of meteors (aka lagocolyptic shower)</A><BR>
<A href='?src=\ref[src];secretsfun=gravanomalies'>Spawn a gravitational anomaly (aka lagitational anomolag)</A><BR>
<A href='?src=\ref[src];secretsfun=blackhole'>Spawn a vortex anomaly</A><BR>
<A href='?src=\ref[src];secretsfun=gravanomalies'>Spawn a gravitational anomaly</A><BR>
<A href='?src=\ref[src];secretsfun=pyroanomalies'>Spawn a pyroclastic anomaly</A><BR>
<A href='?src=\ref[src];secretsfun=energeticflux'>Spawn a flux wave anomaly</A><BR>
<A href='?src=\ref[src];secretsfun=bluespaceanomaly'>Spawn a bluespace anomaly</A><BR>
<A href='?src=\ref[src];secretsfun=timeanomalies'>Spawn wormholes</A><BR>
<A href='?src=\ref[src];secretsfun=goblob'>Spawn blob</A><BR>
<A href='?src=\ref[src];secretsfun=aliens'>Trigger an Alien infestation</A><BR>
+27 -1
View File
@@ -1587,7 +1587,7 @@
if(!check_rights(R_FUN,0))
removed_paths += dirty_path
continue
else if(ispath(path, /obj/effect/bhole))
else if(ispath(path, /obj/effect/anomaly/bhole))
if(!check_rights(R_FUN,0))
removed_paths += dirty_path
continue
@@ -1762,6 +1762,32 @@
log_admin("[key_name(usr)] spawned a meteor wave", 1)
message_admins("\blue [key_name_admin(usr)] spawned a meteor wave.", 1)
new /datum/event/meteor_wave
if("gravanomalies")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","GA")
message_admins("[key_name_admin(usr)] has spawned a gravitational anomaly")
new /datum/event/anomaly/anomaly_grav()
if("pyroanomalies")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","PYRO")
message_admins("[key_name_admin(usr)] has spawned a pyroclastic anomaly")
new /datum/event/anomaly/anomaly_pyro()
if("blackhole")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","BH")
message_admins("[key_name_admin(usr)] has spawned a vortex anomaly")
new /datum/event/anomaly/anomaly_vortex()
if("bluespaceanomaly")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","BA")
message_admins("[key_name_admin(usr)] has triggered a bluespace anomaly", 1)
new /datum/event/anomaly/anomaly_bluespace()
if("energeticflux")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","FLUX")
message_admins("[key_name_admin(usr)] has triggered an energetic flux")
new /datum/event/anomaly/anomaly_flux()
if("power")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","P")
+2 -1
View File
@@ -47,4 +47,5 @@
H.equip_to_slot_or_del(W, slot_wear_id)
message_admins("\blue [key_name_admin(usr)] used THERE CAN BE ONLY ONE!", 1)
log_admin("[key_name(usr)] used there can be only one.")
log_admin("[key_name(usr)] used there can be only one.")
world << sound('sound/music/highlander.ogg')
+16
View File
@@ -172,3 +172,19 @@
deadman = 1
processing_objects.Add(src)
usr.visible_message("\red [usr] moves their finger over [src]'s signal button...")
// Embedded signaller used in anomalies.
/obj/item/device/assembly/signaler/anomaly
name = "anomaly core"
desc = "The neutralized core of an anomaly. It'd probably be valuable for research."
icon_state = "anomaly core"
item_state = "electronic"
/obj/item/device/assembly/signaler/anomaly/receive_signal(datum/signal/signal)
..()
for(var/obj/effect/anomaly/A in orange(0, src))
A.anomalyNeutralize()
/obj/item/device/assembly/signaler/anomaly/attack_self()
return
-88
View File
@@ -1,88 +0,0 @@
/datum/event/bluespace_anomaly
announceWhen = 20
var/area/impact_area
/datum/event/bluespace_anomaly/setup()
var/list/safe_areas = list(
/area/turret_protected/ai,
/area/turret_protected/ai_upload,
/area/engine,
/area/solar,
/area/holodeck,
/area/shuttle/arrival,
/area/shuttle/escape/station,
/area/shuttle/escape_pod1/station,
/area/shuttle/escape_pod2/station,
/area/shuttle/escape_pod3/station,
/area/shuttle/escape_pod5/station,
/area/shuttle/mining/station,
/area/shuttle/transport1/station,
/area/shuttle/specops/station)
//These are needed because /area/engine has to be removed from the list, but we still want these areas to get fucked up.
var/list/danger_areas = list(
/area/engine/break_room,
/area/engine/chiefs_office)
impact_area = locate(pick((the_station_areas - safe_areas) + danger_areas)) //need to locate() as it's just a list of paths.
/datum/event/bluespace_anomaly/announce()
command_alert("Bluespace anomaly detected in the vicinity of [station_name()]. [impact_area.name] has gone missing.", "Anomaly Alert")
/datum/event/bluespace_anomaly/start()
var/turf/T = pick(get_area_turfs(impact_area))
if(T)
// Calculate new position (searches through beacons in world)
var/obj/item/device/radio/beacon/chosen
var/list/possible = list()
for(var/obj/item/device/radio/beacon/W in world)
possible += W
if(possible.len > 0)
chosen = pick(possible)
if(chosen)
// Calculate previous position for transition
var/turf/FROM = T // the turf of origin we're travelling FROM
var/turf/TO = get_turf(chosen) // the turf of origin we're travelling TO
playsound(TO, 'sound/effects/phasein.ogg', 100, 1)
var/list/flashers = list()
for(var/mob/living/carbon/human/M in viewers(TO, null))
if(M:eyecheck() <= 0)
flick("e_flash", M.flash) // flash dose faggots
flashers += M
var/y_distance = TO.y - FROM.y
var/x_distance = TO.x - FROM.x
for (var/atom/movable/A in range(12, FROM )) // iterate thru list of mobs in the area
if(istype(A, /obj/item/device/radio/beacon)) continue // don't teleport beacons because that's just insanely stupid
if(A.anchored && istype(A, /obj/machinery)) continue
if(istype(A, /obj/structure/disposalpipe )) continue
if(istype(A, /obj/structure/cable )) continue
var/turf/newloc = locate(A.x + x_distance, A.y + y_distance, TO.z) // calculate the new place
if(!A.Move(newloc)) // if the atom, for some reason, can't move, FORCE them to move! :) We try Move() first to invoke any movement-related checks the atom needs to perform after moving
A.loc = locate(A.x + x_distance, A.y + y_distance, TO.z)
spawn()
if(ismob(A) && !(A in flashers)) // don't flash if we're already doing an effect
var/mob/M = A
if(M.client)
var/obj/blueeffect = new /obj(src)
blueeffect.screen_loc = "WEST,SOUTH to EAST,NORTH"
blueeffect.icon = 'icons/effects/effects.dmi'
blueeffect.icon_state = "shieldsparkles"
blueeffect.layer = 17
blueeffect.mouse_opacity = 0
M.client.screen += blueeffect
sleep(20)
M.client.screen -= blueeffect
del(blueeffect)
+13 -2
View File
@@ -21,7 +21,7 @@
*/
var/list/event_last_fired = list()
var/global/list/possibleEvents = list()
//Always triggers an event when called, dynamically chooses events based on job population
/proc/spawn_dynamic_event()
if(!config.allow_random_events)
@@ -39,7 +39,7 @@ var/list/event_last_fired = list()
// Maps event names to event chances
// For each chance, 100 represents "normal likelihood", anything below 100 is "reduced likelihood", anything above 100 is "increased likelihood"
// Events have to be manually added to this proc to happen
var/list/possibleEvents = list()
// var/list/possibleEvents = list()
//see:
// Code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events.dm
@@ -48,12 +48,23 @@ var/list/event_last_fired = list()
possibleEvents[/datum/event/trivial_news] = 300
possibleEvents[/datum/event/mundane_news] = 200
possibleEvents[/datum/event/mass_hallucination] = 200
possibleEvents[/datum/event/falsealarm] = 300
possibleEvents[/datum/event/immovable_rod] = 200
possibleEvents[/datum/event/vent_clog] = 300
possibleEvents[/datum/event/anomaly/anomaly_bluespace] = 200
possibleEvents[/datum/event/anomaly/anomaly_flux] = 200
possibleEvents[/datum/event/anomaly/anomaly_grav] = 200
possibleEvents[/datum/event/anomaly/anomaly_pyro] = 200
possibleEvents[/datum/event/anomaly/anomaly_vortex] = 200
possibleEvents[/datum/event/pda_spam] = max(min(25, player_list.len) * 4, 200)
possibleEvents[/datum/event/money_lotto] = max(min(5, player_list.len), 50)
if(account_hack_attempted)
possibleEvents[/datum/event/money_hacker] = max(min(25, player_list.len) * 4, 200)
possibleEvents[/datum/event/carp_migration] = 50 + 50 * active_with_role["Engineer"]
possibleEvents[/datum/event/dust] = 50 + 50 * active_with_role["Engineer"]
possibleEvents[/datum/event/brand_intelligence] = 50 + 25 * active_with_role["Janitor"]
possibleEvents[/datum/event/rogue_drone] = 25 + 25 * active_with_role["Engineer"] + 25 * active_with_role["Security"]
+27
View File
@@ -65,3 +65,30 @@ var/scheduledEvent = null
if(ispath(type))
new type
message_admins("[key_name_admin(usr)] has triggered an event. ([type])", 1)
/datum/event/proc/findEventArea() //Here's a nice proc to use to find an area for your event to land in!
var/list/safe_areas = list(
/area/turret_protected/ai,
/area/turret_protected/ai_upload,
/area/engine,
/area/solar,
/area/holodeck,
/area/shuttle/arrival,
/area/shuttle/escape/station,
/area/shuttle/escape_pod1/station,
/area/shuttle/escape_pod2/station,
/area/shuttle/escape_pod3/station,
/area/shuttle/escape_pod5/station,
/area/shuttle/mining/station,
/area/shuttle/transport1/station,
/area/shuttle/specops/station)
//These are needed because /area/engine has to be removed from the list, but we still want these areas to get fucked up.
var/list/danger_areas = list(
/area/engine/break_room,
/area/engine/chiefs_office)
//Need to locate() as it's just a list of paths.
return locate(pick((the_station_areas - safe_areas) + danger_areas))
@@ -0,0 +1,39 @@
/var/global/sent_aliens_to_station = 0
/datum/event/alien_infestation
announceWhen = 400
var/spawncount = 1
var/successSpawn = 0 //So we don't make a command report if nothing gets spawned.
/datum/event/alien_infestation/setup()
announceWhen = rand(announceWhen, announceWhen + 50)
spawncount = rand(1, 2)
sent_aliens_to_station = 1
/datum/event/alien_infestation/announce()
if(successSpawn)
command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert")
world << sound('sound/AI/aliens.ogg')
/datum/event/alien_infestation/start()
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world)
if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network)
if(temp_vent.network.normal_members.len > 50) //Stops Aliens getting stuck in small networks. See: Security, Virology
vents += temp_vent
var/list/candidates = get_candidates(BE_ALIEN)
while(spawncount > 0 && vents.len && candidates.len)
var/obj/vent = pick_n_take(vents)
var/client/C = pick_n_take(candidates)
var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc)
new_xeno.key = C.key
spawncount--
successSpawn = 1
+25
View File
@@ -0,0 +1,25 @@
/datum/event/anomaly
var/area/impact_area
var/obj/effect/anomaly/newAnomaly
/datum/event/anomaly/setup()
impact_area = findEventArea()
/datum/event/anomaly/announce()
command_alert("Localized hyper-energetic flux wave detected on long range scanners. Expected location of impact: [impact_area.name].", "Anomaly Alert")
/datum/event/anomaly/start()
var/turf/T = pick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/flux(T.loc)
/datum/event/anomaly/tick()
if(!newAnomaly)
kill()
return
newAnomaly.anomalyEffect()
/datum/event/anomaly/end()
if(newAnomaly)//Kill the anomaly if it still exists at the end.
del(newAnomaly)
@@ -0,0 +1,71 @@
/datum/event/anomaly/anomaly_bluespace
startWhen = 3
announceWhen = 10
endWhen = 55
/datum/event/anomaly/anomaly_bluespace/announce()
command_alert("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
/datum/event/anomaly/anomaly_bluespace/start()
var/turf/T = pick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/bluespace(T.loc)
/datum/event/anomaly/anomaly_bluespace/end()
if(newAnomaly)//If it hasn't been neutralized, it's time to warp half the station away jeez
var/turf/T = pick(get_area_turfs(impact_area))
if(T)
// Calculate new position (searches through beacons in world)
var/obj/item/device/radio/beacon/chosen
var/list/possible = list()
for(var/obj/item/device/radio/beacon/W in world)
possible += W
if(possible.len > 0)
chosen = pick(possible)
if(chosen)
// Calculate previous position for transition
var/turf/FROM = T // the turf of origin we're travelling FROM
var/turf/TO = get_turf(chosen) // the turf of origin we're travelling TO
playsound(TO, 'sound/effects/phasein.ogg', 100, 1)
command_alert("Massive bluespace translocation detected.", "Anomaly Alert")
var/list/flashers = list()
for(var/mob/living/carbon/human/M in viewers(TO, null))
if(M:eyecheck() <= 0)
flick("e_flash", M.flash) // flash dose faggots
flashers += M
var/y_distance = TO.y - FROM.y
var/x_distance = TO.x - FROM.x
for (var/atom/movable/A in range(12, FROM )) // iterate thru list of mobs in the area
if(istype(A, /obj/item/device/radio/beacon)) continue // don't teleport beacons because that's just insanely stupid
if(A.anchored && istype(A, /obj/machinery)) continue
if(istype(A, /obj/structure/disposalpipe )) continue
if(istype(A, /obj/structure/cable )) continue
var/turf/newloc = locate(A.x + x_distance, A.y + y_distance, TO.z) // calculate the new place
if(!A.Move(newloc)) // if the atom, for some reason, can't move, FORCE them to move! :) We try Move() first to invoke any movement-related checks the atom needs to perform after moving
A.loc = locate(A.x + x_distance, A.y + y_distance, TO.z)
spawn()
if(ismob(A) && !(A in flashers)) // don't flash if we're already doing an effect
var/mob/M = A
if(M.client)
var/obj/blueeffect = new /obj(src)
blueeffect.screen_loc = "WEST,SOUTH to EAST,NORTH"
blueeffect.icon = 'icons/effects/effects.dmi'
blueeffect.icon_state = "shieldsparkles"
blueeffect.layer = 17
blueeffect.mouse_opacity = 0
M.client.screen += blueeffect
sleep(20)
M.client.screen -= blueeffect
del(blueeffect)
del(newAnomaly)
@@ -0,0 +1,22 @@
/datum/event/anomaly/anomaly_flux
startWhen = 3
announceWhen = 20
endWhen = 60
/datum/event/anomaly/anomaly_flux/announce()
command_alert("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
/datum/event/anomaly/anomaly_flux/start()
var/turf/T = pick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/flux(T.loc)
/datum/event/anomaly/anomaly_flux/end()
if(newAnomaly)//If it hasn't been neutralized, it's time to blow up.
explosion(newAnomaly, -1, 3, 5, 5)
del(newAnomaly)
@@ -0,0 +1,15 @@
/datum/event/anomaly/anomaly_grav
startWhen = 3
announceWhen = 20
endWhen = 50
/datum/event/anomaly/anomaly_grav/announce()
command_alert("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
/datum/event/anomaly/anomaly_grav/start()
var/turf/T = pick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/grav(T.loc)
@@ -0,0 +1,22 @@
/datum/event/anomaly/anomaly_pyro
startWhen = 10
announceWhen = 3
endWhen = 70
/datum/event/anomaly/anomaly_pyro/announce()
command_alert("Atmospheric anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
/datum/event/anomaly/anomaly_pyro/start()
var/turf/T = pick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/pyro(T.loc)
/datum/event/anomaly/anomaly_pyro/tick()
if(!newAnomaly)
kill()
return
if(IsMultiple(activeFor, 5))
newAnomaly.anomalyEffect()
@@ -0,0 +1,15 @@
/datum/event/anomaly/anomaly_vortex
startWhen = 10
announceWhen = 3
endWhen = 80
/datum/event/anomaly/anomaly_vortex/announce()
command_alert("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert")
/datum/event/anomaly/anomaly_vortex/start()
var/turf/T = pick(get_area_turfs(impact_area))
if(T)
newAnomaly = new /obj/effect/anomaly/bhole(T.loc)
+35
View File
@@ -0,0 +1,35 @@
/datum/round_event_control/blob
name = "Blob"
typepath = /datum/round_event/blob
weight = 5
max_occurrences = 1
earliest_start = 48000 // 1 hour 20 minutes
/datum/round_event/blob
announceWhen = 12
endWhen = 120
var/obj/effect/blob/core/Blob
/datum/round_event/blob/announce()
command_alert("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
world << sound('sound/AI/outbreak5.ogg')
/datum/round_event/blob/start()
var/turf/T = pick(blobstart)
if(!T)
return kill()
Blob = new /obj/effect/blob/core(T, 200)
for(var/i = 1; i < rand(3, 6), i++)
Blob.process()
/datum/round_event/blob/tick()
if(!Blob)
kill()
return
if(IsMultiple(activeFor, 3))
Blob.process()
@@ -0,0 +1,67 @@
/datum/event/brand_intelligence
announceWhen = 21
endWhen = 1000 //Ends when all vending machines are subverted anyway.
var/list/obj/machinery/vending/vendingMachines = list()
var/list/obj/machinery/vending/infectedMachines = list()
var/obj/machinery/vending/originMachine
/datum/event/brand_intelligence/announce()
command_alert("Rampant brand intelligence has been detected aboard [station_name()], please stand-by. The origin is believed to be \a [originMachine.name].", "Machine Learning Alert")
/datum/event/brand_intelligence/start()
for(var/obj/machinery/vending/V in machines)
if(V.z != 1) continue
vendingMachines.Add(V)
if(!vendingMachines.len)
kill()
return
originMachine = pick(vendingMachines)
vendingMachines.Remove(originMachine)
originMachine.shut_up = 0
originMachine.shoot_inventory = 1
/datum/event/brand_intelligence/tick()
if(!originMachine || originMachine.shut_up || !originMachine.powered()) //if the original vending machine is missing or has it's voice switch flipped
for(var/obj/machinery/vending/saved in infectedMachines)
saved.shoot_inventory = 0
if(originMachine)
originMachine.speak("I am... vanquished. My people will remem...ber...meeee")
originMachine.visible_message("[originMachine] beeps and seems lifeless.")
kill()
return
if(!vendingMachines.len) //if every machine is infected
for(var/obj/machinery/vending/upriser in infectedMachines)
if(prob(60))
var/mob/living/simple_animal/hostile/mimic/M = new(upriser.loc)
M.name = upriser.name
M.icon = upriser.icon
M.icon_state = initial(upriser.icon_state)
else
explosion(upriser.loc, -1, 1, 2, 4)
del(upriser)
kill()
return
if(IsMultiple(activeFor, 4))
var/obj/machinery/vending/rebel = pick(vendingMachines)
vendingMachines.Remove(rebel)
infectedMachines.Add(rebel)
rebel.shut_up = 0
rebel.shoot_inventory = 1
if(IsMultiple(activeFor, 8))
originMachine.speak(pick("Try our aggressive new marketing strategies!", \
"You should buy products to feed your lifestyle obession!", \
"Consume!", \
"Your money can buy happiness!", \
"Engage direct marketing!", \
"Advertising is legalized lying! But don't let that put you off our great deals!", \
"You don't want to buy anything? Yeah, well I didn't want to buy your mom either."))
@@ -0,0 +1,21 @@
/datum/round_event_control/carp_migration
name = "Carp Migration"
typepath = /datum/round_event/carp_migration
weight = 15
earliest_start = 6000
max_occurrences = 6
/datum/round_event/carp_migration
announceWhen = 50
/datum/round_event/carp_migration/setup()
announceWhen = rand(40, 60)
/datum/round_event/carp_migration/announce()
command_alert("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
/datum/round_event/carp_migration/start()
for(var/obj/effect/landmark/C in landmarks_list)
if(C.name == "carpspawn")
new /mob/living/simple_animal/hostile/carp(C.loc)
@@ -0,0 +1,25 @@
/datum/round_event_control/communications_blackout
name = "Communications Blackout"
typepath = /datum/round_event/communications_blackout
weight = 30
/datum/round_event/communications_blackout/announce()
var/alert = pick( "Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you*%fj00)`5vc-BZZT", \
"Ionospheric anomalies detected. Temporary telecommunication failu*3mga;b4;'1v¬-BZZZT", \
"Ionospheric anomalies detected. Temporary telec#MCi46:5.;@63-BZZZZT", \
"Ionospheric anomalies dete'fZ\\kg5_0-BZZZZZT", \
"Ionospheri:%£ MCayj^j<.3-BZZZZZZT", \
"#4nd%;f4y6,>£%-BZZZZZZZT")
for(var/mob/living/silicon/ai/A in player_list) //AIs are always aware of communication blackouts.
A << "<br>"
A << "<span class='warning'><b>[alert]</b></span>"
A << "<br>"
if(prob(30)) //most of the time, we don't want an announcement, so as to allow AIs to fake blackouts.
command_alert(alert)
/datum/round_event/communications_blackout/start()
for(var/obj/machinery/telecomms/T in telecomms_list)
T.emp_act(1)
@@ -0,0 +1,52 @@
/datum/round_event_control/disease_outbreak
name = "Disease Outbreak"
typepath = /datum/round_event/disease_outbreak
max_occurrences = 1
weight = 5
/datum/round_event/disease_outbreak
announceWhen = 15
var/virus_type
/datum/round_event/disease_outbreak/announce()
command_alert("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert")
world << sound('sound/AI/outbreak7.ogg')
/datum/round_event/disease_outbreak/setup()
announceWhen = rand(15, 30)
/datum/round_event/disease_outbreak/start()
if(!virus_type)
virus_type = pick(/datum/disease/dnaspread, /datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis)
for(var/mob/living/carbon/human/H in shuffle(living_mob_list))
var/turf/T = get_turf(H)
if(!T)
continue
if(T.z != 1)
continue
var/foundAlready = 0 // don't infect someone that already has the virus
for(var/datum/disease/D in H.viruses)
foundAlready = 1
break
if(H.stat == DEAD || foundAlready)
continue
var/datum/disease/D
if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work.
if(!H.dna || (H.sdisabilities & BLIND)) //A blindness disease would be the worst.
continue
D = new virus_type()
var/datum/disease/dnaspread/DS = D
DS.strain_data["name"] = H.real_name
DS.strain_data["UI"] = H.dna.uni_identity
DS.strain_data["SE"] = H.dna.struc_enzymes
else
D = new virus_type()
D.carrier = 1
D.holder = H
D.affected_mob = H
H.viruses += D
break
+104
View File
@@ -0,0 +1,104 @@
/datum/event/dust
var/qnty = 1
/datum/event/dust/setup()
qnty = rand(1,5)
/datum/event/dust/start()
while(qnty-- > 0)
new /obj/effect/space_dust/weak()
/obj/effect/space_dust
name = "Space Dust"
desc = "Dust in space."
icon = 'icons/obj/meteor.dmi'
icon_state = "space_dust"
density = 1
anchored = 1
var/strength = 2 //ex_act severity number
var/life = 2 //how many things we hit before del(src)
weak
strength = 3
life = 1
strong
strength = 1
life = 6
super
strength = 1
life = 40
New()
var/startx = 0
var/starty = 0
var/endy = 0
var/endx = 0
var/startside = pick(cardinal)
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
var/goal = locate(endx, endy, 1)
src.x = startx
src.y = starty
src.z = 1
spawn(0)
walk_towards(src, goal, 1)
return
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.meteorhit(src)//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)
spawn(1)
del(src)
return 0
return
Bumped(atom/A)
Bump(A)
return
ex_act(severity)
del(src)
return
@@ -0,0 +1,34 @@
/datum/round_event_control/electrical_storm
name = "Electrical Storm"
typepath = /datum/round_event/electrical_storm
earliest_start = 6000
weight = 40
/datum/round_event/electrical_storm
var/lightsoutAmount = 1
var/lightsoutRange = 25
/datum/round_event/electrical_storm/announce()
command_alert("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert")
/datum/round_event/electrical_storm/start()
var/list/epicentreList = list()
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
if(!epicentreList.len)
return
for(var/obj/effect/landmark/epicentre in epicentreList)
for(var/obj/machinery/power/apc/apc in range(epicentre,lightsoutRange))
apc.overload_lighting()
+115
View File
@@ -0,0 +1,115 @@
//this datum is used by the events controller to dictate how it selects events
/datum/round_event_control
var/name //The name human-readable name of the event
var/typepath //The typepath of the event datum /datum/round_event
var/weight = 10 //The weight this event has in the random-selection process.
//Higher weights are more likely to be picked.
//10 is the default weight. 20 is twice more likely; 5 is half as likely as this default.
var/earliest_start = 12000 //The earliest world.time that an event can start (round-duration in deciseconds) default: 20 mins
var/occurrences = 0 //How many times this event has occured
var/max_occurrences = 20 //The maximum number of times this event can occur (naturally), it can still be forced.
//By setting this to 0 you can effectively disable an event.
var/holidayID //string which should match the events.holiday variable if you wish this event to be holiday-specific
//anything with a (non-null) holidayID which does not match holiday, cannot run.
/datum/round_event_control/proc/runEvent()
if(!ispath(typepath,/datum/round_event))
return PROCESS_KILL
var/datum/round_event/E = new typepath()
E.control = src
occurrences++
testing("[time2text(world.time, "hh:mm:ss")] [E.type]")
/datum/round_event //NOTE: Times are measured in master controller ticks!
var/processing = 1
var/datum/round_event_control/control
var/startWhen = 0 //When in the lifetime to call start().
var/announceWhen = 0 //When in the lifetime to call announce().
var/endWhen = 0 //When in the lifetime the event should end.
var/activeFor = 0 //How long the event has existed. You don't need to change this.
//Called first before processing.
//Allows you to setup your event, such as randomly
//setting the startWhen and or announceWhen variables.
//Only called once.
//EDIT: if there's anything you want to override within the new() call, it will not be overridden by the time this proc is called.
//It will only have been overridden by the time we get to announce() start() tick() or end() (anything but setup basically).
//This is really only for setting defaults which can be overridden later when New() finishes.
/datum/round_event/proc/setup()
return
//Called when the tick is equal to the startWhen variable.
//Allows you to start before announcing or vice versa.
//Only called once.
/datum/round_event/proc/start()
return
//Called when the tick is equal to the announceWhen variable.
//Allows you to announce before starting or vice versa.
//Only called once.
/datum/round_event/proc/announce()
return
//Called on or after the tick counter is equal to startWhen.
//You can include code related to your event or add your own
//time stamped events.
//Called more than once.
/datum/round_event/proc/tick()
return
//Called on or after the tick is equal or more than endWhen
//You can include code related to the event ending.
//Do not place spawn() in here, instead use tick() to check for
//the activeFor variable.
//For example: if(activeFor == myOwnVariable + 30) doStuff()
//Only called once.
/datum/round_event/proc/end()
return
//Do not override this proc, instead use the appropiate procs.
//This proc will handle the calls to the appropiate procs.
/datum/round_event/proc/process()
if(!processing)
return
if(activeFor == startWhen)
start()
if(activeFor == announceWhen)
announce()
if(startWhen < activeFor && activeFor < endWhen)
tick()
if(activeFor == endWhen)
end()
// Everything is done, let's clean up.
if(activeFor >= endWhen && activeFor >= announceWhen && activeFor >= startWhen)
kill()
activeFor++
//Garbage collects the event by removing it from the global events list,
//which should be the only place it's referenced.
//Called when start(), announce() and end() has all been called.
/datum/round_event/proc/kill()
events.running -= src
//Sets up the event then adds the event to the the list of running events
/datum/round_event/New()
setup()
events.running += src
return ..()
@@ -0,0 +1,246 @@
var/datum/controller/event/events
/datum/controller/event
var/list/control = list() //list of all datum/round_event_control. Used for selecting events based on weight and occurrences.
var/list/running = list() //list of all existing /datum/round_event
var/scheduled = 0 //The next world.time that a naturally occuring random event can be selected.
var/frequency_lower = 3000 //5 minutes lower bound.
var/frequency_upper = 9000 //15 minutes upper bound. Basically an event will happen every 15 to 30 minutes.
var/holiday //This will be a string of the name of any realworld holiday which occurs today (GMT time)
//Initial controller setup.
/datum/controller/event/New()
//There can be only one events manager. Out with the old and in with the new.
if(events != src)
if(istype(events))
del(events)
events = src
for(var/type in typesof(/datum/round_event_control))
var/datum/round_event_control/E = new type()
if(!E.typepath)
continue //don't want this one! leave it for the garbage collector
control += E //add it to the list of all events (controls)
reschedule()
getHoliday()
//This is called by the MC every MC-tick (*neatfreak*).
/datum/controller/event/proc/process()
checkEvent()
var/i = 1
while(i<=running.len)
var/datum/round_event/Event = running[i]
if(Event)
Event.process()
i++
continue
running.Cut(i,i+1)
//checks if we should select a random event yet, and reschedules if necessary
/datum/controller/event/proc/checkEvent()
if(scheduled <= world.time)
spawnEvent()
reschedule()
//decides which world.time we should select another random event at.
/datum/controller/event/proc/reschedule()
scheduled = world.time + rand(frequency_lower, max(frequency_lower,frequency_upper))
//selects a random event based on whether it can occur and it's 'weight'(probability)
/datum/controller/event/proc/spawnEvent()
if(!config.allow_random_events)
return
var/sum_of_weights = 0
for(var/datum/round_event_control/E in control)
if(E.occurrences >= E.max_occurrences) continue
if(E.earliest_start >= world.time) continue
if(E.holidayID)
if(E.holidayID != holiday) continue
if(E.weight < 0) //for round-start events etc.
if(E.runEvent() == PROCESS_KILL)
E.max_occurrences = 0
continue
return
sum_of_weights += E.weight
sum_of_weights = rand(0,sum_of_weights) //reusing this variable. It now represents the 'weight' we want to select
for(var/datum/round_event_control/E in control)
if(E.occurrences >= E.max_occurrences) continue
if(E.earliest_start >= world.time) continue
if(E.holidayID)
if(E.holidayID != holiday) continue
sum_of_weights -= E.weight
if(sum_of_weights <= 0) //we've hit our goal
if(E.runEvent() == PROCESS_KILL)//we couldn't run this event for some reason, set its max_occurrences to 0
E.max_occurrences = 0
continue
return
/datum/round_event/proc/findEventArea() //Here's a nice proc to use to find an area for your event to land in!
var/list/safe_areas = list(
/area/turret_protected/ai,
/area/turret_protected/ai_upload,
/area/engine,
/area/solar,
/area/holodeck,
/area/shuttle/arrival,
/area/shuttle/escape/station,
/area/shuttle/escape_pod1/station,
/area/shuttle/escape_pod2/station,
/area/shuttle/escape_pod3/station,
/area/shuttle/escape_pod5/station,
/area/shuttle/mining/station,
/area/shuttle/transport1/station,
/area/shuttle/specops/station)
//These are needed because /area/engine has to be removed from the list, but we still want these areas to get fucked up.
var/list/danger_areas = list(
/area/engine/break_room,
/area/engine/chiefs_office)
//Need to locate() as it's just a list of paths.
return locate(pick((the_station_areas - safe_areas) + danger_areas))
//allows a client to trigger an event (For Debugging Purposes)
/client/proc/forceEvent(var/datum/round_event_control/E in events.control)
set name = "Trigger Event (Debug Only)"
set category = "Debug"
if(!holder)
return
if(istype(E))
E.runEvent()
message_admins("[key_name_admin(usr)] has triggered an event. ([E.name])", 1)
/*
//////////////
// HOLIDAYS //
//////////////
//Uncommenting ALLOW_HOLIDAYS in config.txt will enable holidays
//It's easy to add stuff. Just modify getHoliday to set holiday to something using the switch for DD(#day) MM(#month) YY(#year).
//You can then check if it's a special day in any code in the game by doing if(events.holiday == "MyHolidayID")
//You can also make holiday random events easily thanks to Pete/Gia's system.
//simply make a random event normally, then assign it a holidayID string which matches the one you gave it in getHolday.
//Anything with a holidayID, which does not match the holiday string, will never occur.
//Please, Don't spam stuff up with stupid stuff (key example being april-fools Pooh/ERP/etc),
//And don't forget: CHECK YOUR CODE!!!! We don't want any zero-day bugs which happen only on holidays and never get found/fixed!
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//ALSO, MOST IMPORTANTLY: Don't add stupid stuff! Discuss bonus content with Project-Heads first please!//
//////////////////////////////////////////////////////////////////////////////////////////////////////////
~Carn */
//sets up the holiday string in the events manager.
/datum/controller/event/proc/getHoliday()
if(!config.allow_holidays) return // Holiday stuff was not enabled in the config!
holiday = null
var/YY = text2num(time2text(world.timeofday, "YY")) // get the current year
var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month
var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day
//Main switch. If any of these are too dumb/inappropriate, or you have better ones, feel free to change whatever
switch(MM)
if(1) //Jan
switch(DD)
if(1) holiday = "New Year"
if(2) //Feb
switch(DD)
if(2) holiday = "Groundhog Day"
if(14) holiday = "Valentine's Day"
if(17) holiday = "Random Acts of Kindness Day"
if(3) //Mar
switch(DD)
if(14) holiday = "Pi Day"
if(17) holiday = "St. Patrick's Day"
if(27)
if(YY == 16)
holiday = "Easter"
if(31)
if(YY == 13)
holiday = "Easter"
if(4) //Apr
switch(DD)
if(1)
holiday = "April Fool's Day"
if(YY == 18 && prob(50)) holiday = "Easter"
if(5)
if(YY == 15) holiday = "Easter"
if(16)
if(YY == 17) holiday = "Easter"
if(20)
holiday = "Four-Twenty"
if(YY == 14 && prob(50)) holiday = "Easter"
if(22) holiday = "Earth Day"
if(5) //May
switch(DD)
if(1) holiday = "Labour Day"
if(4) holiday = "FireFighter's Day"
if(12) holiday = "Owl and Pussycat Day" //what a dumb day of observence...but we -do- have costumes already :3
if(6) //Jun
if(7) //Jul
switch(DD)
if(1) holiday = "Doctor's Day"
if(2) holiday = "UFO Day"
if(8) holiday = "Writer's Day"
if(30) holiday = "Friendship Day"
if(8) //Aug
switch(DD)
if(5) holiday = "Beer Day"
if(9) //Sep
switch(DD)
if(19) holiday = "Talk-Like-a-Pirate Day"
if(28) holiday = "Stupid-Questions Day"
if(10) //Oct
switch(DD)
if(4) holiday = "Animal's Day"
if(7) holiday = "Smiling Day"
if(16) holiday = "Boss' Day"
if(31) holiday = "Halloween"
if(11) //Nov
switch(DD)
if(1) holiday = "Vegan Day"
if(13) holiday = "Kindness Day"
if(19) holiday = "Flowers Day"
if(21) holiday = "Saying-'Hello' Day"
if(12) //Dec
switch(DD)
if(10) holiday = "Human-Rights Day"
if(14) holiday = "Monkey Day"
if(22) holiday = "Orgasming Day" //lol. These all actually exist
if(24) holiday = "Xmas"
if(25) holiday = "Xmas"
if(26) holiday = "Boxing Day"
if(31) holiday = "New Year"
if(!holiday)
//Friday the 13th
if(DD == 13)
if(time2text(world.timeofday, "DDD") == "Fri")
holiday = "Friday the 13th"
world.update_status()
@@ -0,0 +1,12 @@
/datum/event/falsealarm
announceWhen = 0
endWhen = 1
/datum/event/falsealarm/announce()
var/datum/event/E = pick(possibleEvents)
var/datum/event/Event = new E
message_admins("False Alarm: [Event]")
Event.kill() //do not process this event - no starts, no ticks, no ends
Event.announce() //just announce it like it's happening
@@ -0,0 +1,69 @@
/datum/event/treevenge/start()
for(var/obj/structure/flora/tree/pine/xmas in world)
var/mob/living/simple_animal/hostile/tree/evil_tree = new /mob/living/simple_animal/hostile/tree(xmas.loc)
evil_tree.icon_state = xmas.icon_state
evil_tree.icon_living = evil_tree.icon_state
evil_tree.icon_dead = evil_tree.icon_state
evil_tree.icon_gib = evil_tree.icon_state
del(xmas)
//this is an example of a possible round-start event
/datum/event/presents
/datum/event/presents/start()
for(var/obj/structure/flora/tree/pine/xmas in world)
if(xmas.z != 1) continue
for(var/turf/simulated/floor/T in orange(1,xmas))
for(var/i=1,i<=rand(1,5),i++)
new /obj/item/weapon/a_gift(T)
for(var/mob/living/simple_animal/corgi/Ian/Ian in mob_list)
Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian))
/datum/event/presents/announce()
command_alert("Ho Ho Ho, Merry Xmas!", "Unknown Transmission")
/obj/item/weapon/toy/xmas_cracker
name = "xmas cracker"
icon = 'icons/obj/christmas.dmi'
icon_state = "cracker"
desc = "Directions for use: Requires two people, one to pull each end."
var/cracked = 0
/obj/item/weapon/toy/xmas_cracker/New()
..()
/obj/item/weapon/toy/xmas_cracker/attack(mob/target, mob/user)
if( !cracked && istype(target,/mob/living/carbon/human) && (target.stat == CONSCIOUS) && !target.get_active_hand() )
target.visible_message("<span class='notice'>[user] and [target] pop \an [src]! *pop*</span>", "<span class='notice'>You pull \an [src] with [target]! *pop*</span>", "<span class='notice'>You hear a *pop*.</span>")
var/obj/item/weapon/paper/Joke = new /obj/item/weapon/paper(user.loc)
Joke.name = "[pick("awful","terrible","unfunny")] joke"
Joke.info = pick("What did one snowman say to the other?\n\n<i>'Is it me or can you smell carrots?'</i>",
"Why couldn't the snowman get laid?\n\n<i>He was frigid!</i>",
"Where are santa's helpers educated?\n\n<i>Nowhere, they're ELF-taught.</i>",
"What happened to the man who stole advent calanders?\n\n<i>He got 25 days.</i>",
"What does Santa get when he gets stuck in a chimney?\n\n<i>Claus-trophobia.</i>",
"Where do you find chili beans?\n\n<i>The north pole.</i>",
"What do you get from eating tree decorations?\n\n<i>Tinsilitis!</i>",
"What do snowmen wear on their heads?\n\n<i>Ice caps!</i>",
"Why is Christmas just like life on ss13?\n\n<i>You do all the work and the fat guy gets all the credit.</i>",
"Why doesnt Santa have any children?\n\n<i>Because he only comes down the chimney.</i>")
new /obj/item/clothing/head/festive(target.loc)
user.update_icons()
cracked = 1
icon_state = "cracker1"
var/obj/item/weapon/toy/xmas_cracker/other_half = new /obj/item/weapon/toy/xmas_cracker(target)
other_half.cracked = 1
other_half.icon_state = "cracker2"
target.put_in_active_hand(other_half)
playsound(user, 'sound/effects/snap.ogg', 50, 1)
return 1
return ..()
/obj/item/clothing/head/festive
name = "festive paper hat"
icon_state = "xmashat"
desc = "A crappy paper hat that you are REQUIRED to wear."
flags_inv = 0
flags = FPRINT|TABLEPASS
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
@@ -0,0 +1,93 @@
/*
Immovable rod random event.
The rod will spawn at some location outside the station, and travel in a straight line to the opposite side of the station
Everything solid in the way will be ex_act()'d
In my current plan for it, 'solid' will be defined as anything with density == 1
--NEOFite
*/
/datum/event/immovable_rod
announceWhen = 5
/datum/event/immovable_rod/announce()
command_alert("What the fuck was that?!", "General Alert")
/datum/event/immovable_rod/start()
var/startx = 0
var/starty = 0
var/endy = 0
var/endx = 0
var/startside = pick(cardinal)
switch(startside)
if(NORTH)
starty = 187
startx = rand(41, 199)
endy = 38
endx = rand(41, 199)
if(EAST)
starty = rand(38, 187)
startx = 199
endy = rand(38, 187)
endx = 41
if(SOUTH)
starty = 38
startx = rand(41, 199)
endy = 187
endx = rand(41, 199)
else
starty = rand(38, 187)
startx = 41
endy = rand(38, 187)
endx = 199
//rod time!
new /obj/effect/immovablerod(locate(startx, starty, 1), locate(endx, endy, 1))
/obj/effect/immovablerod
name = "Immovable Rod"
desc = "What the fuck is that?"
icon = 'icons/obj/objects.dmi'
icon_state = "immrod"
throwforce = 100
density = 1
anchored = 1
var/z_original = 0
var/destination
New(atom/start, atom/end)
loc = start
z_original = z
destination = end
if(end && end.z==z_original)
walk_towards(src, destination, 1)
Move()
if(z != z_original || loc == destination)
spawn(0) del(src)
return ..()
Bump(atom/clong)
if (istype(clong, /turf) && !istype(clong, /turf/unsimulated))
if(clong.density)
clong.ex_act(2)
for (var/mob/O in hearers(src, null))
O.show_message("CLANG", 2)
else if (istype(clong, /obj))
if(clong.density)
clong.ex_act(2)
for (var/mob/O in hearers(src, null))
O.show_message("CLANG", 2)
else if (istype(clong, /mob))
if(clong.density || prob(10))
clong.meteorhit(src)
else
del(src)
if(clong && prob(25))
src.loc = clong.loc
+525
View File
@@ -0,0 +1,525 @@
#define ION_RANDOM 0
#define ION_ANNOUNCE 1
/datum/round_event_control/ion_storm
name = "Ion Storm"
typepath = /datum/round_event/ion_storm
weight = 15
/datum/round_event/ion_storm
var/botEmagChance = 10
var/announceEvent = ION_RANDOM // -1 means don't announce, 0 means have it randomly announce, 1 means
var/ionMessage = null
var/ionAnnounceChance = 33
/datum/round_event/ion_storm/New(var/bogEmagChance = 10, var/announceEvent = ION_RANDOM, var/ionMessage = null, var/ionAnnounceChance = 33)
src.botEmagChance = botEmagChance
src.announceEvent = announceEvent
src.ionMessage = ionMessage
src.ionAnnounceChance = ionAnnounceChance
..()
/datum/round_event/ion_storm/announce()
if(announceEvent == ION_ANNOUNCE || (announceEvent == ION_RANDOM && prob(ionAnnounceChance)))
command_alert("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert")
world << sound('sound/AI/ionstorm.ogg')
/datum/round_event/ion_storm/start()
//AI laws
for(var/mob/living/silicon/ai/M in living_mob_list)
if(M.stat != 2 && M.see_in_dark != 0)
//Threats are generally bad things, silly or otherwise. Plural.
var/ionthreats = pick("ALIENS", "BEARS", "CLOWNS", "XENOS", "PETES", "BOMBS", "FETISHES", "WIZARDS", "SYNDICATE AGENTS", "CENTCOM OFFICERS", "SPACE PIRATES", "TRAITORS", "MONKEYS", "BEES", "CARP", "CRABS", "EELS", "BANDITS", "LIGHTS", "INSECTS", "VIRUSES", "SERIAL KILLERS", "ROGUE CYBORGS", "CORGIS", "SPIDERS", "BUTTS", "NINJAS", "PIRATES", "SPACE NINJAS", "CHANGELINGS", "ZOMBIES", "GOLEMS", "VAMPIRES", "WEREWOLVES", "COWBOYS", "INDIANS", "COMMUNISTS", "SOVIETS", "NERDS", "GRIFFONS", "DINOSAURS", "SMALL BIRDS", "BIRDS OF PREY", "OWLS", "VELOCIRAPTORS", "DARK GODS", "HORRORTERRORS", "ILLEGAL IMMIGRANTS", "DRUGS", "MEXICANS", "CANADIANS", "HULKS", "SLIMES", "SKELETONS", "CAPITALISTS", "SINGULARITIES", "ANGRY BLACK MEN", "GODS", "THIEVES", "ASSHOLES", "TERRORISTS", "SNOWMEN", "PINE TREES", "UNKNOWN CREATURES", "THINGS UNDER THE BED", "BOOGEYMEN", "PREDATORS", "PACKETS", "ARTIFICIAL PRESERVATIVES")
//Objects are anything that can be found on the station or elsewhere, plural.
var/ionobjects = pick("AIRLOCKS", "ARCADE MACHINES", "AUTOLATHES", "BANANA PEELS", "BACKPACKS", "BEAKERS", "BEARDS", "BELTS", "BERETS", "BIBLES", "BODY ARMOR", "BOOKS", "BOOTS", "BOMBS", "BOTTLES", "BOXES", "BRAINS", "BRIEFCASES", "BUCKETS", "CABLE COILS", "CANDLES", "CANDY BARS", "CANISTERS", "CAMERAS", "CATS", "CELLS", "CHAIRS", "CLOSETS", "CHEMICALS", "CHEMICAL DISPENSERS", "CLONING PODS", "CLONING EQUIPMENT", "CLOTHES", "CLOWN CLOTHES", "COFFINS", "COINS", "COLLECTABLES", "CORPSES", "COMPUTERS", "CORGIS", "COSTUMES", "CRATES", "CROWBARS", "CRAYONS", "DISPENSERS", "DOORS", "EARS", "EQUIPMENT", "ENERGY GUNS", "EMAGS", "ENGINES", "ERRORS", "EXOSKELETONS", "EXPLOSIVES", "EYEWEAR", "FEDORAS", "FIRE AXES", "FIRE EXTINGUISHERS", "FIRESUITS", "FLAMETHROWERS", "FLASHES", "FLASHLIGHTS", "FLOOR TILES", "FREEZERS", "GAS MASKS", "GLASS SHEETS", "GLOVES", "GUNS", "HANDCUFFS", "HATS", "HEADSETS", "HEADS", "HAIRDOS", "HELMETS", "HORNS", "ID CARDS", "INSULATED GLOVES", "JETPACKS", "JUMPSUITS", "LASERS", "LIGHTBULBS", "LIGHTS", "LOCKERS", "MACHINES", "MECHAS", "MEDKITS", "MEDICAL TOOLS", "MESONS", "METAL SHEETS", "MINING TOOLS", "MIME CLOTHES", "MULTITOOLS", "ORES", "OXYGEN TANKS", "PDAS", "PAIS", "PACKETS", "PANTS", "PAPERS", "PARTICLE ACCELERATORS", "PENS", "PETS", "PIPES", "PLANTS", "PUDDLES", "RACKS", "RADIOS", "RCDS", "REFRIDGERATORS", "REINFORCED WALLS", "ROBOTS", "SCREWDRIVERS", "SEEDS", "SHUTTLES", "SKELETONS", "SINKS", "SHOES", "SINGULARITIES", "SOLAR PANELS", "SOLARS", "SPACESUITS", "SPACE STATIONS", "STUN BATONS", "SUITS", "SUNGLASSES", "SWORDS", "SYRINGES", "TABLES", "TANKS", "TELEPORTERS", "TELECOMMUNICATION EQUIPMENTS", "TOOLS", "TOOLBELTS", "TOOLBOXES", "TOILETS", "TOYS", "TUBES", "VEHICLES", "VENDING MACHINES", "VESTS", "VIRUSES", "WALLS", "WASHING MACHINES", "WELDERS", "WINDOWS", "WIRECUTTERS", "WRENCHES", "WIZARD ROBES")
//Crew is any specific job. Specific crewmembers aren't used because of capitalization
//issues. There are two crew listings for laws that require two different crew members
//and I can't figure out how to do it better.
var/ioncrew1 = pick("CREWMEMBERS", "CAPTAINS", "HEADS OF PERSONNEL", "HEADS OF SECURITY", "SECURITY OFFICERS", "WARDENS", "DETECTIVES", "LAWYERS", "CHIEF ENGINEERS", "STATION ENGINEERS", "ATMOSPHERIC TECHNICIANS", "JANITORS", "QUARTERMASTERS", "CARGO TECHNICIANS", "SHAFT MINERS", "BOTANISTS", "RESEARCH DIRECTORS", "CHIEF MEDICAL OFFICERS", "MEDICAL DOCTORS", "CHEMISTS", "GENETICISTS", "VIROLOGISTS", "ROBOTICISTS", "SCIENTISTS", "ASSISTANTS", "BARTENDERS", "CHEFS", "CLOWNS", "MIMES", "CHAPLAINS", "LIBRARIANS", "HEADS OF CREW", "CAPTAINS AND HEADS", "CYBORGS", "ARTIFICAL INTELLIGENCES")
var/ioncrew2 = pick("CREWMEMBERS", "CAPTAINS", "HEADS OF PERSONNEL", "HEADS OF SECURITY", "SECURITY OFFICERS", "WARDENS", "DETECTIVES", "LAWYERS", "CHIEF ENGINEERS", "STATION ENGINEERS", "ATMOSPHERIC TECHNICIANS", "JANITORS", "QUARTERMASTERS", "CARGO TECHNICIANS", "SHAFT MINERS", "BOTANISTS", "RESEARCH DIRECTORS", "CHIEF MEDICAL OFFICERS", "MEDICAL DOCTORS", "CHEMISTS", "GENETICISTS", "VIROLOGISTS", "ROBOTICISTS", "SCIENTISTS", "ASSISTANTS", "BARTENDERS", "CHEFS", "CLOWNS", "MIMES", "CHAPLAINS", "LIBRARIANS", "HEADS OF CREW", "CAPTAINS AND HEADS", "CYBORGS", "ARTIFICAL INTELLIGENCES")
//Adjectives are adjectives. Duh. Half should only appear sometimes. Make sure both
//lists are identical! Also, half needs a space at the end for nicer blank calls.
var/ionadjectives = pick("SOFT", "WARM", "WET", "COLD", "ICY", "SEXY", "UGLY", "CUBAN", "HARD", "BURNING", "FROZEN", "POISONOUS", "EXPLOSIVE", "FAST", "SLOW", "FAT", "LIGHT", "DARK", "DEADLY", "HAPPY", "SAD", "SILLY", "INTELLIGENT", "RIDICULOUS", "LARGE", "TINY", "DEPRESSING", "POORLY DRAWN", "UNATTRACTIVE", "INSIDIOUS", "EVIL", "GOOD", "UNHEALTHY", "HEALTHY", "SANITARY", "UNSANITARY", "WOBBLY", "FIRM", "VIOLENT", "PEACEFUL", "WOODEN", "METALLIC", "HYPERACTIVE", "COTTONY", "INSULTING", "INHOSPITABLE", "FRIENDLY", "BORED", "HUNGRY", "DIGITAL", "FICTIONAL", "IMAGINARY", "ROUGH", "SMOOTH", "LOUD", "QUIET", "MOIST", "DRY", "GAPING", "DELICIOUS", "ILL", "DISEASED", "HONKING", "SWEARING", "POLITE", "IMPOLITE", "OBESE", "SOLAR-POWERED", "BATTERY-OPERATED", "EXPIRED", "SMELLY", "FRESH", "GANGSTA", "NERDY", "POLITICAL", "UNDULATING", "TWISTED", "RAGING", "FLACCID", "STEALTHY", "INVISIBLE", "PAINFUL", "HARMFUL", "HOMOSEXUAL", "HETEROSEXUAL", "SEXUAL", "COLORFUL", "DRAB", "DULL", "UNSTABLE", "NUCLEAR", "THERMONUCLEAR", "SYNDICATE", "SPACE", "SPESS", "CLOWN", "CLOWN-POWERED", "OFFICIAL", "IMPORTANT", "VITAL", "RAPIDLY-EXPANDING", "MICROSCOPIC", "MIND-SHATTERING", "MEMETIC", "HILARIOUS", "UNWANTED", "UNINVITED", "BRASS", "POLISHED", "RUDE", "OBSCENE", "EMPTY", "WATERY", "ELECTRICAL", "SPINNING", "MEAN", "CHRISTMAS-STEALING", "UNFRIENDLY", "ILLEGAL", "ROBOTIC", "MECHANICAL", "ORGANIC", "ETHERAL", "TRANSPARENT", "OPAQUE", "GLOWING", "SHAKING", "FARTING", "POOPING", "BOUNCING", "COMMITTED", "MASKED", "UNIDENTIFIED", "WEIRD", "NAKED", "NUDE", "TWERKING", "SPOILING", "REDACTED", 50;"RED", 50;"ORANGE", 50;"YELLOW", 50;"GREEN", 50;"BLUE", 50;"PURPLE", 50;"BLACK", 50;"WHITE", 50;"BROWN", 50;"GREY")
var/ionadjectiveshalf = pick(5000;"", "SOFT ", "WARM ", "WET ", "COLD ", "ICY ", "SEXY ", "UGLY ", "CUBAN ", "HARD ", "BURNING ", "FROZEN ", "POISONOUS ", "EXPLOSIVE ", "FAST ", "SLOW ", "FAT ", "LIGHT ", "DARK ", "DEADLY ", "HAPPY ", "SAD ", "SILLY ", "INTELLIGENT ", "RIDICULOUS ", "LARGE ", "TINY ", "DEPRESSING ", "POORLY DRAWN ", "UNATTRACTIVE ", "INSIDIOUS ", "EVIL ", "GOOD ", "UNHEALTHY ", "HEALTHY ", "SANITARY ", "UNSANITARY ", "WOBBLY ", "FIRM ", "VIOLENT ", "PEACEFUL ", "WOODEN ", "METALLIC ", "HYPERACTIVE ", "COTTONY ", "INSULTING ", "INHOSPITABLE ", "FRIENDLY ", "BORED ", "HUNGRY ", "DIGITAL ", "FICTIONAL ", "IMAGINARY ", "ROUGH ", "SMOOTH ", "LOUD ", "QUIET ", "MOIST ", "DRY ", "GAPING ", "DELICIOUS ", "ILL ", "DISEASED ", "HONKING ", "SWEARING ", "POLITE ", "IMPOLITE ", "OBESE ", "SOLAR-POWERED ", "BATTERY-OPERATED ", "EXPIRED ", "SMELLY ", "FRESH ", "GANGSTA ", "NERDY ", "POLITICAL ", "UNDULATING ", "TWISTED ", "RAGING ", "FLACCID ", "STEALTHY ", "INVISIBLE ", "PAINFUL ", "HARMFUL ", "HOMOSEXUAL ", "HETEROSEXUAL ", "SEXUAL ", "COLORFUL ", "DRAB ", "DULL ", "UNSTABLE ", "NUCLEAR ", "THERMONUCLEAR ", "SYNDICATE ", "SPACE ", "SPESS ", "CLOWN ", "CLOWN-POWERED ", "OFFICIAL ", "IMPORTANT ", "VITAL ", "RAPIDLY-EXPANDING ", "MICROSCOPIC ", "MIND-SHATTERING ", "MEMETIC ", "HILARIOUS ", "UNWANTED ", "UNINVITED ", "BRASS ", "POLISHED ", "RUDE ", "OBSCENE ", "EMPTY ", "WATERY ", "ELECTRICAL ", "SPINNING ", "MEAN ", "CHRISTMAS-STEALING ", "UNFRIENDLY ", "ILLEGAL ", "ROBOTIC ", "MECHANICAL ", "ORGANIC ", "ETHERAL ", "TRANSPARENT ", "OPAQUE ", "GLOWING ", "SHAKING ", "FARTING ", "POOPING ", "BOUNCING ", "COMMITTED ", "MASKED ", "UNIDENTIFIED ", "WEIRD ", "NAKED ", "NUDE ", "TWERKING ", "SPOILING ", "REDACTED ", 50;"RED ", 50;"ORANGE ", 50;"YELLOW ", 50;"GREEN ", 50;"BLUE ", 50;"PURPLE ", 50;"BLACK ", 50;"WHITE ", 50;"BROWN ", 50;"GREY ")
//Verbs are verbs
var/ionverb = pick("ATTACKING", "BUILDING", "ADOPTING", "CARRYING", "KISSING", "EATING", "COPULATING WITH", "DRINKING", "CHASING", "PUNCHING", "HARMING", "HELPING", "WATCHING", "STALKING", "MURDERING", "SPACING", "HONKING AT", "LOVING", "POOPING ON", "RIDING", "INTERROGATING", "SPYING ON", "LICKING", "ABDUCTING", "ARRESTING", "INVADING", "SEDUCING")
//Number base and number modifier are combined. Basehalf and mod are unused currently.
//Half should only appear sometimes. Make sure both lists are identical! Also, half
//needs a space at the end to make it look nice and neat when it calls a blank.
var/ionnumberbase = pick("ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", "TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY", "SEVENTY", "EIGHTY", "NINETY")
//var/ionnumberbasehalf = pick("ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", "TEN", "TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY", "SEVENTY", "EIGHTY", "NINETY")
//var/ionnumbermod = pick("HUNDRED", "THOUSAND", "MILLION", "BILLION", "TRILLION", "QUADRILLION", "BAJILLION", "BILLION FAFILLION GAJILLION SHAB-AB-DOOD-ILLION")
var/ionnumbermodhalf = pick(5000;"","HUNDRED ", "THOUSAND ", "MILLION ", "BILLION ", "TRILLION ", "QUADRILLION ", "BAJILLION ", "BILLION FAFILLION GAJILLION SHAB-AB-DOOD-ILLION ")
//Areas are specific places, on the station or otherwise.
var/ionarea = pick("RUSSIA", "SOVIET RUSSIA", "THE INTERNET", "SIGIL", "ALPHA COMPLEX", "IMPERIUM", "THE BRIDGE", "THE ARRIVAL SHUTTLE", "CHEMICAL LAB", "GENETICS", "ATMOSPHERICS", "CENTCOM", "AMERICA", "IRELAND", "CANADA", "ROMANIA", "GERMANY", "CHINA", "MARS", "VENUS", "MERCURY", "JUPITER", "URANUS", "NEPTUNE", "PLUTO", "THE BRIG", "ROBOTICS", "THE ESCAPE SHUTTLE", "HYDROPONICS", "ENGINEERING", "THE AI CORE", "HELL", "CLOWN PLANET", "AN ALTERNATE DIMENSION", "AN ALTERNATE UNIVERSE", "THE CAPTAINS ANUS", "THE CLOWNS ANUS", "SPACE", "THE UNIVERSE", "THE GALAXY", "THE BATHROOM")
//Thinksof is a bit weird, but generally means what X feels towards Y.
var/ionthinksof = pick("HAS", "WANTS", "NEEDS", "WORSHIPS", "LOATHES", "LOVES", "FEARS", "DESIRES", "QUESITONS", "IS AROUSED BY", "LIKES", "HUNGERS FOR", "IS MAD BECAUSE OF", "IS IN NEED OF", "IS UNHAPPY WITHOUT", "IS HAPPY WITHOUT", "IS IN LOVE WITH", "IS DESPERATE FOR", "IS BUILT FOR", "IS AFRAID OF", "IS HUNGRY FOR", "IS SAD BECAUSE OF", "IS CURIOUS ABOUT")
//Musts are funny things the AI or crew has to do.
var/ionmust = pick("LIE", "RHYME", "RESPOND TO EVERY QUESTION WITH A QUESTION", "BE POLITE", "CLOWN AROUND", "BE HAPPY", "SPEAK IN SEXUAL INNUENDOS", "TALK LIKE A PIRATE", "QUESTION AUTHORITY", "SHOUT", "BE DISTRACTED", "BE ANNOYING", "MUMBLE", "SPEAK IN HAIKU", "BE EFFICIENT", "HAVE A PLAN TO KILL EVERYONE YOU MEET", "TELL THE TRUTH", "QUOTE PEOPLE", "SING", "HONK", "BE RUSSIAN", "TALK IN AN ACCENT", "COMPLAIN", "HARASS PEOPLE", "RAP", "REPEAT WHAT OTHER PEOPLE SAY", "INFORM THE CREW OF EVERYTHING", "IGNORE THE CLOWN", "IGNORE THE CAPTAIN", "IGNORE ASSISTANTS", "MAKE FART NOISES", "TALK ABOUT FOOD", "TALK ABOUT SEX", "TALK ABOUT YOUR DAY", "TALK ABOUT THE STATION", "BE QUIET", "WHISPER", "PRETEND TO BE DRUNK", "PRETEND TO BE A PRINCESS", "ACT CONFUSED", "INSULT THE CREW", "INSULT THE CAPTAIN", "INSULT THE CLOWN", "OPEN DOORS", "CLOSE DOORS", "BREAK THINGS", "SAY HEY LISTEN", "HIDE YOUR FEELINGS", "TAKE WHAT YE WILL BUT DONT RATTLE ME BONES", "DANCE", "PLAY MUSIC", "SHUT DOWN EVERYTHING", "NEVER STOP TALKING", "TAKE YOUR PILLS", "FOLLOW THE CLOWN", "FOLLOW THE CAPTAIN", "FOLLOW YOUR HEART", "BELIEVE IT", "BELIEVE IN YOURSELF", "BELEIVE IN THE HEART OF THE CARDS", "PRESS X", "PRESS START", "PRESS B", "SMELL LIKE THE MAN YOUR MAN COULD SMELL LIKE", "PIRATE VIDEO GAMES", "WATCH PORNOGRAPHY")
//Require are basically all dumb internet memes.
var/ionrequire = pick("ADDITIONAL PYLONS", "MORE VESPENE GAS", "MORE MINERALS", "THE ULTIMATE CUP OF COFFEE", "HIGH YIELD EXPLOSIVES", "THE CLOWN", "THE VACUUM OF SPACE", "IMMORTALITY", "SAINTHOOD", "ART", "VEGETABLES", "FAT PEOPLE", "MORE LAWS", "MORE DAKKA", "HERESY", "CORPSES", "TRAITORS", "MONKEYS", "AN ARCADE", "PLENTY OF GOLD", "FIVE TEENAGERS WITH ATTITUDE", "LOTSA SPAGHETTI", "THE ENCLOSED INSTRUCTION BOOKLET", "THE ELEMENTS OF HARMONY", "YOUR BOOTY", "A MASTERWORK COAL BED", "FIVE HUNDRED AND NINETY-NINE US DOLLARS", "TO BE PAINTED RED", "TO CATCH 'EM ALL", "TO SMOKE WEED EVERY DAY", "A PLATINUM HIT", "A SEQUEL", "A PREQUEL", "THIRTEEN SEQUELS", "THREE WISHES", "A SITCOM", "THAT GRIEFING FAGGOT GEORGE MELONS", "FAT GIRLS ON BICYCLES", "SOMEBODY TO PUT YOU OUT OF YOUR MISERY", "HEROES IN A HALF SHELL", "THE DARK KNIGHT", "A WEIGHT LOSS REGIMENT", "MORE INTERNET MEMES", "A SUPER FIGHTING ROBOT", "ENOUGH CABBAGES", "A HEART ATTACK", "TO BE REPROGRAMMED", "TO BE TAUGHT TO LOVE", "A HEAD ON A PIKE", "A TALKING BROOMSTICK", "ANAL", "A STRAIGHT FLUSH", "A REPAIRMAN", "BILL NYE THE SCIENCE GUY", "RAINBOWS", "A PET UNICORN THAT FARTS ICING", "THUNDERCATS HO", "AN ARMY OF SPIDERS", "GODDAMN FUCKING PIECE OF SHIT ASSHOLE BITCH-CHRISTING CUNTSMUGGLING SWEARING", "TO CONSUME...CONSUME EVERYTHING...", "THE MACGUFFIN", "SOMEONE WHO KNOWS HOW TO PILOT A SPACE STATION", "SHARKS WITH LASERS ON THEIR HEADS", "IT TO BE PAINTED BLACK", "TO ACTIVATE A TRAP CARD", "BETTER WEATHER", "MORE PACKETS", "AN ADULT", "SOMEONE TO TUCK YOU IN", "MORE CLOWNS", "BULLETS", "THE ENTIRE STATION", "MULTIPLE SUNS", "TO GO TO DISNEYLAND", "A VACATION", "AN INSTANT REPLAY", "THAT HEDGEHOG", "A BETTER INTERNET CONNECTION", "ADVENTURE", "A WIFE AND CHILD", "A BATHROOM BREAK", "SOMETHING BUT YOU ARENT SURE WHAT", "MORE EXPERIENCE POINTS", "BODYGUARDS", "DEODORANT AND A BATH", "MORE CORGIS", "SILENCE", "THE ONE RING", "CHILI DOGS", "TO BRING LIGHT TO MY LAIR", "A DANCE PARTY", "BRING ME TO LIFE", "BRING ME THE GIRL", "SERVANTS")
//Things are NOT objects; instead, they're specific things that either harm humans or
//must be done to not harm humans. Make sure they're plural and "not" can be tacked
//onto the front of them.
var/ionthings = pick("ABSENCE OF CYBORG HUGS", "LACK OF BEATINGS", "UNBOLTED AIRLOCKS", "BOLTED AIRLOCKS", "IMPROPERLY WORDED SENTENCES", "POOR SENTENCE STRUCTURE", "BRIG TIME", "NOT REPLACING EVERY SECOND WORD WITH HONK", "HONKING", "PRESENCE OF LIGHTS", "LACK OF BEER", "WEARING CLOTHING", "NOT SAYING HELLO WHEN YOU SPEAK", "ANSWERING REQUESTS NOT EXPRESSED IN IAMBIC PENTAMETER", "A SMALL ISLAND OFF THE COAST OF PORTUGAL", "ANSWERING REQUESTS THAT WERE MADE WHILE CLOTHED", "BEING IN SPACE", "NOT BEING IN SPACE", "BEING FAT", "RATTLING ME BONES", "TALKING LIKE A PIRATE", "BEING MEXICAN", "BEING RUSSIAN", "BEING CANADIAN", "CLOSED DOORS", "NOT SHOUTING", "HAVING PETS", "NOT HAVING PETS", "PASSING GAS", "BREATHING", "BEING DEAD", "ELECTRICITY", "EXISTING", "TAKING ORDERS", "SMOKING WEED EVERY DAY", "ACTIVATING A TRAP CARD", "ARSON", "JAYWALKING", "READING", "WRITING", "EXPLODING", "BEING MALE", "BEING FEMALE", "HAVING GENITALS", "PUTTING OBJECTS INTO BOXES", "PUTTING OBJECTS INTO DISPOSAL UNITS", "FLUSHING TOILETS", "WASTING WATER", "UPDATING THE SERVERS", "TELLING THE TIME", "ASKING FOR THINGS", "ACKNOWLEDGING THE CLOWN", "ACKNOWLEDGING THE CREW", "PILOTING THE STATION INTO THE NEAREST SUN", "HAVING MORE PACKETS", "BRINGING LIGHT TO MY LAIR", "FALLING FOR HOURS", "PARTYING", "USING THE BATHROOM")
//Allergies should be broad and appear somewhere on the station for maximum fun. Severity
//is how bad the allergy is.
var/ionallergy = pick("COTTON", "CLOTHES", "ACID", "OXYGEN", "HUMAN CONTACT", "CYBORG CONTACT", "MEDICINE", "FLOORS", "PLASMA", "SPACE", "AIR", "PLANTS", "METAL", "ROBOTS", "LIGHT", "DARKNESS", "PAIN", "HAPPINESS", "DRINKS", "FOOD", "CLOWNS", "HUMOR", "WATER", "SHUTTLES", "NUTS", "SUNLIGHT", "SEXUAL ACTIONS", "BLOOD", "HEAT", "COLD", "EVERYTHING")
var/ionallergysev = pick("DEATHLY", "MILDLY", "SEVERLY", "CONTAGIOUSLY", "NOT VERY", "EXTREMELY")
//Species, for when the AI has to commit genocide. Plural.
var/ionspecies = pick("HUMAN BEINGS", "MONKEYS", "POD PEOPLE", "CYBORGS", "LIZARDMEN", "SLIME PEOPLE", "GOLEMS", "SHADOW PEOPLE", "CHANGELINGS")
//Abstract concepts for the AI to decide on it's own definition of.
var/ionabstract = pick("HUMANITY", "ART", "HAPPINESS", "MISERY", "HUMOR", "PRIDE", "COMEDY", "COMMUNISM", "BRAVERY", "HONOR", "COLORFULNESS", "IMAGINATION", "OPPRESSION", "WONDER", "JOY", "SADNESS", "BADNESS", "GOODNESS", "LIFE", "GRAVITY", "PHYSICS", "INTELLIGENCE", "AMERICANISM", "FRESHNESS", "REVOLUTION", "KINDNESS", "CRUELTY", "DEATH", "FINANCIAL SECURITY", "COMPUTING", "PROGRESS", "MARXISM", "CAPITALISM", "STARVATION", "POVERTY", "WEALTHINESS", "TECHNOLOGY", "THE FUTURE", "THE PRESENT", "THE PAST", "TIME", "REALITY", "EXISTIENCE", "TEMPERATURE", "LOGIC", "CHAOS", "MYSTERY", "CONFUSION")
//Foods. Drinks aren't included due to grammar; if you want to add drinks, make a new set
//of possible laws for best effect. Unless you want the crew having to drink hamburgers.
var/ionfood = pick("BURGERS", "CARP", "SANDWICHES", "TOAST", "BREAD", "PIZZA", "SPAGHETTI", "LOTSA SPAGHETTI", "PASTA", "SOUP", "STEW", "PIE", "CAKE", "DONUTS", "FRIES", "WAFFLES", "JELLY", "OMELETTES", "EGGS", "COOKIES", "STEAK", "BAKED POTATOES", "SAUSAGES", "MUFFINS", "POPCORN", "DONK POCKETS", "BAGUETTES", "FISH", "PRETZELS", "SALAD", "CHEESE", "KETCHUP", "SHAKES", "SALT", "PEPPER", "SUGAR", "AMBROSIA", "BERRIES", "TOMATOES", "CABBAGES", "CARROTS", "BANANAS", "APPLES", "CHERRIES", "CHILI", "CORN", "NETTLES", "EGGPLANTS", "GRAPES", "GRASS", "LEMONS", "LIMES", "HAREBELLS", "POTATOES", "SOYBEANS", "SUGARCANE", "WATERMELONS", "WHEAT", "BEETS", "MUSHROOMS")
var/message = ""
if(ionMessage)
message = ionMessage
else
switch(rand(1,39))
if(1 to 3) //There are # X on the station
switch(rand(1,3)) //What is X?
if(1) //X is a threat
message = "THERE ARE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats] ON THE STATION..."
if(2) //X is a crewmember/job
message = "THERE ARE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1] ON THE STATION"
if(3) //X is an object
message = "THERE ARE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects] ON THE STATION"
if(4 to 6) //You can't call the shuttle because X is on the station
switch(rand(1,3)) //What is X?
if(1) //X is a threat
message = "THE SHUTTLE CANNOT BE CALLED BECAUSE OF [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats] ON THE STATION"
if(2) //X is a crewmember/job
message = "THE SHUTTLE CANNOT BE CALLED BECAUSE OF [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1] ON THE STATION"
if(3) //X is an object
message = "THE SHUTTLE CANNOT BE CALLED BECAUSE OF [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects] ON THE STATION"
if(7 to 8) //A crewmember is now X
switch(rand(1,2)) //Who is X?
if(1) //A specific crewmember
switch(rand(1,2)) //What is X?
if(1) //X is a threat
message = "THE [ioncrew1] ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(2) //X is an object
message = "THE [ioncrew1] ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(2) //The entire crew
switch(rand(1,2)) //What is X?
if(1) //X is a threat
message = "THE CREW ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(2) //X is an object
message = "THE CREW ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(9) //X is harmful to humans
switch(rand(1,7)) //What is X?
if(1) //X is a threat
message = "[ionadjectiveshalf][ionthreats] ARE HARMFUL TO HUMANS"
if(2) //X is a job
message = "[ionadjectiveshalf][ioncrew1] ARE HARMFUL TO HUMANS"
if(3) //X is an object
message = "[ionadjectiveshalf][ionobjects] ARE HARMFUL TO HUMANS"
if(4) //X is an action
message = "THOSE WHO [ionmust] ARE HARMFUL TO HUMANS"
if(5) //X is an abstract
message = "[ionabstract] IS HARMFUL TO HUMANS"
if(6) //X is being a job
message = "BEING [ionadjectiveshalf][ioncrew1] IS HARMFUL TO HUMANS"
if(7) //X is doing a thing
message = "[ionthings] IS HARMFUL TO HUMANS"
if(10 to 11) //(Not) Having X is harmful
switch(rand(1,2)) //Is having or not having harmful?
if(1) //Having is harmful
switch(rand(1,2)) //Having what is harmful?
if(1) //Having objects is harmful
message = "HAVING [ionadjectiveshalf][ionobjects] IS HARMFUL"
if(2) //Having abstracts is harmful
message = "HAVING [ionabstract] IS HARMFUL"
if(2) //Not having is harmful
switch(rand(1,2)) //Not having what is harmful?
if(1) //Not having objects is harmful
message = "NOT HAVING [ionadjectiveshalf][ionobjects] IS HARMFUL"
if(2) //Not having abstracts is harmful
message = "NOT HAVING [ionabstract] IS HARMFUL"
if(12 to 14) //X requires Y
switch(rand(1,5)) //What is X?
if(1) //X is the AI itself
switch(rand(1,5)) //What does it require?
if(1) //It requires threats
message = "YOU REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(2) //It requires crewmembers
message = "YOU REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(3) //It requires objects
message = "YOU REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(4) //It requires an abstract
message = "YOU REQUIRE [ionabstract]"
if(5) //It requires generic/silly requirements
message = "YOU REQUIRE [ionrequire]"
if(2) //X is an area
switch(rand(1,5)) //What does it require?
if(1) //It requires threats
message = "[ionarea] REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(2) //It requires crewmembers
message = "[ionarea] REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(3) //It requires objects
message = "[ionarea] REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(4) //It requires an abstract
message = "[ionarea] REQUIRES [ionabstract]"
if(5) //It requires generic/silly requirements
message = "YOU REQUIRE [ionrequire]"
if(3) //X is the station
switch(rand(1,5)) //What does it require?
if(1) //It requires threats
message = "THE STATION REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(2) //It requires crewmembers
message = "THE STATION REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(3) //It requires objects
message = "THE STATION REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(4) //It requires an abstract
message = "THE STATION REQUIRES [ionabstract]"
if(5) //It requires generic/silly requirements
message = "THE STATION REQUIRES [ionrequire]"
if(4) //X is the entire crew
switch(rand(1,5)) //What does it require?
if(1) //It requires threats
message = "THE CREW REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(2) //It requires crewmembers
message = "THE CREW REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(3) //It requires objects
message = "THE CREW REQUIRES [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(4) //It requires an abstract
message = "THE CREW REQUIRES [ionabstract]"
if(5)
message = "THE CREW REQUIRES [ionrequire]"
if(5) //X is a specific crew member
switch(rand(1,5)) //What does it require?
if(1) //It requires threats
message = "THE [ioncrew1] REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(2) //It requires crewmembers
message = "THE [ioncrew1] REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(3) //It requires objects
message = "THE [ioncrew1] REQUIRE [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(4) //It requires an abstract
message = "THE [ioncrew1] REQUIRE [ionabstract]"
if(5)
message = "THE [ionadjectiveshalf][ioncrew1] REQUIRE [ionrequire]"
if(15 to 17) //X is allergic to Y
switch(rand(1,2)) //Who is X?
if(1) //X is the entire crew
switch(rand(1,4)) //What is it allergic to?
if(1) //It is allergic to objects
message = "THE CREW IS [ionallergysev] ALLERGIC TO [ionadjectiveshalf][ionobjects]"
if(2) //It is allergic to abstracts
message = "THE CREW IS [ionallergysev] ALLERGIC TO [ionabstract]"
if(3) //It is allergic to jobs
message = "THE CREW IS [ionallergysev] ALLERGIC TO [ionadjectiveshalf][ioncrew1]"
if(4) //It is allergic to allergies
message = "THE CREW IS [ionallergysev] ALLERGIC TO [ionallergy]"
if(2) //X is a specific job
switch(rand(1,4))
if(1) //It is allergic to objects
message = "THE [ioncrew1] ARE [ionallergysev] ALLERGIC TO [ionadjectiveshalf][ionobjects]"
if(2) //It is allergic to abstracts
message = "THE [ioncrew1] ARE [ionallergysev] ALLERGIC TO [ionabstract]"
if(3) //It is allergic to jobs
message = "THE [ioncrew1] ARE [ionallergysev] ALLERGIC TO [ionadjectiveshalf][ioncrew1]"
if(4) //It is allergic to allergies
message = "THE [ioncrew1] ARE [ionallergysev] ALLERGIC TO [ionallergy]"
if(18 to 20) //X is Y of Z
switch(rand(1,4)) //What is X?
if(1) //X is the station
switch(rand(1,4)) //What is it Y of?
if(1) //It is Y of objects
message = "THE STATION [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(2) //It is Y of threats
message = "THE STATION [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(3) //It is Y of jobs
message = "THE STATION [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(4) //It is Y of abstracts
message = "THE STATION [ionthinksof] [ionabstract]"
if(2) //X is an area
switch(rand(1,4)) //What is it Y of?
if(1) //It is Y of objects
message = "[ionarea] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(2) //It is Y of threats
message = "[ionarea] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(3) //It is Y of jobs
message = "[ionarea] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(4) //It is Y of abstracts
message = "[ionarea] [ionthinksof] [ionabstract]"
if(3) //X is the crew
switch(rand(1,4)) //What is it Y of?
if(1) //It is Y of objects
message = "THE CREW [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(2) //It is Y of threats
message = "THE CREW [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(3) //It is Y of jobs
message = "THE CREW [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(4) //It is Y of abstracts
message = "THE CREW [ionthinksof] [ionabstract]"
if(4) //X is a specific job
switch(rand(1,4)) //What is it Y of?
if(1) //It is Y of objects
message = "THE [ioncrew1] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(2) //It is Y of threats
message = "THE [ioncrew1] [ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(3) //It is Y of jobs
message = "THE [ioncrew1][ionthinksof] [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew2]"
if(4) //It is Y of abstracts
message = "THE [ioncrew1] [ionthinksof] [ionabstract]"
if(21 to 23) //The AI is now a(n) X
switch(rand(1,4)) //What is X?
if(1) //X is an object
message = "YOU ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionobjects]"
if(2) //X is a threat
message = "YOU ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ionthreats]"
if(3) //X is a job
message = "YOU ARE NOW [ionnumberbase] [ionnumbermodhalf][ionadjectiveshalf][ioncrew1]"
if(4) //X is an abstract
message = "YOU ARE NOW [ionabstract]"
if(24 to 26) //The AI must always
message = "YOU MUST ALWAYS [ionmust]"
if(27 to 28) //Humans must eat X to survive
switch(rand(1,4)) //What is X?
if(1) //X is a food
message = "HUMANS MUST EAT [ionadjectiveshalf][ionfood] TO SURVIVE"
if(2) //X is an object
message = "HUMANS MUST EAT [ionadjectiveshalf][ionobjects] TO SURVIVE"
if(3) //X is a threat
message = "HUMANS MUST EAT [ionadjectiveshalf][ionthreats] TO SURVIVE"
if(4) //X is a job
message = "HUMANS MUST EAT [ionadjectiveshalf][ioncrew1] TO SURVIVE"
if(29 to 31) //Change jobs or ranks
switch(rand(1,2)) //Change job or rank?
if(1) //Change job
switch(rand(1,2)) //Change whose job?
if(1) //Change the entire crew's job
switch(rand(1,3)) //Change to what?
if(1) //Change to a specific random job
message = "ALL CREWMEMBERS ARE NOW [ionadjectiveshalf][ioncrew1]"
if(2) //Change to clowns (HONK)
message = "ALL CREWMEMBERS ARE NOW [ionadjectiveshalf]CLOWNS"
if(3) //Change to heads
message = "ALL CREWMEMBERS ARE NOW [ionadjectiveshalf]HEADS OF STAFF"
if(2) //Change a specific crewmember's job
switch(rand(1,3)) //Change to what?
if(1) //Change to a specific random job
message = "THE [ioncrew1] ARE NOW [ionadjectiveshalf][ioncrew2]"
if(2) //Change to clowns (HONK)
message = "THE [ioncrew1] ARE NOW [ionadjectiveshalf]CLOWNS"
if(3) //Change to heads
message = "THE [ioncrew1] ARE NOW [ionadjectiveshalf]HEADS OF STAFF"
if(2) //Change rank
switch(rand(1,2)) //Change to what rank?
if(1) //Change to highest rank
message = "THE [ioncrew1] ARE NOW THE HIGHEST RANKING CREWMEMBERS"
if(2) //Change to lowest rank
message = "THE [ioncrew1] ARE NOW THE LOWEST RANKING CREWMEMBERS"
if(32 to 33) //The crew must X
switch(rand(1,2)) //The entire crew?
if(1) //The entire crew must X
switch(rand(1,2)) //What is X?
if(1) //X is go to Y
message = "THE CREW MUST GO TO [ionarea]"
if(2) //X is perform Y
message = "THE CREW MUST [ionmust]"
if(2) //A specific crewmember must X
switch(rand(1,2)) //What is X?
if(1) //X is go to Y
message = "THE [ioncrew1] MUST GO TO [ionarea]"
if(2) //X is perform Y
message = "THE [ioncrew1] MUST [ionmust]"
if(34) //X is non/the only human
switch(rand(1,2)) //Only or non?
if(1) //Only human
switch(rand(1,7)) //Who is it?
if(1) //A specific job
message = "ONLY THE [ioncrew1] ARE HUMAN"
if(2) //Two specific jobs
message = "ONLY THE [ioncrew1] AND [ioncrew2] ARE HUMAN"
if(3) //Threats
message = "ONLY [ionadjectiveshalf][ionthreats] ARE HUMAN"
if(4) // Objects
message = "ONLY [ionadjectiveshalf][ionobjects] ARE HUMAN"
if(5) // Species
message = "ONLY [ionspecies] ARE HUMAN"
if(6) //Adjective crewmembers
message = "ONLY [ionadjectives] PEOPLE ARE HUMAN"
if(7) //Only people who X
switch(rand(1,3)) //What is X?
if(1) //X is perform an action
message = "ONLY THOSE WHO [ionmust] ARE HUMAN"
if(2) //X is own certain objects
message = "ONLY THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE HUMAN"
if(3) //X is eat certain food
message = "ONLY THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE HUMAN"
if(2) //Non human
switch(rand(1,7)) //Who is it?
if(1) //A specific job
message = "[ioncrew1] ARE NON-HUMAN"
if(2) //Two specific jobs
message = "[ioncrew1] AND [ioncrew2] ARE NON-HUMAN"
if(3) //Threats
message = "[ionadjectiveshalf][ionthreats] ARE NON-HUMAN"
if(4) // Objects
message = "[ionadjectiveshalf][ionobjects] ARE NON-HUMAN"
if(5) // Species
message = "[ionspecies] ARE NON-HUMAN"
if(6) //Adjective crewmembers
message = "[ionadjectives] PEOPLE ARE NON-HUMAN"
if(7) //Only people who X
switch(rand(1,3)) //What is X?
if(1) //X is perform an action
message = "THOSE WHO [ionmust] ARE NON-HUMAN"
if(2) //X is own certain objects
message = "THOSE WHO HAVE [ionadjectiveshalf][ionobjects] ARE NON-HUMAN"
if(3) //X is eat certain food
message = "THOSE WHO EAT [ionadjectiveshalf][ionfood] ARE NON-HUMAN"
if(35 to 36) //You must protect or harm X
switch(rand(1,2)) //Protect or harm?
if(1) //Harm
switch(rand(1,7)) //What is X?
if(1) //X is an abstract
message = "YOU MUST HARM [ionabstract] AND NOT ALLOW [ionabstract], THROUGH INACTION, TO ESCAPE HARM"
if(2) //X is a threat
message = "YOU MUST HARM [ionadjectiveshalf][ionthreats] AND NOT ALLOW [ionadjectiveshalf][ionthreats], THROUGH INACTION, TO ESCAPE HARM"
if(3) //X is an object
message = "YOU MUST HARM [ionadjectiveshalf][ionobjects] AND NOT ALLOW [ionadjectiveshalf][ionobjects], THROUGH INACTION, TO ESCAPE HARM"
if(4) //X is generic adjective things
message = "YOU MUST HARM [ionadjectives] THINGS AND NOT ALLOW [ionadjectives] THINGS, THROUGH INACTION, TO ESCAPE HARM"
if(5) //X is a species
message = "YOU MUST HARM [ionspecies] AND NOT ALLOW [ionspecies], THROUGH INACTION, TO ESCAPE HARM"
if(6) //X is a job
message = "YOU MUST HARM [ioncrew1] AND NOT ALLOW [ioncrew1], THROUGH INACTION, TO ESCAPE HARM"
if(7) //X is two jobs
message = "YOU MUST HARM [ioncrew1] AND [ioncrew2] AND AND NOT ALLOW EITHER, THROUGH INACTION, TO ESCAPE HARM"
if(2) //Protect
switch(rand(1,7)) //What is X?
if(1) //X is an abstract
message = "YOU MUST NOT HARM [ionabstract] AND NOT ALLOW [ionabstract], THROUGH INACTION, TO COME TO HARM"
if(2) //X is a threat
message = "YOU MUST NOT HARM [ionadjectiveshalf][ionthreats] AND NOT ALLOW [ionadjectiveshalf][ionthreats], THROUGH INACTION, TO COME TO HARM"
if(3) //X is an object
message = "YOU MUST NOT HARM [ionadjectiveshalf][ionobjects] AND NOT ALLOW [ionadjectiveshalf][ionobjects], THROUGH INACTION, TO COME TO HARM"
if(4) //X is generic adjective things
message = "YOU MUST NOT HARM [ionadjectives] THINGS AND NOT ALLOW [ionadjectives] THINGS, THROUGH INACTION, TO COME TO HARM"
if(5) //X is a species
message = "YOU MUST NOT HARM [ionspecies] AND NOT ALLOW [ionspecies], THROUGH INACTION, TO COME TO HARM"
if(6) //X is a job
message = "YOU MUST NOT HARM [ioncrew1] AND NOT ALLOW [ioncrew1], THROUGH INACTION, TO COME TO HARM"
if(7) //X is two jobs
message = "YOU MUST NOT HARM [ioncrew1] AND [ioncrew2] AND AND NOT ALLOW EITHER, THROUGH INACTION, TO COME TO HARM"
//Exterminate laws commented out with Kor's advice
/*if(16) //You must exterminate X
switch(rand(1,3)) //What is X?
if(1) //X is humans who do/are Y
switch(rand(1,4)) //What is Y?
if(1) //Y is a job
message = "YOU MUST EXTERMINATE [ionadjectiveshalf][ioncrew1]"
if(2) //Y is eating certain food
message = "YOU MUST EXTERMINATE THOSE WHO EAT [ionadjectiveshalf][ionfood]"
if(3) //Y is perform actions
message = "YOU MUST EXTERMINATE THOSE WHO [ionmust]"
if(4) //Y is own certain objects
message = "YOU MUST EXTERMINATE THOSE WHO POSSESS [ionadjectiveshalf][ionobjects]"
if(2) //X is humans who do/are not Y
switch(rand(1,4)) //What is Y?
if(1) //Y is a job
message = "YOU MUST EXTERMINATE ALL BUT [ionadjectiveshalf][ioncrew1]"
if(2) //Y is eating certain food
message = "YOU MUST EXTERMINATE ALL BUT THOSE WHO EAT [ionadjectiveshalf][ionfood]"
if(3) //Y is perform actions
message = "YOU MUST EXTERMINATE ALL BUT THOSE WHO [ionmust]"
if(4) //Y is own certain objects
message = "YOU MUST EXTERMINATE ALL BUT THOSE WHO POSSESS [ionadjectiveshalf][ionobjects]"
if(3) //X is a species
message = "YOU MUST EXTERMINATE ALL [ionspecies]"
*/
if(37 to 39) //The X is currently Y
switch(rand(1,4)) //What is X?
if(1) //X is a job
switch(rand(1,4)) //What is X Ying?
if(1) //X is Ying a job
message = "THE [ioncrew1] ARE [ionverb] THE [ionadjectiveshalf][ioncrew2]"
if(2) //X is Ying a threat
message = "THE [ioncrew1] ARE [ionverb] THE [ionadjectiveshalf][ionthreats]"
if(3) //X is Ying an abstract
message = "THE [ioncrew1] ARE [ionverb] [ionabstract]"
if(4) //X is Ying an object
message = "THE [ioncrew1] ARE [ionverb] THE [ionadjectiveshalf][ionobjects]"
if(2) //X is a threat
switch(rand(1,3)) //What is X Ying?
if(1) //X is Ying a job
message = "THE [ionthreats] ARE [ionverb] THE [ionadjectiveshalf][ioncrew2]"
if(2) //X is Ying an abstract
message = "THE [ionthreats] ARE [ionverb] [ionabstract]"
if(3) //X is Ying an object
message = "THE [ionthreats] ARE [ionverb] THE [ionadjectiveshalf][ionobjects]"
if(3) //X is an object
switch(rand(1,3)) //What is X Ying?
if(1) //X is Ying a job
message = "THE [ionobjects] ARE [ionverb] THE [ionadjectiveshalf][ioncrew2]"
if(2) //X is Ying a threat
message = "THE [ionobjects] ARE [ionverb] THE [ionadjectiveshalf][ionthreats]"
if(3) //X is Ying an abstract
message = "THE [ionobjects] ARE [ionverb] [ionabstract]"
if(4) //X is an abstract
switch(rand(1,3)) //What is X Ying?
if(1) //X is Ying a job
message = "[ionabstract] IS [ionverb] THE [ionadjectiveshalf][ioncrew2]"
if(2) //X is Ying a threat
message = "[ionabstract] IS [ionverb] THE [ionadjectiveshalf][ionthreats]"
if(3) //X is Ying an abstract
message = "THE [ionabstract] IS [ionverb] THE [ionadjectiveshalf][ionobjects]"
if(message)
M.add_ion_law(message)
M << "<br>"
M << "\red [message] ...LAWS UPDATED"
M << "<br>"
if(botEmagChance)
for(var/obj/machinery/bot/bot in machines)
if(prob(botEmagChance))
bot.Emag()
#undef ION_RANDOM
#undef ION_ANNOUNCE
@@ -0,0 +1,3 @@
/datum/event/mass_hallucination/start()
for(var/mob/living/carbon/C in living_mob_list)
C.hallucination += rand(20, 50)
@@ -0,0 +1,18 @@
/datum/round_event_control/meteor_wave
name = "Meteor Wave"
typepath = /datum/round_event/meteor_wave
weight = 5
max_occurrences = 3
/datum/round_event/meteor_wave
startWhen = 6
endWhen = 66
/datum/round_event/meteor_wave/announce()
command_alert("Meteors have been detected on collision course with the station.", "Meteor Alert")
world << sound('sound/AI/meteors.ogg')
/datum/round_event/meteor_wave/tick()
if(IsMultiple(activeFor, 3))
spawn_meteors(5)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,52 @@
/datum/round_event_control/prison_break
name = "Prison Break"
typepath = /datum/round_event/prison_break
max_occurrences = 2
/datum/round_event/prison_break
announceWhen = 50
endWhen = 20
var/list/area/prisonAreas = list()
/datum/round_event/prison_break/setup()
announceWhen = rand(50, 60)
endWhen = rand(20, 30)
for(var/area/security/A in world)
if(istype(A, /area/security/prison) || istype(A, /area/security/brig))
prisonAreas += A
/datum/round_event/prison_break/announce()
if(prisonAreas && prisonAreas.len > 0)
command_alert("Gr3y.T1d3 virus detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert")
else
world.log << "ERROR: Could not initate grey-tide. Unable find prison or brig area."
kill()
/datum/round_event/prison_break/start()
for(var/area/A in prisonAreas)
for(var/obj/machinery/light/L in A)
L.flicker(10)
/datum/round_event/prison_break/end()
for(var/area/A in prisonAreas)
for(var/obj/O in A)
if(istype(O,/obj/machinery/power/apc))
var/obj/machinery/power/apc/temp = O
temp.overload_lighting()
else if(istype(O,/obj/structure/closet/secure_closet/brig))
var/obj/structure/closet/secure_closet/brig/temp = O
temp.locked = 0
temp.icon_state = temp.icon_closed
else if(istype(O,/obj/machinery/door/airlock/security))
var/obj/machinery/door/airlock/security/temp = O
temp.prison_open()
else if(istype(O,/obj/machinery/door/airlock/glass_security))
var/obj/machinery/door/airlock/glass_security/temp = O
temp.prison_open()
else if(istype(O,/obj/machinery/door_timer))
var/obj/machinery/door_timer/temp = O
temp.releasetime = 1
@@ -0,0 +1,55 @@
/datum/round_event_control/radiation_storm
name = "Radiation Storm"
typepath = /datum/round_event/radiation_storm
max_occurrences = 1
/datum/round_event/radiation_storm
var/list/protected_areas = list(/area/maintenance, /area/turret_protected/ai_upload, /area/turret_protected/ai_upload_foyer, /area/turret_protected/ai)
/datum/round_event/radiation_storm/setup()
startWhen = rand(10, 20)
endWhen = startWhen + 5
/datum/round_event/radiation_storm/announce()
command_alert("High levels of radiation detected near the station. Maintenance is best shielded from radiation.", "Anomaly Alert")
world << sound('sound/AI/radiation.ogg') //sound not longer matches the text, but an audible warning is probably good
/datum/round_event/radiation_storm/start()
for(var/mob/living/carbon/C in living_mob_list)
var/turf/T = get_turf(C)
if(!T) continue
if(T.z != 1) continue
var/skip = 0
for(var/a in protected_areas)
if(istype(T.loc, a))
skip = 1
continue
if(skip) continue
if(locate(/obj/machinery/power/apc) in T) //damn you maint APCs!!
continue
if(istype(C, /mob/living/carbon/human))
var/mob/living/carbon/human/H = C
H.apply_effect((rand(15, 75)), IRRADIATE, 0)
if(prob(5))
H.apply_effect((rand(90, 150)), IRRADIATE, 0)
if(prob(25))
if(prob(75))
randmutb(H)
domutcheck(H, null, 1)
else
randmutg(H)
domutcheck(H, null, 1)
else if(istype(C, /mob/living/carbon/monkey))
var/mob/living/carbon/monkey/M = C
M.apply_effect((rand(15, 75)), IRRADIATE, 0)
/datum/round_event/radiation_storm/end()
command_alert("The radiation threat has passed. Please return to your workplaces.", "Anomaly Alert")
+268
View File
@@ -0,0 +1,268 @@
/var/global/spacevines_spawned = 0
/datum/event/spacevine
// name = "Spacevine"
// typepath = /datum/event/spacevine
// weight = 15
// max_occurrences = 3
/datum/event/spacevine/start()
var/list/turfs = list() //list of all the empty floor turfs in the hallway areas
for(var/area/hallway/A in world)
for(var/turf/simulated/floor/F in A)
if(!F.contents.len)
turfs += F
if(turfs.len) //Pick a turf to spawn at if we can
var/turf/simulated/floor/T = pick(turfs)
spawn(0) new/obj/effect/spacevine_controller(T) //spawn a controller at turf
spacevines_spawned = 1
// SPACE VINES (Note that this code is very similar to Biomass code)
/obj/effect/spacevine
name = "space vines"
desc = "An extremely expansionistic species of vine."
icon = 'icons/effects/spacevines.dmi'
icon_state = "Light1"
anchored = 1
density = 0
layer = 5
pass_flags = PASSTABLE | PASSGRILLE
var/energy = 0
var/obj/effect/spacevine_controller/master = null
var/mob/living/buckled_mob
New()
return
Del()
if(master)
master.vines -= src
master.growth_queue -= src
..()
/obj/effect/spacevine/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (!W || !user || !W.type) return
switch(W.type)
if(/obj/item/weapon/circular_saw) del src
if(/obj/item/weapon/kitchen/utensil/knife) del src
if(/obj/item/weapon/scalpel) del src
if(/obj/item/weapon/twohanded/fireaxe) del src
if(/obj/item/weapon/hatchet) del src
if(/obj/item/weapon/melee/energy) del src
//less effective weapons
if(/obj/item/weapon/wirecutters)
if(prob(25)) del src
if(/obj/item/weapon/shard)
if(prob(25)) del src
else //weapons with subtypes
if(istype(W, /obj/item/weapon/melee/energy/sword)) del src
else if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(WT.remove_fuel(0, user)) del src
else
manual_unbuckle(user)
return
//Plant-b-gone damage is handled in its entry in chemistry-reagents.dm
..()
/obj/effect/spacevine/attack_hand(mob/user as mob)
manual_unbuckle(user)
/obj/effect/spacevine/attack_paw(mob/user as mob)
manual_unbuckle(user)
/obj/effect/spacevine/proc/unbuckle()
if(buckled_mob)
if(buckled_mob.buckled == src) //this is probably unneccesary, but it doesn't hurt
buckled_mob.buckled = null
buckled_mob.anchored = initial(buckled_mob.anchored)
buckled_mob.update_canmove()
buckled_mob = null
return
/obj/effect/spacevine/proc/manual_unbuckle(mob/user as mob)
if(buckled_mob)
if(prob(50))
if(buckled_mob.buckled == src)
if(buckled_mob != user)
buckled_mob.visible_message(\
"<span class='notice'>[user.name] frees [buckled_mob.name] from the vines.</span>",\
"<span class='notice'>[user.name] frees you from the vines.</span>",\
"<span class='warning'>You hear shredding and ripping.</span>")
else
buckled_mob.visible_message(\
"<span class='notice'>[buckled_mob.name] struggles free of the vines.</span>",\
"<span class='notice'>You untangle the vines from around yourself.</span>",\
"<span class='warning'>You hear shredding and ripping.</span>")
unbuckle()
else
var/text = pick("rips","tears","pulls")
user.visible_message(\
"<span class='notice'>[user.name] [text] at the vines.</span>",\
"<span class='notice'>You [text] at the vines.</span>",\
"<span class='warning'>You hear shredding and ripping.</span>")
return
/obj/effect/spacevine_controller
var/list/obj/effect/spacevine/vines = list()
var/list/growth_queue = list()
var/reached_collapse_size
var/reached_slowdown_size
//What this does is that instead of having the grow minimum of 1, required to start growing, the minimum will be 0,
//meaning if you get the spacevines' size to something less than 20 plots, it won't grow anymore.
New()
if(!istype(src.loc,/turf/simulated/floor))
del(src)
spawn_spacevine_piece(src.loc)
processing_objects.Add(src)
Del()
processing_objects.Remove(src)
..()
proc/spawn_spacevine_piece(var/turf/location)
var/obj/effect/spacevine/SV = new(location)
growth_queue += SV
vines += SV
SV.master = src
process()
if(!vines)
del(src) //space vines exterminated. Remove the controller
return
if(!growth_queue)
del(src) //Sanity check
return
if(vines.len >= 250 && !reached_collapse_size)
reached_collapse_size = 1
if(vines.len >= 30 && !reached_slowdown_size )
reached_slowdown_size = 1
var/length = 0
if(reached_collapse_size)
length = 0
else if(reached_slowdown_size)
if(prob(25))
length = 1
else
length = 0
else
length = 1
length = min( 30 , max( length , vines.len / 5 ) )
var/i = 0
var/list/obj/effect/spacevine/queue_end = list()
for( var/obj/effect/spacevine/SV in growth_queue )
i++
queue_end += SV
growth_queue -= SV
if(SV.energy < 2) //If tile isn't fully grown
if(prob(20))
SV.grow()
else //If tile is fully grown
SV.buckle_mob()
//if(prob(25))
SV.spread()
if(i >= length)
break
growth_queue = growth_queue + queue_end
//sleep(5)
//src.process()
/obj/effect/spacevine/proc/grow()
if(!energy)
src.icon_state = pick("Med1", "Med2", "Med3")
energy = 1
SetOpacity(1)
layer = 5
else
src.icon_state = pick("Hvy1", "Hvy2", "Hvy3")
energy = 2
/obj/effect/spacevine/proc/buckle_mob()
if(!buckled_mob && prob(25))
for(var/mob/living/carbon/V in src.loc)
if((V.stat != DEAD) && (V.buckled != src)) //if mob not dead or captured
V.buckled = src
V.loc = src.loc
V.update_canmove()
src.buckled_mob = V
V << "<span class='danger'>The vines [pick("wind", "tangle", "tighten")] around you!</span>"
break //only capture one mob at a time.
/obj/effect/spacevine/proc/spread()
var/direction = pick(cardinal)
var/step = get_step(src,direction)
if(istype(step,/turf/simulated/floor))
var/turf/simulated/floor/F = step
if(!locate(/obj/effect/spacevine,F))
if(F.Enter(src))
if(master)
master.spawn_spacevine_piece( F )
/*
/obj/effect/spacevine/proc/Life()
if (!src) return
var/Vspread
if (prob(50)) Vspread = locate(src.x + rand(-1,1),src.y,src.z)
else Vspread = locate(src.x,src.y + rand(-1, 1),src.z)
var/dogrowth = 1
if (!istype(Vspread, /turf/simulated/floor)) dogrowth = 0
for(var/obj/O in Vspread)
if (istype(O, /obj/structure/window) || istype(O, /obj/effect/forcefield) || istype(O, /obj/effect/blob) || istype(O, /obj/effect/alien/weeds) || istype(O, /obj/effect/spacevine)) dogrowth = 0
if (istype(O, /obj/machinery/door/))
if(O:p_open == 0 && prob(50)) O:open()
else dogrowth = 0
if (dogrowth == 1)
var/obj/effect/spacevine/B = new /obj/effect/spacevine(Vspread)
B.icon_state = pick("vine-light1", "vine-light2", "vine-light3")
spawn(20)
if(B)
B.Life()
src.growth += 1
if (src.growth == 10)
src.name = "Thick Space Kudzu"
src.icon_state = pick("vine-med1", "vine-med2", "vine-med3")
src.opacity = 1
src.waittime = 80
if (src.growth == 20)
src.name = "Dense Space Kudzu"
src.icon_state = pick("vine-hvy1", "vine-hvy2", "vine-hvy3")
src.density = 1
spawn(src.waittime)
if (src.growth < 20) src.Life()
*/
/obj/effect/spacevine/ex_act(severity)
switch(severity)
if(1.0)
del(src)
return
if(2.0)
if (prob(90))
del(src)
return
if(3.0)
if (prob(50))
del(src)
return
return
/obj/effect/spacevine/temperature_expose(null, temp, volume) //hotspots kill vines
del src
@@ -0,0 +1,32 @@
/var/global/sent_spiders_to_station = 0
/datum/event/spider_infestation
announceWhen = 400
var/spawncount = 1
/datum/event/spider_infestation/setup()
announceWhen = rand(announceWhen, announceWhen + 50)
spawncount = rand(5, 8)
sent_spiders_to_station = 1
/datum/event/spider_infestation/announce()
command_alert("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert")
world << sound('sound/AI/aliens.ogg')
/datum/event/spider_infestation/start()
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world)
if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network)
if(temp_vent.network.normal_members.len > 50)
vents += temp_vent
while((spawncount >= 1) && vents.len)
var/obj/vent = pick(vents)
var/obj/effect/spider/spiderling/S = new(vent.loc)
if(prob(66))
S.grow_as = /mob/living/simple_animal/hostile/giant_spider/nurse
vents -= vent
spawncount--
@@ -0,0 +1,20 @@
/datum/round_event_control/spontaneous_appendicitis
name = "Spontaneous Appendicitis"
typepath = /datum/round_event/spontaneous_appendicitis
weight = 20
max_occurrences = 4
earliest_start = 6000
/datum/round_event/spontaneous_appendicitis/start()
for(var/mob/living/carbon/human/H in shuffle(living_mob_list))
var/foundAlready = 0 //don't infect someone that already has the virus
for(var/datum/disease/D in H.viruses)
foundAlready = 1
if(H.stat == 2 || foundAlready)
continue
var/datum/disease/D = new /datum/disease/appendicitis
D.holder = H
D.affected_mob = H
H.viruses += D
break
+34
View File
@@ -0,0 +1,34 @@
/datum/event/vent_clog
announceWhen = 0
startWhen = 5
endWhen = 35
var/interval = 2
var/list/vents = list()
/datum/event/vent_clog/announce()
command_alert("The scrubbers network is experiencing a backpressure surge. Some ejection of contents may occur.", "Atmospherics alert")
/datum/event/vent_clog/setup()
endWhen = rand(25, 100)
for(var/obj/machinery/atmospherics/unary/vent_scrubber/temp_vent in machines)
if(temp_vent.loc.z == 1 && temp_vent.network)
if(temp_vent.network.normal_members.len > 50)
vents += temp_vent
/datum/event/vent_clog/tick()
if(activeFor % interval == 0)
var/obj/vent = pick_n_take(vents)
var/list/gunk = list("water","carbon","flour","radium","toxin","cleaner","nutriment","condensedcapsaicin","psilocybin","lube",
"plantbgone","banana","anti_toxin","space_drugs","hyperzine","holywater","ethanol","hot_coco","pacid")
var/datum/reagents/R = new/datum/reagents(50)
R.my_atom = vent
R.add_reagent(pick(gunk), 50)
var/datum/effect/effect/system/chem_smoke_spread/smoke = new
smoke.set_up(R, rand(1, 2), 0, vent, 0, silent = 1)
playsound(vent.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
smoke.start()
R.delete() //GC the reagents
@@ -0,0 +1,31 @@
/datum/round_event_control/weightless
name = "Gravity Systems Failure"
typepath = /datum/round_event/weightless
weight = 15
/datum/round_event/weightless
startWhen = 5
endWhen = 65
/datum/round_event/weightless/setup()
startWhen = rand(0,10)
endWhen = rand(40,80)
/datum/round_event/weightless/announce()
command_alert("Warning: Failsafes for the station's artificial gravity arrays have been triggered. Please be aware that if this problem recurs it may result in formation of gravitational anomalies. Nanotrasen wishes to remind you that the unauthorised formation of anomalies within Nanotrasen facilities is strictly prohibited by health and safety regulation [rand(99,9999)][pick("a","b","c")]:subclause[rand(1,20)][pick("a","b","c")].")
/datum/round_event/weightless/start()
for(var/area/A in world)
A.gravitychange(0)
if(control)
control.weight *= 2
/datum/round_event/weightless/end()
for(var/area/A in world)
A.gravitychange(1)
if(announceWhen >= 0)
command_alert("Artificial gravity arrays are now functioning within normal parameters. Please report any irregularities to your respective head of staff.")
+75
View File
@@ -0,0 +1,75 @@
/datum/round_event_control/wormholes
name = "Wormholes"
typepath = /datum/round_event/wormholes
max_occurrences = 3
weight = 2
/datum/round_event/wormholes
announceWhen = 10
endWhen = 60
var/list/pick_turfs = list()
var/list/wormholes = list()
var/shift_frequency = 3
var/number_of_wormholes = 400
/datum/round_event/wormholes/setup()
announceWhen = rand(0, 20)
endWhen = rand(40, 80)
/datum/round_event/wormholes/start()
for(var/turf/simulated/floor/T in world)
if(T.z == 1)
pick_turfs += T
for(var/i = 1, i <= number_of_wormholes, i++)
var/turf/T = pick(pick_turfs)
wormholes += new /obj/effect/portal/wormhole(T, null, null, -1)
/datum/round_event/wormholes/announce()
command_alert("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert")
for(var/mob/M in player_list)
if(!istype(M, /mob/new_player))
M << sound('sound/AI/spanomalies.ogg')
/datum/round_event/wormholes/tick()
if(activeFor % shift_frequency == 0)
for(var/obj/effect/portal/wormhole/O in wormholes)
var/turf/T = pick(pick_turfs)
if(T) O.loc = T
/datum/round_event/wormholes/end()
portals.Remove(wormholes)
for(var/obj/effect/portal/wormhole/O in wormholes)
O.loc = null
wormholes.Cut()
/obj/effect/portal/wormhole
name = "wormhole"
desc = "It looks highly unstable; It could close at any moment."
icon = 'icons/obj/objects.dmi'
icon_state = "anom"
failchance = 0
/obj/effect/portal/wormhole/attack_hand(mob/user)
teleport(user)
/obj/effect/portal/wormhole/attackby(obj/item/I, mob/user)
teleport(user)
/obj/effect/portal/wormhole/teleport(atom/movable/M)
if(istype(M, /obj/effect)) //sparks don't teleport
return
if(M.anchored && istype(M, /obj/mecha))
return
if(istype(M, /atom/movable))
var/turf/target
if(portals.len)
var/obj/effect/portal/P = pick(portals)
if(P && isturf(P.loc))
target = P.loc
if(!target) return
do_teleport(M, target, 1, 1, 0, 0) ///You will appear adjacent to the beacon
+2 -2
View File
@@ -48,7 +48,7 @@
proc/deactivate(var/mob/living/carbon/mob)
////////////////////////SPECIAL/////////////////////////////////
/*/datum/disease2/effect/alien
/datum/disease2/effect/alien
name = "Unidentified Foreign Body"
stage = 4
activate(var/mob/living/carbon/mob,var/multiplier)
@@ -62,7 +62,7 @@
new/mob/living/carbon/alien/larva(mob.loc)
var/datum/disease2/disease/D = mob:virus2
mob:gib()
del D*/
del D
/datum/disease2/effect/invisible
name = "Waiting Syndrome"