mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-20 19:44:09 +01:00
Revenant update, event weight tweaks
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#define ASSIGNMENT_SECURITY "Security"
|
||||
|
||||
var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT_LEVEL_MODERATE = "Moderate", EVENT_LEVEL_MAJOR = "Major")
|
||||
var/list/event_last_fired = list()
|
||||
|
||||
/datum/event_container
|
||||
var/severity = -1
|
||||
@@ -134,8 +135,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation",/datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50)),
|
||||
// NON-BAY EVENTS
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Cargo Bonus", /datum/event/cargo_bonus, 100),
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Revenant", /datum/event/revenant, 50)
|
||||
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Cargo Bonus", /datum/event/cargo_bonus, 100)
|
||||
)
|
||||
|
||||
/datum/event_container/moderate
|
||||
@@ -158,7 +158,6 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ion_storm, 0, list(ASSIGNMENT_AI = 50, ASSIGNMENT_CYBORG = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Borer Infestation", /datum/event/borer_infestation, 20, list(ASSIGNMENT_SECURITY = 20), 1),
|
||||
new /datum/event_meta/alien(EVENT_LEVEL_MODERATE, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 15), 1),
|
||||
//new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 15), 1),
|
||||
// NON-BAY EVENTS
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Mass Hallucination", /datum/event/mass_hallucination, 300),
|
||||
@@ -172,6 +171,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Bluespace Anomaly", /datum/event/anomaly/anomaly_bluespace, 50, list(ASSIGNMENT_ENGINEER = 25)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Flux Anomaly", /datum/event/anomaly/anomaly_flux, 50, list(ASSIGNMENT_ENGINEER = 50)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Gravitational Anomaly", /datum/event/anomaly/anomaly_grav, 200),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Revenant", /datum/event/revenant, 150)
|
||||
)
|
||||
|
||||
/datum/event_container/major
|
||||
@@ -183,6 +183,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 30), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 30), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1),
|
||||
new /datum/event_meta/alien(EVENT_LEVEL_MAJOR, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 30), 1),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -1,242 +0,0 @@
|
||||
|
||||
/*
|
||||
/proc/start_events()
|
||||
//changed to a while(1) loop since they are more efficient.
|
||||
//Moved the spawn in here to allow it to be called with advance proc call if it crashes.
|
||||
//and also to stop spawn copying variables from the game ticker
|
||||
spawn(3000)
|
||||
while(1)
|
||||
/*if(prob(50))//Every 120 seconds and prob 50 2-4 weak spacedusts will hit the station
|
||||
spawn(1)
|
||||
dust_swarm("weak")*/
|
||||
if(!event)
|
||||
//CARN: checks to see if random events are enabled.
|
||||
if(config.allow_random_events)
|
||||
hadevent = event()
|
||||
else
|
||||
Holiday_Random_Event()
|
||||
else
|
||||
event = 0
|
||||
sleep(2400)
|
||||
*/
|
||||
|
||||
var/list/event_last_fired = list()
|
||||
|
||||
//Always triggers an event when called, dynamically chooses events based on job population
|
||||
var/global/list/possibleEvents = list()
|
||||
/proc/spawn_dynamic_event()
|
||||
if(!config.allow_random_events)
|
||||
return
|
||||
|
||||
var/minutes_passed = world.time/600
|
||||
|
||||
var/list/active_with_role = number_active_with_role()
|
||||
//var/engineer_count = number_active_with_role("Engineer")
|
||||
//var/security_count = number_active_with_role("Security")
|
||||
//var/medical_count = number_active_with_role("Medical")
|
||||
//var/AI_count = number_active_with_role("AI")
|
||||
//var/janitor_count = number_active_with_role("Janitor")
|
||||
|
||||
// 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
|
||||
|
||||
//see:
|
||||
// Code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events.dm
|
||||
// Code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events_Mundane.dm
|
||||
|
||||
possibleEvents[/datum/event/economic_event] = 300
|
||||
possibleEvents[/datum/event/trivial_news] = 400
|
||||
possibleEvents[/datum/event/mundane_news] = 300
|
||||
|
||||
possibleEvents[/datum/event/cargo_bonus] = 100
|
||||
possibleEvents[/datum/event/revenant] = 75
|
||||
|
||||
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/mass_hallucination] = 200
|
||||
possibleEvents[/datum/event/vent_clog] = 300
|
||||
possibleEvents[/datum/event/anomaly/anomaly_grav] = 200
|
||||
|
||||
possibleEvents[/datum/event/wormholes] = 150
|
||||
|
||||
possibleEvents[/datum/event/carp_migration] = 20 + 10 * active_with_role["Engineer"]
|
||||
possibleEvents[/datum/event/dust] = 50 + 50 * active_with_role["Engineer"]
|
||||
possibleEvents[/datum/event/dust/meaty] = 50 + 50 * active_with_role["Engineer"]
|
||||
|
||||
possibleEvents[/datum/event/rogue_drone] = 5 + 25 * active_with_role["Engineer"] + 25 * active_with_role["Security"]
|
||||
possibleEvents[/datum/event/infestation] = 100 + 100 * active_with_role["Janitor"]
|
||||
|
||||
possibleEvents[/datum/event/communications_blackout] = 50 + 25 * active_with_role["AI"] + active_with_role["Scientist"] * 25
|
||||
possibleEvents[/datum/event/ion_storm] = active_with_role["AI"] * 25 + active_with_role["Cyborg"] * 25 + active_with_role["Engineer"] * 10 + active_with_role["Scientist"] * 5
|
||||
// possibleEvents[/datum/event/grid_check] = 25 + 10 * active_with_role["Engineer"]
|
||||
possibleEvents[/datum/event/electrical_storm] = 15 * active_with_role["Janitor"] + 5 * active_with_role["Engineer"]
|
||||
possibleEvents[/datum/event/wallrot] = 30 * active_with_role["Engineer"] + 50 * active_with_role["Botanist"]
|
||||
possibleEvents[/datum/event/borer_infestation] = 50 + 15 * active_with_role["Security"]
|
||||
|
||||
if(!spacevines_spawned)
|
||||
possibleEvents[/datum/event/spacevine] = 10 + 5 * active_with_role["Engineer"]
|
||||
if(minutes_passed >= 30) // Give engineers time to set up engine
|
||||
possibleEvents[/datum/event/brand_intelligence] = 50 + 25 * active_with_role["Engineer"]
|
||||
possibleEvents[/datum/event/anomaly/anomaly_pyro] = 100 + 60 * active_with_role["Engineer"]
|
||||
possibleEvents[/datum/event/anomaly/anomaly_vortex] = 50 + 25 * active_with_role["Engineer"]
|
||||
possibleEvents[/datum/event/anomaly/anomaly_bluespace] = 50 + 25 * active_with_role["Engineer"]
|
||||
possibleEvents[/datum/event/anomaly/anomaly_flux] = 50 + 50 * active_with_role["Engineer"]
|
||||
|
||||
possibleEvents[/datum/event/meteor_wave] = 10 * active_with_role["Engineer"]
|
||||
possibleEvents[/datum/event/blob] = 10 * active_with_role["Engineer"]
|
||||
|
||||
if(active_with_role["Medical"] > 0)
|
||||
possibleEvents[/datum/event/radiation_storm] = active_with_role["Medical"] * 10
|
||||
possibleEvents[/datum/event/viral_infection] = active_with_role["Medical"] * 10
|
||||
|
||||
possibleEvents[/datum/event/prison_break] = active_with_role["Security"] * 50
|
||||
if(active_with_role["Security"] > 0)
|
||||
if(!sent_spiders_to_station)
|
||||
possibleEvents[/datum/event/spider_infestation] = max(active_with_role["Security"], 5) + 5
|
||||
if(aliens_allowed && !sent_aliens_to_station)
|
||||
possibleEvents[/datum/event/alien_infestation] = max(active_with_role["Security"], 5) + 2.5
|
||||
/*if(!sent_ninja_to_station && toggle_space_ninja)
|
||||
possibleEvents[/datum/event/space_ninja] = max(active_with_role["Security"], 5)*/
|
||||
possibleEvents[/datum/event/tear] = active_with_role["Security"] * 25
|
||||
|
||||
for(var/event_type in event_last_fired) if(possibleEvents[event_type])
|
||||
var/time_passed = world.time - event_last_fired[event_type]
|
||||
var/full_recharge_after = 60 * 60 * 10 * 3 // 3 hours
|
||||
var/weight_modifier = max(0, (full_recharge_after - time_passed) / 300)
|
||||
|
||||
possibleEvents[event_type] = max(possibleEvents[event_type] - weight_modifier, 0)
|
||||
|
||||
var/picked_event = pickweight(possibleEvents)
|
||||
event_last_fired[picked_event] = world.time
|
||||
|
||||
// Debug code below here, very useful for testing so don't delete please.
|
||||
var/debug_message = "Firing random event. "
|
||||
for(var/V in active_with_role)
|
||||
debug_message += "#[V]:[active_with_role[V]] "
|
||||
debug_message += "||| "
|
||||
for(var/V in possibleEvents)
|
||||
debug_message += "[V]:[possibleEvents[V]]"
|
||||
debug_message += "|||Picked:[picked_event]"
|
||||
log_debug(debug_message)
|
||||
|
||||
if(!picked_event)
|
||||
return
|
||||
|
||||
//The event will add itself to the MC's event list
|
||||
//and start working via the constructor.
|
||||
new picked_event
|
||||
|
||||
//moved this to proc/check_event()
|
||||
/*var/chance = possibleEvents[picked_event]
|
||||
var/base_chance = 0.4
|
||||
switch(player_list.len)
|
||||
if(5 to 10)
|
||||
base_chance = 0.6
|
||||
if(11 to 15)
|
||||
base_chance = 0.7
|
||||
if(16 to 20)
|
||||
base_chance = 0.8
|
||||
if(21 to 25)
|
||||
base_chance = 0.9
|
||||
if(26 to 30)
|
||||
base_chance = 1.0
|
||||
if(30 to 100000)
|
||||
base_chance = 1.1
|
||||
|
||||
// Trigger the event based on how likely it currently is.
|
||||
if(!prob(chance * eventchance * base_chance / 100))
|
||||
return 0*/
|
||||
|
||||
/*switch(picked_event)
|
||||
if("Meteor")
|
||||
command_announcement.Announce("Meteors have been detected on collision course with the station.", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg')
|
||||
spawn(100)
|
||||
meteor_wave(10)
|
||||
spawn_meteors()
|
||||
spawn(700)
|
||||
meteor_wave(10)
|
||||
spawn_meteors()
|
||||
if("Space Ninja")
|
||||
//Handled in space_ninja.dm. Doesn't announce arrival, all sneaky-like.
|
||||
space_ninja_arrival()
|
||||
if("Radiation")
|
||||
high_radiation_event()
|
||||
if("Virus")
|
||||
viral_outbreak()
|
||||
if("Alien")
|
||||
alien_infestation()
|
||||
if("Prison Break")
|
||||
prison_break()
|
||||
if("Carp")
|
||||
carp_migration()
|
||||
if("Lights")
|
||||
lightsout(1,2)
|
||||
if("Appendicitis")
|
||||
appendicitis()
|
||||
if("Ion Storm")
|
||||
IonStorm()
|
||||
if("Spacevine")
|
||||
spacevine_infestation()
|
||||
if("Communications")
|
||||
communications_blackout()
|
||||
if("Grid Check")
|
||||
grid_check()
|
||||
if("Meteor")
|
||||
meteor_shower()*/
|
||||
|
||||
return 1
|
||||
|
||||
// Returns how many characters are currently active(not logged out, not AFK for more than 10 minutes)
|
||||
// with a specific role.
|
||||
// Note that this isn't sorted by department, because e.g. having a roboticist shouldn't make meteors spawn.
|
||||
/proc/number_active_with_role()
|
||||
var/list/active_with_role = list()
|
||||
active_with_role["Engineer"] = 0
|
||||
active_with_role["Medical"] = 0
|
||||
active_with_role["Security"] = 0
|
||||
active_with_role["Scientist"] = 0
|
||||
active_with_role["AI"] = 0
|
||||
active_with_role["Cyborg"] = 0
|
||||
active_with_role["Janitor"] = 0
|
||||
active_with_role["Botanist"] = 0
|
||||
active_with_role["Any"] = player_list.len
|
||||
|
||||
for(var/mob/M in player_list)
|
||||
if(!M.mind || !M.client || M.client.inactivity > 10 * 10 * 60) // longer than 10 minutes AFK counts them as inactive
|
||||
continue
|
||||
|
||||
if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "engineering robot module")
|
||||
active_with_role["Engineer"]++
|
||||
if(M.mind.assigned_role in list("Chief Engineer", "Station Engineer"))
|
||||
active_with_role["Engineer"]++
|
||||
|
||||
if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "medical robot module")
|
||||
active_with_role["Medical"]++
|
||||
if(M.mind.assigned_role in list("Chief Medical Officer", "Medical Doctor"))
|
||||
active_with_role["Medical"]++
|
||||
|
||||
if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "security robot module")
|
||||
active_with_role["Security"]++
|
||||
if(M.mind.assigned_role in security_positions)
|
||||
active_with_role["Security"]++
|
||||
|
||||
if(M.mind.assigned_role in list("Research Director", "Scientist"))
|
||||
active_with_role["Scientist"]++
|
||||
|
||||
if(M.mind.assigned_role == "AI")
|
||||
active_with_role["AI"]++
|
||||
|
||||
if(M.mind.assigned_role == "Cyborg")
|
||||
active_with_role["Cyborg"]++
|
||||
|
||||
if(M.mind.assigned_role == "Janitor")
|
||||
active_with_role["Janitor"]++
|
||||
|
||||
if(M.mind.assigned_role == "Botanist")
|
||||
active_with_role["Botanist"]++
|
||||
|
||||
return active_with_role
|
||||
@@ -361,3 +361,54 @@
|
||||
if(P.client)
|
||||
players++
|
||||
return players
|
||||
|
||||
// Returns how many characters are currently active(not logged out, not AFK for more than 10 minutes)
|
||||
// with a specific role.
|
||||
// Note that this isn't sorted by department, because e.g. having a roboticist shouldn't make meteors spawn.
|
||||
/proc/number_active_with_role()
|
||||
var/list/active_with_role = list()
|
||||
active_with_role["Engineer"] = 0
|
||||
active_with_role["Medical"] = 0
|
||||
active_with_role["Security"] = 0
|
||||
active_with_role["Scientist"] = 0
|
||||
active_with_role["AI"] = 0
|
||||
active_with_role["Cyborg"] = 0
|
||||
active_with_role["Janitor"] = 0
|
||||
active_with_role["Botanist"] = 0
|
||||
active_with_role["Any"] = player_list.len
|
||||
|
||||
for(var/mob/M in player_list)
|
||||
if(!M.mind || !M.client || M.client.inactivity > 10 * 10 * 60) // longer than 10 minutes AFK counts them as inactive
|
||||
continue
|
||||
|
||||
if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "engineering robot module")
|
||||
active_with_role["Engineer"]++
|
||||
if(M.mind.assigned_role in list("Chief Engineer", "Station Engineer"))
|
||||
active_with_role["Engineer"]++
|
||||
|
||||
if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "medical robot module")
|
||||
active_with_role["Medical"]++
|
||||
if(M.mind.assigned_role in list("Chief Medical Officer", "Medical Doctor"))
|
||||
active_with_role["Medical"]++
|
||||
|
||||
if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "security robot module")
|
||||
active_with_role["Security"]++
|
||||
if(M.mind.assigned_role in security_positions)
|
||||
active_with_role["Security"]++
|
||||
|
||||
if(M.mind.assigned_role in list("Research Director", "Scientist"))
|
||||
active_with_role["Scientist"]++
|
||||
|
||||
if(M.mind.assigned_role == "AI")
|
||||
active_with_role["AI"]++
|
||||
|
||||
if(M.mind.assigned_role == "Cyborg")
|
||||
active_with_role["Cyborg"]++
|
||||
|
||||
if(M.mind.assigned_role == "Janitor")
|
||||
active_with_role["Janitor"]++
|
||||
|
||||
if(M.mind.assigned_role == "Botanist")
|
||||
active_with_role["Botanist"]++
|
||||
|
||||
return active_with_role
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
endWhen = 1
|
||||
|
||||
/datum/event/falsealarm/announce()
|
||||
var/datum/event/E = pick(possibleEvents)
|
||||
var/datum/event/Event = new E
|
||||
message_admins("False Alarm: [Event]")
|
||||
Event.announce() //just announce it like it's happening
|
||||
Event.kill() //do not process this event - no starts, no ticks, no ends
|
||||
var/weight = pick(EVENT_LEVEL_MUNDANE,EVENT_LEVEL_MUNDANE,EVENT_LEVEL_MUNDANE,EVENT_LEVEL_MODERATE,EVENT_LEVEL_MODERATE,EVENT_LEVEL_MAJOR)
|
||||
var/datum/event_container/container = event_manager.event_containers[weight]
|
||||
var/datum/event/E = container.acquire_event()
|
||||
var/datum/event/Event = new E
|
||||
message_admins("False Alarm: [Event]")
|
||||
Event.announce() //just announce it like it's happening
|
||||
Event.kill() //do not process this event - no starts, no ticks, no ends
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
var/dead = 0
|
||||
unsuitable_atoms_damage = 15
|
||||
unsuitable_atmos_damage = 15
|
||||
faction = list("alien")
|
||||
status_flags = CANPUSH
|
||||
minbodytemp = 0
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
max_co2 = 0
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
unsuitable_atoms_damage = 15
|
||||
unsuitable_atmos_damage = 15
|
||||
faction = list("mining")
|
||||
environment_smash = 2
|
||||
minbodytemp = 0
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
max_co2 = 5
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
unsuitable_atoms_damage = 15
|
||||
unsuitable_atmos_damage = 15
|
||||
speak_emote = list("yarrs")
|
||||
var/corpse = /obj/effect/landmark/mobcorpse/pirate
|
||||
var/weapon1 = /obj/item/weapon/melee/energy/sword/pirate
|
||||
|
||||
@@ -36,4 +36,4 @@
|
||||
maxbodytemp = 370
|
||||
heat_damage_per_tick = 15 //amount of damage applied if animal's body temperature is higher than maxbodytemp
|
||||
cold_damage_per_tick = 10 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp
|
||||
unsuitable_atoms_damage = 10
|
||||
unsuitable_atmos_damage = 10
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
max_co2 = 5
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
unsuitable_atoms_damage = 15
|
||||
unsuitable_atmos_damage = 15
|
||||
faction = list("russian")
|
||||
status_flags = CANPUSH
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
max_co2 = 5
|
||||
min_n2 = 0
|
||||
max_n2 = 0
|
||||
unsuitable_atoms_damage = 15
|
||||
unsuitable_atmos_damage = 15
|
||||
faction = list("syndicate")
|
||||
status_flags = CANPUSH
|
||||
|
||||
|
||||
@@ -12,26 +12,28 @@
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
health = 25
|
||||
maxHealth = 25
|
||||
see_in_dark = 255
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
universal_understand = 1
|
||||
response_help = "passes through"
|
||||
response_disarm = "swings at"
|
||||
response_harm = "punches"
|
||||
unsuitable_atmos_damage = 0
|
||||
minbodytemp = 0
|
||||
maxbodytemp = INFINITY
|
||||
harm_intent_damage = 5
|
||||
speak_emote = list("hisses", "spits", "growls")
|
||||
harm_intent_damage = 0
|
||||
friendly = "touches"
|
||||
status_flags = 0
|
||||
wander = 0
|
||||
density = 0
|
||||
flying = 1
|
||||
anchored = 1
|
||||
|
||||
var/essence = 25 //The resource of revenants. Max health is equal to twice this amount
|
||||
var/essence = 25 //The resource of revenants. Max health is equal to three times this amount
|
||||
var/essence_regen_cap = 25 //The regeneration cap of essence (go figure); regenerates every Life() tick up to this amount.
|
||||
var/essence_regen = 1 //If the revenant regenerates essence or not; 1 for yes, 0 for no
|
||||
var/essence_regenerating = 1 //If the revenant regenerates essence or not; 1 for yes, 0 for no
|
||||
var/essence_regen_amount = 2 //How much essence regenerates
|
||||
var/essence_min = 1 //The minimum amount of essence a revenant can have; by default, it never drops below one
|
||||
var/strikes = 0 //How many times a revenant can die before dying for good
|
||||
var/essence_accumulated = 0 //How much essence the revenant has stolen
|
||||
var/revealed = 0 //If the revenant can take damage from normal sources.
|
||||
var/inhibited = 0 //If the revenant's abilities are blocked by a chaplain's power.
|
||||
|
||||
@@ -39,20 +41,20 @@
|
||||
..()
|
||||
if(essence < essence_min)
|
||||
essence = essence_min
|
||||
if(strikes > 0)
|
||||
strikes--
|
||||
src << "<span class='boldannounce'>Your essence has dropped below critical levels. You barely manage to save yourself - [strikes ? "you can't keep this up!" : "next time, it's death."]</span>"
|
||||
else if(strikes <= 0)
|
||||
Die()
|
||||
maxHealth = essence * 2
|
||||
if(essence_regenerating && !inhibited && essence < essence_regen_cap) //While inhibited, essence will not regenerate
|
||||
essence += essence_regen_amount
|
||||
if(essence > essence_regen_cap)
|
||||
essence = essence_regen_cap
|
||||
maxHealth = essence * 3
|
||||
if(!revealed)
|
||||
health = maxHealth //Heals to full when not revealed
|
||||
if(essence_regen && !inhibited && essence < essence_regen_cap) //While inhibited, essence will not regenerate
|
||||
essence++
|
||||
|
||||
/mob/living/simple_animal/revenant/ex_act(severity)
|
||||
return 1 //Immune to the effects of explosions.
|
||||
|
||||
/mob/living/simple_animal/revenant/blob_act()
|
||||
return 1 //blah blah blobs aren't in tune with the spirit world, or something.
|
||||
|
||||
/mob/living/simple_animal/revenant/ClickOn(var/atom/A, var/params) //Copypaste from ghost code - revenants can't interact with the world directly.
|
||||
if(client.buildmode)
|
||||
build_click(src, client.buildmode, params, A)
|
||||
@@ -83,6 +85,7 @@
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
stat(null, "Current essence: [essence]E")
|
||||
stat(null, "Stolen essence: [essence_accumulated]E")
|
||||
|
||||
/mob/living/simple_animal/revenant/New()
|
||||
..()
|
||||
@@ -99,11 +102,11 @@
|
||||
src << "<b><i>You do not remember anything of your past lives, nor will you remember anything about this one after your death.</i></b>"
|
||||
src << "<b>Be sure to read the wiki page at http://nanotrasen.se/wiki/index.php/Revenant to learn more.</b>"
|
||||
var/datum/objective/revenant/objective = new
|
||||
objective.owner = src
|
||||
objective.owner = src.mind
|
||||
src.mind.objectives += objective
|
||||
src << "<b>Objective #1</b>: [objective.explanation_text]"
|
||||
var/datum/objective/revenantFluff/objective2 = new
|
||||
objective2.owner = src
|
||||
objective2.owner = src.mind
|
||||
src.mind.objectives += objective2
|
||||
src << "<b>Objective #2</b>: [objective2.explanation_text]"
|
||||
ticker.mode.traitors |= src.mind //Necessary for announcing
|
||||
@@ -119,13 +122,11 @@
|
||||
src.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_harvest
|
||||
src.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_transmit
|
||||
src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_light
|
||||
src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenantDefile
|
||||
src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_defile
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/revenant/Die()
|
||||
if(strikes)
|
||||
return 0 //Impossible to die with strikes still active
|
||||
..()
|
||||
src << "<span class='userdanger'><b>NO! No... it's too late, you can feel yourself fading...</b></span>"
|
||||
notransform = 1
|
||||
@@ -145,16 +146,15 @@
|
||||
|
||||
|
||||
/mob/living/simple_animal/revenant/attackby(obj/item/W, mob/living/user, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/weapon/nullrod))
|
||||
visible_message("<span class='warning'>[src] violently flinches!</span>", \
|
||||
"<span class='boldannounce'>The null rod invokes agony in you! You feel your essence draining away!</span>")
|
||||
"<span class='boldannounce'>As the null rod passes through you, you feel your essence draining away!</span>")
|
||||
essence -= 25 //hella effective
|
||||
inhibited = 1
|
||||
spawn(30)
|
||||
inhibited = 0
|
||||
|
||||
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/revenant/proc/castcheck(var/essence_cost)
|
||||
var/mob/living/simple_animal/revenant/user = usr
|
||||
@@ -168,12 +168,10 @@
|
||||
user << "<span class='warning'>You lack the essence to use that ability.</span>"
|
||||
return 0
|
||||
if(user.inhibited)
|
||||
user << "<span class='warning'>Your powers have been suppressed by holy energies!</span>"
|
||||
user << "<span class='warning'>Your powers have been suppressed by nulling energy!</span>"
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/revenant/proc/change_essence_amount(var/essence_amt, var/silent = 0, var/source = null)
|
||||
var/mob/living/simple_animal/revenant/user = usr
|
||||
if(!istype(usr) || !usr)
|
||||
@@ -181,7 +179,10 @@
|
||||
if(user.essence + essence_amt <= 0)
|
||||
return
|
||||
user.essence += essence_amt
|
||||
user.essence = Clamp(user.essence, 0, INFINITY)
|
||||
user.essence = max(0, user.essence)
|
||||
if(essence_amt > 0)
|
||||
user.essence_accumulated += essence_amt
|
||||
user.essence_accumulated = max(0, user.essence_accumulated)
|
||||
if(!silent)
|
||||
if(essence_amt > 0)
|
||||
user << "<span class='notice'>Gained [essence_amt]E from [source].</span>"
|
||||
@@ -189,8 +190,6 @@
|
||||
user << "<span class='danger'>Lost [essence_amt]E from [source].</span>"
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/revenant/proc/reveal(var/time, var/stun)
|
||||
var/mob/living/simple_animal/revenant/R = usr
|
||||
if(!istype(usr) || !usr)
|
||||
@@ -199,20 +198,20 @@
|
||||
R.invisibility = 0
|
||||
if(stun)
|
||||
R.notransform = 1
|
||||
R << "<span class='warning'>You have been revealed [stun ? "and cannot move" : ""].</span>"
|
||||
R << "<span class='warning'>You have been revealed[stun ? " and cannot move" : ""].</span>"
|
||||
spawn(time)
|
||||
R.revealed = 0
|
||||
R.invisibility = INVISIBILITY_OBSERVER
|
||||
if(stun)
|
||||
R.notransform = 0
|
||||
R << "<span class='notice'>You are once more concealed [stun ? "and can move again" : ""].</span>"
|
||||
R << "<span class='notice'>You are once more concealed[stun ? " and can move again" : ""].</span>"
|
||||
|
||||
/datum/objective/revenant
|
||||
var/targetAmount = 100
|
||||
|
||||
/datum/objective/revenant/New()
|
||||
targetAmount = rand(100,200)
|
||||
explanation_text = "Absorb [targetAmount] points of essence."
|
||||
explanation_text = "Absorb [targetAmount] points of essence from humans."
|
||||
..()
|
||||
|
||||
/datum/objective/revenant/check_completion()
|
||||
@@ -221,8 +220,8 @@
|
||||
var/mob/living/simple_animal/revenant/R = owner.current
|
||||
if(!R || R.stat == DEAD)
|
||||
return 0
|
||||
var/essenceAccumulated = R.essence
|
||||
if(essenceAccumulated < targetAmount)
|
||||
var/essence_stolen = R.essence_accumulated
|
||||
if(essence_stolen < targetAmount)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -254,7 +253,7 @@
|
||||
/obj/item/weapon/ectoplasm/revenant/New()
|
||||
..()
|
||||
reforming = 1
|
||||
spawn(1800) //3 minutes
|
||||
spawn(600) //1 minutes
|
||||
if(src && reforming)
|
||||
return reform()
|
||||
if(src && !reforming)
|
||||
@@ -290,7 +289,7 @@
|
||||
/obj/item/weapon/ectoplasm/revenant/proc/reform()
|
||||
if(!reforming || !src)
|
||||
return
|
||||
message_admins("Revenant ectoplasm was left undestroyed for 3 minutes and has reformed into a new revenant.")
|
||||
message_admins("Revenant ectoplasm was left undestroyed for 1 minute and has reformed into a new revenant.")
|
||||
loc = get_turf(src) //In case it's in a backpack or someone's hand
|
||||
visible_message("<span class='boldannounce'>[src] suddenly rises into the air before fading away.</span>")
|
||||
var/mob/living/simple_animal/revenant/R = new(get_turf(src))
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
panel = "Revenant Abilities"
|
||||
charge_max = 100 //Short cooldown
|
||||
clothes_req = 0
|
||||
range = 5
|
||||
range = 1
|
||||
var/essence_drained = 0
|
||||
var/draining
|
||||
var/list/drained_mobs = list() //Cannot harvest the same mob twice
|
||||
@@ -18,22 +18,29 @@
|
||||
spawn(0)
|
||||
if(draining)
|
||||
user << "<span class='warning'>You are already siphoning the essence of a soul!</span>"
|
||||
charge_counter = charge_max
|
||||
return
|
||||
if(target in drained_mobs)
|
||||
user << "<span class='warning'>[target]'s soul is dead and empty.</span>"
|
||||
charge_counter = charge_max
|
||||
return
|
||||
if(target.stat != DEAD)
|
||||
if(!target.stat)
|
||||
user << "<span class='notice'>This being's soul is too strong to harvest.</span>"
|
||||
if(prob(10))
|
||||
target << "You feel as if you are being watched."
|
||||
return
|
||||
draining = 1
|
||||
essence_drained = 1
|
||||
user << "<span class='notice'>You search for the still-living soul of [target].</span>"
|
||||
essence_drained = 2
|
||||
user << "<span class='notice'>You search for the soul of [target].</span>"
|
||||
sleep(10)
|
||||
if(target.ckey)
|
||||
user << "<span class='notice'>Their soul burns with intelligence.</span>"
|
||||
essence_drained += 3
|
||||
essence_drained += 2
|
||||
if(target.stat != DEAD)
|
||||
user << "<span class='notice'>Their soul blazes with life!</span>"
|
||||
essence_drained += 2
|
||||
else
|
||||
user << "<span class='notice'>Their soul is weak and faltering.</span>"
|
||||
sleep(20)
|
||||
switch(essence_drained)
|
||||
if(1 to 2)
|
||||
@@ -50,23 +57,19 @@
|
||||
if(!target.stat)
|
||||
user << "<span class='warning'>They are now powerful enough to fight off your draining.</span>"
|
||||
target << "<span class='boldannounce'>You feel something tugging across your body before subsiding.</span>"
|
||||
user << "<span class='danger'>You begin siphoning essence from [target]'s soul. You can not move while this is happening.</span>"
|
||||
return //hey, wait a minute...
|
||||
user << "<span class='danger'>You begin siphoning essence from [target]'s soul.</span>"
|
||||
if(target.stat != DEAD)
|
||||
target << "<span class='warning'>You feel a horribly unpleasant draining sensation as your grip on life weakens...</span>"
|
||||
user.icon_state = "revenant_draining"
|
||||
user.notransform = 1
|
||||
user.revealed = 1
|
||||
user.invisibility = 0
|
||||
user.reveal(65,1)
|
||||
target.visible_message("<span class='warning'>[target] suddenly rises slightly into the air, their skin turning an ashy gray.</span>")
|
||||
target.Beam(user,icon_state="drain_life",icon='icons/effects/effects.dmi',time=80)
|
||||
target.Beam(user,icon_state="drain_life",icon='icons/effects/effects.dmi',time=60)
|
||||
target.death(0)
|
||||
target.visible_message("<span class='warning'>[target] gently slumps back onto the ground.</span>")
|
||||
user.icon_state = "revenant_idle"
|
||||
user.change_essence_amount(essence_drained * 5, 0, target)
|
||||
user << "<span class='info'>[target]'s soul has been considerably weakened and will yield no more essence for the time being.</span>"
|
||||
user.revealed = 0
|
||||
user.notransform = 0
|
||||
user.invisibility = INVISIBILITY_OBSERVER
|
||||
drained_mobs.Add(target)
|
||||
draining = 0
|
||||
|
||||
@@ -106,25 +109,29 @@
|
||||
|
||||
//Overload Light: Breaks a light that's online and sends out lightning bolts to all nearby people.
|
||||
/obj/effect/proc_holder/spell/aoe_turf/revenant_light
|
||||
name = "Overload Light (25E)"
|
||||
desc = "Directs a large amount of essence into an electrical light, causing an impressive light show."
|
||||
name = "Overload Light (30E)"
|
||||
desc = "Directs a large amount of essence into nearby electrical lights, causing lights to shock those nearby."
|
||||
panel = "Revenant Abilities (Locked)"
|
||||
charge_max = 300
|
||||
charge_max = 200
|
||||
clothes_req = 0
|
||||
range = 1
|
||||
var/locked = 1
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/revenant_light/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
|
||||
if(!user.castcheck(-25))
|
||||
charge_counter = charge_max
|
||||
return
|
||||
if(locked)
|
||||
user << "<span class='info'>You have unlocked Overload Light!</span>"
|
||||
if(!user.castcheck(-30))
|
||||
charge_counter = charge_max
|
||||
return
|
||||
user << "<span class='info'>You have unlocked Overload Lights!</span>"
|
||||
name = "Overload Lights (20E)"
|
||||
panel = "Revenant Abilities"
|
||||
locked = 0
|
||||
range = 5
|
||||
charge_counter = charge_max
|
||||
return
|
||||
if(!user.castcheck(-20))
|
||||
charge_counter = charge_max
|
||||
return
|
||||
for(var/turf/T in targets)
|
||||
spawn(0)
|
||||
for(var/obj/machinery/light/L in T.contents)
|
||||
@@ -132,57 +139,68 @@
|
||||
if(!L.on)
|
||||
return
|
||||
L.visible_message("<span class='warning'><b>\The [L] suddenly flares brightly and begins to spark!</span>")
|
||||
sleep(20)
|
||||
sleep(10)
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(4, 1, L)
|
||||
s.start()
|
||||
sleep(10)
|
||||
for(var/mob/living/M in orange(4, L))
|
||||
if(M == user)
|
||||
return
|
||||
M.Beam(L,icon_state="lightning",icon='icons/effects/effects.dmi',time=5)
|
||||
M.electrocute_act(25, "[L.name]")
|
||||
var/datum/effect/effect/system/spark_spread/z = new /datum/effect/effect/system/spark_spread
|
||||
z.set_up(4, 1, M)
|
||||
z.start()
|
||||
playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1)
|
||||
user.reveal(50, 1)
|
||||
user.reveal(80)
|
||||
|
||||
|
||||
//Defile: Corrupts nearby stuff, unblesses floor tiles.
|
||||
/obj/effect/proc_holder/spell/aoe_turf/revenantDefile
|
||||
name = "Defile (30E)"
|
||||
/obj/effect/proc_holder/spell/aoe_turf/revenant_defile
|
||||
name = "Defile (40E)"
|
||||
desc = "Twists and corrupts certain nearby objects. Also dispels holy auras on floors, but not salt lines."
|
||||
panel = "Revenant Abilities (Locked)"
|
||||
charge_max = 300
|
||||
charge_max = 200
|
||||
clothes_req = 0
|
||||
range = 1
|
||||
var/locked = 1
|
||||
|
||||
/obj/effect/proc_holder/spell/aoe_turf/revenantDefile/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
|
||||
if(!user.castcheck(-30))
|
||||
charge_counter = charge_max
|
||||
return
|
||||
/obj/effect/proc_holder/spell/aoe_turf/revenant_defile/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
|
||||
if(locked)
|
||||
if(!user.castcheck(-40))
|
||||
charge_counter = charge_max
|
||||
return
|
||||
user << "<span class='info'>You have unlocked Defile!</span>"
|
||||
name = "Defile (20E)"
|
||||
panel = "Revenant Abilities"
|
||||
locked = 0
|
||||
range = 4
|
||||
charge_counter = charge_max
|
||||
return
|
||||
if(!user.castcheck(-20))
|
||||
charge_counter = charge_max
|
||||
return
|
||||
for(var/turf/T in targets)
|
||||
spawn(0)
|
||||
if(T.flags & NOJAUNT)
|
||||
T.flags -= NOJAUNT
|
||||
for(var/obj/machinery/bot/secbot/secbot in T.contents) //Not including ED-209
|
||||
secbot.emagged = 2
|
||||
secbot.Emag(null)
|
||||
for(var/obj/machinery/bot/cleanbot/cleanbot in T.contents)
|
||||
cleanbot.emagged = 2
|
||||
cleanbot.Emag(null)
|
||||
for(var/obj/machinery/bot/bot in T.contents)
|
||||
bot.locked = 0
|
||||
bot.open = 1
|
||||
bot.emagged = 2
|
||||
bot.Emag(null)
|
||||
for(var/mob/living/carbon/human/human in T.contents)
|
||||
human << "<span class='warning'>You suddenly feel tired.</span>"
|
||||
human.adjustStaminaLoss(25)
|
||||
human.adjustStaminaLoss(50)
|
||||
for(var/mob/living/silicon/robot/robot in T.contents)
|
||||
robot.visible_message("<span class='warning'>[robot] lets out an alarm!</span>", \
|
||||
"<span class='boldannounce'>01001111 01010110 01000101 01010010 01001100 01001111 01000001 01000100</span>") //Translates to "OVERLOAD"
|
||||
robot << 'sound/misc/interference.ogg'
|
||||
robot.emp_act(2)
|
||||
playsound(robot, 'sound/machines/warning-buzzer.ogg', 50, 1)
|
||||
for(var/obj/structure/window/window in T.contents)
|
||||
window.hit(rand(10,50))
|
||||
window.hit(rand(50,200))
|
||||
for(var/obj/machinery/light/light in T.contents)
|
||||
light.flicker() //spooky
|
||||
user.reveal(30, 1)
|
||||
user.reveal(100)
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
var/max_co2 = 5
|
||||
var/min_n2 = 0
|
||||
var/max_n2 = 0
|
||||
var/unsuitable_atoms_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above
|
||||
var/unsuitable_atmos_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above
|
||||
|
||||
|
||||
//LETTING SIMPLE ANIMALS ATTACK? WHAT COULD GO WRONG. Defaults to zero so Ian can still be cuddly
|
||||
@@ -218,7 +218,7 @@
|
||||
fire_alert = 0
|
||||
|
||||
if(!atmos_suitable)
|
||||
adjustBruteLoss(unsuitable_atoms_damage)
|
||||
adjustBruteLoss(unsuitable_atmos_damage)
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/Bumped(AM as mob|obj)
|
||||
|
||||
Reference in New Issue
Block a user