diff --git a/code/game/objects/effects/fire_blast.dm b/code/game/objects/effects/fire_blast.dm
index e4b8c23835f1..8610ffdb7a00 100644
--- a/code/game/objects/effects/fire_blast.dm
+++ b/code/game/objects/effects/fire_blast.dm
@@ -54,22 +54,7 @@
adjusted_fire_damage = fire_damage * 0.25
spawn()
- if(spread && current_step >= spread_start && blast_age < 4)
- var/turf/TS = get_turf(src)
- for(var/turf/TU in range(1, TS))
- if(TU != get_turf(src))
- var/tilehasfire = 0
- var/obstructed = 0
- for(var/obj/effect/E in TU)
- if(istype(E, /obj/effect/fire_blast))
- tilehasfire = 1
- for(var/obj/machinery/door/D in TU)
- if(istype(D, /obj/machinery/door/airlock) || istype(D, /obj/machinery/door/mineral))
- if(D.density)
- obstructed = 1
- if(prob(spread_chance) && TS.Adjacent(TU) && !TU.density && !tilehasfire && !obstructed)
- new type(TU, fire_damage, current_step, blast_age+1, pressure, blast_temperature, duration)
- sleep(1)
+ blast_spread(current_step, pressure, blast_temperature)
spawn()
while(world.time < began_life + duration)
@@ -115,6 +100,24 @@
else
L.adjustFireLoss(adjusted_fire_damage)
+/obj/effect/fire_blast/proc/blast_spread(current_step, pressure, blast_temperature)
+ if(spread && current_step >= spread_start && blast_age < 4)
+ var/turf/TS = get_turf(src)
+ for(var/turf/TU in range(1, TS))
+ if(TU != get_turf(src))
+ var/tilehasfire = 0
+ var/obstructed = 0
+ for(var/obj/effect/E in TU)
+ if(istype(E, /obj/effect/fire_blast))
+ tilehasfire = 1
+ for(var/obj/machinery/door/D in TU)
+ if(istype(D, /obj/machinery/door/airlock) || istype(D, /obj/machinery/door/mineral))
+ if(D.density)
+ obstructed = 1
+ if(prob(spread_chance) && TS.Adjacent(TU) && !TU.density && !tilehasfire && !obstructed)
+ new type(TU, fire_damage, current_step, blast_age+1, pressure, blast_temperature, duration)
+ sleep(1)
+
/obj/effect/fire_blast/dragonbreath/burn_mob(mob/living/L, var/adjusted_fire_damage, var/origin)
if(L.mutations.Find(M_RESIST_HEAT)) //Heat resistance protects you from fear
return ..()
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 8aab4a955c5f..0b831dad1e0e 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -1658,3 +1658,69 @@ var/alien_ship_location = 1 // 0 = base , 1 = mine
dat += "
"
usr << browse(HTML_SKELETON(dat), "window=rodswindow;size=350x300")
+
+/datum/admins/proc/beasts_panel()
+
+ var/dat = {"
+
+ Megabeast Panel
+
+
+
+ Megabeast Panel
+
+
+
+ "}
+
+ usr << browse(HTML_SKELETON(dat), "window=beastspanel;size=840x450")
+
+/datum/admins/proc/create_megabeast(var/datum/procedural_mobspawn/add_template)
+ if(!add_template)
+ new /datum/procedural_mobspawn()
+ return
+ new /mob/living/simple_animal/hostile/forgotten_beast(get_turf(usr), add_template)
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 27f0e2d08030..2742612ad9c3 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -89,8 +89,9 @@ var/list/admin_verbs_admin = list(
/client/proc/body_archive_panel,
/client/proc/climate_panel,
/datum/admins/proc/ashInvokedEmotions, /*Ashes all paper from the invoke emotion spell. An emergency purge.*/
- /client/proc/toggle_admin_examine
-)
+ /client/proc/toggle_admin_examine,
+ /client/proc/beasts_panel /* Lists all forgotten beasts generated, along with their characteristics */
+ )
var/list/admin_verbs_ban = list(
/client/proc/unban_panel,
/client/proc/jobbans,
@@ -1428,3 +1429,11 @@ fieldset {width:140px;}
to_chat(usr, "You toggle [holder.admin_examine ? "on" : "off"] admin examining.")
feedback_add_details("admin_verb","admin_examine")
return
+
+/client/proc/beasts_panel()
+ set name = "Megabeast Panel"
+ set category = "Admin"
+ if(holder)
+ holder.beasts_panel()
+ log_admin("[key_name(usr)] checked the Megabeast Panel.")
+ feedback_add_details("admin_verb","BST")
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index c6202d3c909c..767afeec41d9 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -3234,6 +3234,12 @@
return
return create_mob(usr)
+ else if(href_list["create_megabeast"])
+ if(!check_rights(0))
+ return
+ var/datum/D = locate(href_list["create_megabeast"])
+ return create_megabeast(D)
+
else if(href_list["object_list"]) //this is the laggiest thing ever
if(!check_rights(R_SPAWN))
return
diff --git a/code/modules/mob/living/simple_animal/hostile/megabeast.dm b/code/modules/mob/living/simple_animal/hostile/megabeast.dm
new file mode 100644
index 000000000000..a74b5589c399
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/megabeast.dm
@@ -0,0 +1,156 @@
+/obj/effect/landmark/procedural_mobspawn/forgottenbeast
+ name = "forgotten beast spawner"
+ desc = "You shouldn't be seeing this"
+ icon = 'icons/mob/screen1.dmi'
+ icon_state = "x2"
+ var/mob/living/simple_animal/hostile/mobtype
+
+/obj/effect/landmark/procedural_mobspawn/forgottenbeast/New()
+ SpawnMob(mobtype)
+
+/obj/effect/landmark/procedural_mobspawn/forgottenbeast/proc/SpawnMob()
+ new /mob/living/simple_animal/hostile/forgotten_beast(get_turf(src), new /datum/procedural_mobspawn(mobtype))
+ qdel(src)
+
+/*
+//Megabeast Template
+//Basic beast template.
+//Arguments: loc for spawn location
+//(optional) add_template for a pre-chosen procgen datum to template off of. If none is provided, it will pick one at random from the existing list. If none exist, it will make one.
+//
+//refer to procedural_mobspawn for the datums
+*/
+/mob/living/simple_animal/hostile/forgotten_beast
+ name = "Forgotten Beast"
+ desc = "Some indescribable horror."
+ health = 1000
+ maxHealth = 1000
+ icon = 'icons/mob/animal.dmi'
+ icon_state = "otherthing"
+ icon_dead = "otherthing-dead"
+ attack_sound = 'sound/weapons/heavysmash.ogg'
+ faction = "megabeast"
+ min_oxy = 0
+ max_oxy = 0
+ min_tox = 0
+ max_tox = 0
+ min_co2 = 0
+ max_co2 = 0
+ min_n2 = 0
+ max_n2 = 0
+ environment_smash_flags = SMASH_LIGHT_STRUCTURES | SMASH_CONTAINERS | SMASH_WALLS
+ size = SIZE_HUGE
+ a_intent = I_HURT
+ var/picked
+ var/mob/living/simple_animal/hostile/mymob
+ var/list/mob_types
+ var/list/breath_types = list()
+ var/datum/reagent/vapors
+ var/radioactive
+ var/pulse_cooldown = 0
+ var/special_cooldown
+ var/breath_damage = 10
+ var/breath_damage_type = BRUTE
+ var/datum/custom_breath/mybreath
+ var/datum/procedural_mobspawn/template
+ var/obj/loot
+ var/loot_count
+
+/mob/living/simple_animal/hostile/forgotten_beast/Life()
+ ..()
+ if(radioactive)
+ if(world.time > pulse_cooldown +20 SECONDS)
+ rad_blast()
+ if(vapors)
+ if(world.time > pulse_cooldown +60 SECONDS)
+ GasAttack()
+
+/mob/living/simple_animal/hostile/forgotten_beast/death(var/gibbed = FALSE)
+ if(!gibbed)
+ gib()
+ return
+ for(var/i = loot_count; i > 0)
+ new loot(get_turf(src))
+ --i
+ gibs(loc)
+ ..()
+
+/mob/living/simple_animal/hostile/forgotten_beast/OpenFire(target)
+ if(!mybreath)
+ return ..()
+ if(prob(70))
+ BreathAttack(target)
+ return
+ if(!projectiletype)
+ return
+ ..()
+
+/mob/living/simple_animal/hostile/forgotten_beast/New(loc, var/datum/procedural_mobspawn/add_template)
+ appearance_flags |= PIXEL_SCALE
+ if(!add_template) //no template provided
+ if(!procgen_mob_datums.len) //if no pre-generated templates available...
+ add_template = new /datum/procedural_mobspawn/ //generating a new one will add it to the list automatically
+ else
+ add_template = pick(procgen_mob_datums)
+ template = add_template
+ meat_type = pick(typesof(/obj/item/weapon/reagent_containers/food/snacks/meat))
+
+ name = template.name
+ health = template.health
+ maxHealth = template.maxHealth
+ desc = template.desc
+ icon = template.icon
+ icon_state = template.icon_state
+ icon_dead = template.icon_dead
+ pixel_x = template.pixel_x
+ pixel_y = template.pixel_y
+ melee_damage_lower = template.melee_damage_lower
+ melee_damage_upper = template.melee_damage_upper
+ mybreath = template.mybreath
+ ranged = template.ranged
+ rapid = template.rapid
+ projectiletype = template.projectiletype
+ move_to_delay = template.move_to_delay
+ color = template.color
+ transform = template.size_matrix
+ radioactive = template.radioactive
+ vapors = template.vapors
+ loot = template.randomloot[1]
+ loot_count = template.randomloot[2]
+ ..()
+
+/mob/living/simple_animal/hostile/forgotten_beast/proc/BreathAttack(atom/A = target)
+ if(world.time < (special_cooldown + 10 SECONDS))
+ return
+ var/obj/item/projectile/custom_breath/thebreath = new /obj/item/projectile/custom_breath(src)
+ thebreath.name = mybreath.name//find a better way to do this
+ thebreath.damage = mybreath.damage
+ thebreath.color = mybreath.color
+ thebreath.damage_type = mybreath.damage_type
+ thebreath.pressure = mybreath.pressure
+ thebreath.temperature = mybreath.temperature
+ thebreath.special = mybreath.special
+ thebreath.reagent_type = mybreath.reagent_type
+ generic_projectile_fire(get_ranged_target_turf(src, dir, 10), src, thebreath, 'sound/weapons/flamethrower.ogg', src)
+ special_cooldown = world.time
+
+/mob/living/simple_animal/hostile/forgotten_beast/proc/GasAttack()
+ playsound(get_turf(src), 'sound/effects/smoke.ogg', 50, FALSE, 8)
+ // Create the reagents to put into the air
+ reagents.add_reagent(vapors.id, 100)
+ var/datum/chemical_reaction/chemsmoke/CS = new()
+ CS.on_reaction(src.reagents)
+ pulse_cooldown = world.time
+
+/mob/living/simple_animal/hostile/forgotten_beast/proc/rad_blast()//copied from glowing ones, does not require radiation
+ if(prob(30))
+ visible_message("\The [src] glows with a brilliant light!")
+ set_light(vision_range/2, vision_range, "#a1d68b")
+ spawn(1 SECONDS)
+ emitted_harvestable_radiation(get_turf(src), rand(250, 500), range = 7)
+
+ for(var/mob/living/carbon/human/H in view(src, vision_range))
+ H.apply_radiation(15, RAD_EXTERNAL)
+ pulse_cooldown = world.time
+ spawn(3 SECONDS)
+ set_light(1, 2, "#5dca31")
diff --git a/code/modules/mob/procedural_mobspawn.dm b/code/modules/mob/procedural_mobspawn.dm
new file mode 100644
index 000000000000..ffb0672e0c3a
--- /dev/null
+++ b/code/modules/mob/procedural_mobspawn.dm
@@ -0,0 +1,361 @@
+
+//Global list of generated hostile mobs. Utilize these lists in future panels to look up what mobs this system has generated.
+var/list/procgen_mob_datums = list()
+var/list/megabeast_datums = list() //example of super generated ones
+
+//Global lists for general useful mob data
+var/list/breath_list = list(
+ list("steam breath", BURN, "WHITE", list("CHEM"), /datum/reagent/water),
+ list("firey breath", BURN, "#FFAC1C", list("IGNITE")),
+ list("plasmafire breath", BURN, "#844A97", list("PLASMA", "IGNITE")),
+ list("dark flame", BURN, "#000066", list("IGNITE")),
+ list("acidic spray", TOXIN, "GREEN", list("CHEM"),/datum/reagent/pacid),
+ list("toxic breath", TOXIN, "YELLOW", list("CHEM"), /datum/reagent/toxin),
+ list("mysterious sludge", TOXIN, "#5E02F8", list("CHEM"), /datum/reagent/phazon),
+ list("petrifying breath", BRUTE, "GREY", list("CHEM"), /datum/reagent/petritricin),
+ list("plasma dust", BRUTE,"#733B97", list("PLASMA", "COUGH")),
+ list("radioactive dust", BRUTE, "YELLOW", list("RADIATION", "COUGH")),
+ list("dust cloud", BRUTE,"GREY", list("PUSH", "COUGH")),
+ list("sand breath", BRUTE,"#EOE8C5", list("PUSH", "BLIND")),
+ list("water cannon", BRUTE,"#DEF7F5", list("PUSH", "CHEM"), /datum/reagent/water),
+ list("booze blast", BRUTE,"#664300", list("PUSH", "CHEM"), /datum/reagent/ethanol),
+ list("color spray", BRUTE,"#DEF7F5", list("PUSH", "CHEM"), /datum/reagent/colorful_reagent)
+ )
+var/list/appendage_modifier = list(
+ "gaunt",
+ "pale",
+ "rusty",
+ "molten",
+ "scorched",
+ "thin",
+ "ugly",
+ "translucent",
+ "warty",
+ "mutated",
+ "twisted",
+ "hairy",
+ "feathery",
+ "tentacled",
+ )
+var/list/procgen_loot = list(//path, # of items
+ list(/obj/item/weapon/gun/energy/bison/alien, 1) = 100,//guns
+ list(/obj/item/weapon/gun/energy/laser/captain, 1) = 100,
+ list(/obj/item/weapon/gun/projectile/roulette_revolver, 2) = 100,
+ list(/obj/item/weapon/gun/energy/laser/captain/alien, 2) = 50,
+ list(/obj/item/weapon/gun/gravitywell, 1) = 50,
+ list(/obj/item/weapon/gun/portalgun, 1) = 50,
+ list(/obj/item/stack/sheet/mineral/clown, 20) = 200,//sheets
+ list(/obj/item/stack/sheet/mineral/adamantine, 5) = 200,
+ list(/obj/item/stack/sheet/mineral/phazon, 5) = 100,
+ list(/obj/machinery/sleeper/mancrowave/galo, 1) = 50,//machines
+ list(/obj/machinery/chem_dispenser/scp_294, 1) = 10,
+ list(/obj/mecha/combat/durand/old, 1) = 10,//mechs
+ list(/obj/mecha/combat/phazon, 1) = 5,
+ list(/obj/mecha/medical/odysseus/murdysseus, 1) = 5,
+ list(/obj/item/weapon/storage/box/syndie_kit/mech_killdozer, 1) = 5,//syndie packs
+ list(/obj/item/weapon/storage/box/syndie_kit/emags_and_glue/, 1) = 25,
+ list(/obj/item/clothing/accessory/medal/participation, 1) = 10,//trash
+ list(/obj/item/weapon/paper/iou, 1) = 10
+ )
+
+/*
+//PROC GENNED MEGABEASTS
+//Datum that stores generated data for a procgenned mob. You can spawn a mob by TODO picking a datum from the above global list and calling a .gen_monster(location)
+//
+//big break
+*/
+/datum/procedural_mobspawn
+ var/name = "Forgotten Beast"
+ var/mob/living/simple_animal/hostile/mymob
+ var/health
+ var/maxHealth
+ var/desc
+ var/icon
+ var/icon_state
+ var/icon_dead
+ var/pixel_x
+ var/pixel_y
+ var/melee_damage_lower
+ var/melee_damage_upper
+ var/ranged
+ var/rapid
+ var/obj/item/projectile/projectiletype
+ var/move_to_delay
+ var/matrix/size_matrix
+ var/color
+ var/radioactive
+ var/datum/reagent/vapors
+ var/rad_cooldown
+ var/special_cooldown
+ var/breath_string
+ var/breath_damage
+ var/breath_damage_type
+ var/datum/custom_breath/mybreath
+ var/datum/reagent/mypoison
+ var/list/appendage_types = list(
+ "head",
+ "eye",
+ "mouth",
+ "arm",
+ "leg",
+ "tail",
+ "wing",
+ )
+ var/list/randomloot
+
+//Generate datum variables on creation
+/datum/procedural_mobspawn/New(var/mob/living/simple_animal/hostile/mobtype)
+ PickMob(mobtype)
+ if(!ranged)
+ if(prob(30))
+ PickProjectile()
+ else
+ PickBreath()
+ //When finished, add self to the global list of generated mobs for future reference
+ procgen_mob_datums += src
+
+//Assign general mob data
+/datum/procedural_mobspawn/proc/PickMob(var/mob/living/simple_animal/hostile/mobtype)
+ mymob = mobtype
+ if(!mymob)
+ var/list/mob_types = existing_typesof(/mob/living/simple_animal/hostile)
+ mymob = pick(mob_types)
+ health = clamp((mymob.health * 10), 100, 1000)
+ maxHealth = clamp((mymob.maxHealth * 10), 100, 1000)
+ GenerateDesc()
+ if(prob(90))
+ AddFlavorText()
+ if(prob(50))
+ AddFlavorText(TRUE)
+ icon = mymob.icon
+ icon_state = mymob.icon_state
+ icon_dead = mymob.icon_dead
+ pixel_x = mymob.pixel_x
+ pixel_y = mymob.pixel_y
+ melee_damage_lower = clamp((mymob.melee_damage_lower * 2), 15, 60)
+ melee_damage_upper = clamp((mymob.melee_damage_upper * 2), 35, 80)
+ breath_damage = clamp(rand(15), 5, 15)
+ if(mymob.projectiletype)
+ ranged = TRUE
+ rapid = mymob.rapid
+ projectiletype = mymob.projectiletype
+ var/obj/item/projectile/P = projectiletype
+ desc += " Beware of its deadly [P.name]s!"
+ var/scaling_x = rand(1.5, 2)
+ var/scaling_y = rand(1.5, 2)
+ move_to_delay = mymob.move_to_delay
+ size_matrix = matrix()
+ size_matrix.Scale(scaling_x, scaling_y)
+ randomloot = pickweight(procgen_loot)
+ if(prob(33))
+ color = rgb(rand(0, 255), rand(0, 255), rand(0, 255))
+ if(prob(10))
+ radioactive = TRUE
+ desc += " It has a spooky green glow around it!"
+ else if(prob(20))
+ PickVapors()
+
+/datum/procedural_mobspawn/proc/GenerateDesc()//can be done much better
+ var/list/mydesc = list(
+ "A great [mymob.name].",
+ "An abominable [mymob.name].",
+ "An enormous [mymob.name].",
+ )
+ desc = pick(mydesc)
+
+/datum/procedural_mobspawn/proc/AddFlavorText(randompart = FALSE)
+ var/modifier = pick(appendage_modifier)
+ if(randompart)
+ var/appendage = pick(appendage_types)
+ appendage_types -= appendage
+ var/number = roll(1, 10)
+ var/amount = num2text(number)
+ desc += " Its [amount] [appendage][number <= 1 ? " is" : "s are"] [modifier]."
+ return
+ desc += " It is [modifier]."
+
+/datum/procedural_mobspawn/proc/PickProjectile()
+ ranged = TRUE
+ if(prob(20))
+ projectiletype = /obj/item/projectile/web
+ desc += " Beware of its webs!"
+ return
+ var/list/available_projectiles = existing_typesof(/obj/item/projectile) - restricted_roulette_projectiles
+ for(var/type in restrict_with_subtypes)
+ for(var/subtype in subtypesof(type))
+ available_projectiles -= subtype
+ available_projectiles -= type
+ var/obj/item/projectile/P = pick(available_projectiles)
+ if(!P.name)
+ PickProjectile()
+ return
+ projectiletype = P
+ desc += " Beware of its deadly [P.name]s!"//needs some variation
+
+/datum/procedural_mobspawn/proc/PickBreath()
+ var/list/breath_type = pick(breath_list)
+ if(breath_type.len < 4)
+ return
+ ranged = TRUE
+ breath_string = breath_type[1]
+ breath_damage_type = breath_type[2]
+ mybreath = new()
+ mybreath.name = breath_string
+ mybreath.color = breath_type[3]
+ mybreath.special = breath_type[4]//this is a list
+ mybreath.damage = breath_damage
+ if(length(breath_type)>= 5)
+ mybreath.reagent_type = breath_type[5]
+ desc += " Beware its deadly [breath_string]!"
+ switch(breath_damage_type)
+ if(BRUTE)
+ mybreath.damage_type = BRUTE
+ if(TOXIN)
+ mybreath.damage_type = TOX
+
+/datum/procedural_mobspawn/proc/PickVapors()
+ var/list/all_reagents = subtypesof(/datum/reagent)
+ var/vapornoun = pick("vapors", "gas", "smoke", "mist", "fog", "clouds")
+ vapors = pick(all_reagents)
+ desc += (" Beware its deadly [vapors.name] [vapornoun]!")
+
+/datum/procedural_mobspawn/proc/gen_monster(var/target)
+ new /mob/living/simple_animal/hostile/forgotten_beast(target, src)
+
+/datum/procedural_mobspawn/megabeast
+//Alternative, more dangerous procs. You can replace PickMob() and other such procs in this datum and use it for your more powerful stuff.
+
+/*
+//Accessory datums and functions used in forgotten beasts
+*/
+
+/datum/custom_breath
+ var/name = ""
+ var/damage = 0
+ var/color = "#FFAC1C"
+ var/damage_type = BURN
+ var/pressure = ONE_ATMOSPHERE * 4.5
+ var/temperature = T0C + 175
+ var/special
+ var/datum/reagent/reagent_type
+
+/obj/item/projectile/custom_breath
+ name = "fiery breath"
+ icon_state = ""
+ damage = 0
+ penetration = -1
+ phase_type = PROJREACT_MOBS|PROJREACT_BLOB|PROJREACT_OBJS
+ bounce_sound = null
+ custom_impact = 1
+ penetration_message = 0
+ grillepasschance = 100
+ color = "#FFAC1C"
+
+ var/stepped_range = 0
+ var/max_range = 9
+ var/pressure = ONE_ATMOSPHERE * 4.5
+ var/temperature = T0C + 175
+ var/fire_duration
+ var/special
+ var/datum/reagent/reagent_type
+
+/obj/item/projectile/custom_breath/New(turf/T, var/direction, var/Dam, var/P, var/Temp, var/F_Dur)
+ ..(T,direction)
+ if(damage)
+ damage = Dam
+ if(P)
+ pressure = P
+ if(Temp)
+ temperature = Temp
+ if(F_Dur)
+ fire_duration = F_Dur
+
+/obj/item/projectile/custom_breath/process_step()
+ ..()
+ if(stepped_range <= max_range)
+ stepped_range++
+ else
+ bullet_die()
+ return
+ var/turf/T = get_turf(src)
+ if(!T)
+ return
+ var/obj/effect/fire_blast/custom/F = new(T, damage, stepped_range, 1, pressure, temperature, fire_duration)
+ F.color = color
+ F.damage_type = damage_type
+ F.special = special
+ F.reagent_type = reagent_type
+
+/obj/effect/fire_blast/custom
+ icon_state = "key1"
+ spread_chance = 100
+ var/damage_type = BURN
+ var/damage = 10
+ var/special
+ var/datum/reagent/reagent_type
+
+/obj/effect/fire_blast/custom/New(atom/A, var/damage = 0, var/current_step = 0, var/age = 1, var/pressure = 0, var/blast_temperature = 0, var/fire_duration, var/origin, color, damage_type, special, reagent_type)
+ ..()
+ icon_state = "key[rand(1,3)]"
+
+/obj/effect/fire_blast/custom/burn_mob(mob/living/L, var/adjusted_fire_damage)
+ if(special)
+ ApplyStatus(L, special, adjusted_fire_damage)
+ if(L.mutations.Find(M_RESIST_HEAT) && damage_type == BURN)
+ return
+ L.apply_damage(adjusted_fire_damage, damage_type)
+
+/obj/effect/fire_blast/custom/proc/ApplyStatus(mob/living/L, special, adjusted_fire_damage)
+ var/mob/living/carbon/H = L
+ if(adjusted_fire_damage < 1)
+ adjusted_fire_damage++
+ for(var/status in special)
+ if(status == "IGNITE")
+ if(!L.on_fire)
+ L.ignite()
+ if(status == "RADIATION")
+ L.apply_radiation((damage), RAD_EXTERNAL)
+ if(status == "PLASMA")//contaminate equipment with plasma
+ if(!ishuman(L))
+ return
+ if(H.flags & PLASMA_IMMUNE)
+ return
+ H.contaminate()
+ if(status == "CHEM")
+ var/datum/reagents/R = L.reagents
+ R.add_reagent(reagent_type.id, 10)
+ if(status == "PUSH")
+ var/randomdir = pick(alldirs)
+ L.Move(get_turf(src), randomdir)
+ if(status == "COUGH")
+ if(ishuman(H))
+ if(H.has_breathing_mask())
+ return
+ L.audible_cough()
+ var/obj/item/I = H.get_active_hand()
+ if(I && I.w_class < W_CLASS_MEDIUM)
+ H.drop_item(I)
+ if(status == "BLIND")
+ L.apply_effects(0, 0, 0, 0, 0, 10)
+
+/obj/effect/fire_blast/custom/blast_spread(current_step, pressure, blast_temperature)//needs to transfer the new vars
+ if(spread && current_step >= spread_start && blast_age < 4)
+ var/turf/TS = get_turf(src)
+ for(var/turf/TU in range(1, TS))
+ if(TU != get_turf(src))
+ var/tilehasfire = 0
+ var/obstructed = 0
+ for(var/obj/effect/E in TU)
+ if(istype(E, /obj/effect/fire_blast))
+ tilehasfire = 1
+ for(var/obj/machinery/door/D in TU)
+ if(istype(D, /obj/machinery/door/airlock) || istype(D, /obj/machinery/door/mineral))
+ if(D.density)
+ obstructed = 1
+ if(prob(spread_chance) && TS.Adjacent(TU) && !TU.density && !tilehasfire && !obstructed)
+ var/obj/effect/fire_blast/custom/breath = new type(TU, fire_damage, current_step, blast_age+1, pressure, blast_temperature, duration, damage)
+ breath.color = color
+ breath.damage_type = damage_type
+ breath.special = special
+ breath.reagent_type = reagent_type
+ sleep(1)
diff --git a/vgstation13.dme b/vgstation13.dme
index d15bc3785f0e..92deccaa92c2 100644
--- a/vgstation13.dme
+++ b/vgstation13.dme
@@ -1918,6 +1918,7 @@
#include "code\modules\mob\mob_helpers.dm"
#include "code\modules\mob\mob_movement.dm"
#include "code\modules\mob\mob_transformation_simple.dm"
+#include "code\modules\mob\procedural_mobspawn.dm"
#include "code\modules\mob\say.dm"
#include "code\modules\mob\spells.dm"
#include "code\modules\mob\thermoregulation.dm"
@@ -2213,6 +2214,7 @@
#include "code\modules\mob\living\simple_animal\hostile\hog.dm"
#include "code\modules\mob\living\simple_animal\hostile\hostile.dm"
#include "code\modules\mob\living\simple_animal\hostile\mannequin.dm"
+#include "code\modules\mob\living\simple_animal\hostile\megabeast.dm"
#include "code\modules\mob\living\simple_animal\hostile\mimic.dm"
#include "code\modules\mob\living\simple_animal\hostile\mining_mobs.dm"
#include "code\modules\mob\living\simple_animal\hostile\monster.dm"
@@ -2977,8 +2979,8 @@
#include "code\modules\trader\trade_window.dm"
#include "code\modules\trader\crates\alcatrazfour.dm"
#include "code\modules\trader\crates\cloudnine.dm"
-#include "code\modules\trader\crates\lostcrate.dm"
#include "code\modules\trader\crates\exoticshotgunshells.dm"
+#include "code\modules\trader\crates\lostcrate.dm"
#include "code\modules\trader\crates\misc_variety.dm"
#include "code\modules\trader\crates\shoaljunk.dm"
#include "code\modules\trader\crates\yantar.dm"