Some missed mirrors (#13415)

* Refactors firestacks into status effects (#66573)

This PR refactors firestacks into two status effects: fire_stacks, which behave like normal firestacks you have right now, and wet_stacks, which are your negative fire stacks right now. This allows for custom fires with custom behaviors and icons to be made.

Some fire related is moved away from species(what the fuck was it even doing there) into these as well.
Oh and I fixed the bug where monkeys on fire had a human fire overlay, why wasn't this fixed already, it's like ancient.

Also changed some related proc names to be snake_case like everything should be.

This allows for custom fire types with custom behaviours, like freezing freon fire or radioactive tritium fire. Removing vars from living and moving them to status effects for modularity is also good.
Nothing to argue about since there's nothing player-facing

* Hud Image Culling By Z Level: Theft edition (#65189)

* makes hud images only apply by z level

* makes some of the atom_hud procs have better names

* fixes warning with the hud_user list and adds better documentation

* better docs for hud_images

* removes TODOs

* docs for hud_list

* adds support for linked z levels so mobs can see lower ones

* fixes merge conflict and shittily makes only shocked airlocks get added

* adds support for setting images in the hud as active and inactive

* gets rid of unatomic spatial grid change

* maybe i should actually try COMPILING my changes

* fixes merge skew and makes it compile again

* fixes huds refusing to remove from users who changed z level

* improves z level and registration logic

* fixes antag huds not appearing

* Fixes antag huds not properly setting. We now use hud_list in init, so it needs to be set before the new call, not after. Not sure why the use of appearance key was split like this, but none else knows either so none can stop me

* Ensures that hiding a basic appearance also hides the atom's active list too

* Fixes antag huds going poof

Ensures that remove_atom_from_hud will return false if the passed atom
isn't managed by it

This fixes antag huds disappearing randomly, since they assumed that if
the parent call of remove_atom_from_hud returned true, we should delete
ourselves. This is a safe assumption for them to make, since they should
only ever have one atom.

Does kinda bork if we call remove_atom_from_hud in a way that is unsure
if the passed atom is actually in that list. We were forced into doing
this by how atom huds use the qdeleting signal.

* makes basic alternate_appearance's only update themselves when setting their hud image to active and makes them not add themselves to the global huds_by_category list

* fixes mistake with hud_users list being set non associatively (bad)

* as anything in bot path loops

* Fixes merge skew problems

* Makes bot paths non global

This way they can show themselves to only the bot that "owns" them, ya
feel me?

* Fixes huds not showing up sometimes, cleans up some code

Post Kapu's limb refactor, we were calling prepare_huds twice in a human
init call chain. What was happening was this:

call prepare_huds() // Human
I gained a new hud image
I set active hud icons to mirror it
call prepare_huds() // Living
I overwrote the new hud image
I attempted to set active hud icons, which failed because it assumes
this can never happen

*cries*

* Renames add_hud_to_atom to show_to

My hope is this will make understanding hud code a bit easier, by tying
the behavior to a "verb" more closely. Also renamed a few vars

* remove_hud_from_mob -> hide_from

* Nitpicks a few comments

* Whoops/fuck/shit/damn it all/hhhhhhhhhhhh

* Moves check down, improves stack trace a bit

Co-authored-by: KylerAce <kylerlumpkin1@gmail.com>

* small touch-up

* this should do it

Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com>
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: KylerAce <kylerlumpkin1@gmail.com>
This commit is contained in:
Useroth
2022-05-08 03:59:40 +01:00
committed by GitHub
co-authored by KylerAce SmArtKar LemonInTheDark
parent cd45c0f943
commit cca7f8ee4c
138 changed files with 1288 additions and 646 deletions
+1
View File
@@ -2,6 +2,7 @@
// note: if you add more HUDs, even for non-human atoms, make sure to use unique numbers for the defines!
// /datum/atom_hud expects these to be unique
// these need to be strings in order to make them associative lists
/// dead, alive, sick, health status
#define HEALTH_HUD "1"
/// a simple line rounding the mob's number health
@@ -16,7 +16,7 @@
#define COMSIG_LIVING_DOORCRUSHED "living_doorcrush"
///from base of mob/living/resist() (/mob/living)
#define COMSIG_LIVING_RESIST "living_resist"
///from base of mob/living/IgniteMob() (/mob/living)
///from base of mob/living/ignite_mob() (/mob/living)
#define COMSIG_LIVING_IGNITED "living_ignite"
///from base of mob/living/extinguish_mob() (/mob/living)
#define COMSIG_LIVING_EXTINGUISHED "living_extinguished"
+1 -2
View File
@@ -26,8 +26,7 @@ DEFINE_BITFIELD(smoothing_flags, list(
#define QUEUE_SMOOTH(thing_to_queue) if(thing_to_queue.smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK)) {SSicon_smooth.add_to_queue(thing_to_queue)}
#define QUEUE_SMOOTH_NEIGHBORS(thing_to_queue) for(var/neighbor in orange(1, thing_to_queue)) {var/atom/atom_neighbor = neighbor; QUEUE_SMOOTH(atom_neighbor)}
#define QUEUE_SMOOTH_NEIGHBORS(thing_to_queue) for(var/atom/atom_neighbor as anything in orange(1, thing_to_queue)) {QUEUE_SMOOTH(atom_neighbor)}
/**SMOOTHING GROUPS
* Groups of things to smooth with.
+26
View File
@@ -14,3 +14,29 @@
///whether movable is itself or containing something which should be in one of the spatial grid channels.
#define HAS_SPATIAL_GRID_CONTENTS(movable) (movable.important_recursive_contents && (movable.important_recursive_contents[RECURSIVE_CONTENTS_HEARING_SENSITIVE] || movable.important_recursive_contents[RECURSIVE_CONTENTS_CLIENT_MOBS]))
// macros meant specifically to add/remove movables from lazy content lists in the spatial grid.
// when empty they become references to a single list in SSspatial_grid and when filled they become their own list
// this is to save memory without making them lazylists as that slows down iteration through them
#define GRID_CELL_ADD(cell_contents_list, movable_or_list) \
if(!length(cell_contents_list)) { \
cell_contents_list = list(); \
cell_contents_list += movable_or_list; \
} else { \
cell_contents_list += movable_or_list; \
};
#define GRID_CELL_SET(cell_contents_list, movable_or_list) \
if(!length(cell_contents_list)) { \
cell_contents_list = list(); \
cell_contents_list += movable_or_list; \
} else { \
cell_contents_list |= movable_or_list; \
};
//dont use these outside of SSspatial_grid's scope use the procs it has for this purpose
#define GRID_CELL_REMOVE(cell_contents_list, movable_or_list) \
cell_contents_list -= movable_or_list; \
if(!length(cell_contents_list)) {\
cell_contents_list = dummy_list; \
};
+1
View File
@@ -38,3 +38,4 @@
#define STASIS_CHEMICAL_EFFECT "stasis_chemical"
#define STASIS_ASCENSION_EFFECT "heretic_ascension"
+9 -12
View File
@@ -309,8 +309,7 @@ DEFINE_BITFIELD(smoothing_junction, list(
return ADJ_FOUND
if(smoothing_flags & SMOOTH_OBJ)
for(var/am in target_turf)
var/atom/movable/thing = am
for(var/atom/movable/thing as anything in target_turf)
if(!thing.anchored || isnull(thing.smoothing_groups))
continue
for(var/target in canSmoothWith)
@@ -402,20 +401,18 @@ DEFINE_BITFIELD(smoothing_junction, list(
//Icon smoothing helpers
/proc/smooth_zlevel(zlevel, now = FALSE)
var/list/away_turfs = block(locate(1, 1, zlevel), locate(world.maxx, world.maxy, zlevel))
for(var/V in away_turfs)
var/turf/T = V
if(T.smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK))
for(var/turf/turf_to_smooth as anything in away_turfs)
if(turf_to_smooth.smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK))
if(now)
T.smooth_icon()
turf_to_smooth.smooth_icon()
else
QUEUE_SMOOTH(T)
for(var/R in T)
var/atom/A = R
if(A.smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK))
QUEUE_SMOOTH(turf_to_smooth)
for(var/atom/movable/movable_to_smooth as anything in turf_to_smooth)
if(movable_to_smooth.smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK))
if(now)
A.smooth_icon()
movable_to_smooth.smooth_icon()
else
QUEUE_SMOOTH(A)
QUEUE_SMOOTH(movable_to_smooth)
/atom/proc/clear_smooth_overlays()
+1 -1
View File
@@ -231,7 +231,7 @@
// Add AntagHUD to everyone, see who was really evil the whole time!
for(var/datum/atom_hud/alternate_appearance/basic/antagonist_hud/antagonist_hud in GLOB.active_alternate_appearances)
for(var/mob/player as anything in GLOB.player_list)
antagonist_hud.add_hud_to(player)
antagonist_hud.show_to(player)
CHECK_TICK
+7 -8
View File
@@ -11,10 +11,10 @@ SUBSYSTEM_DEF(icon_smooth)
var/list/deferred = list()
/datum/controller/subsystem/icon_smooth/fire()
var/list/cached = smooth_queue
while(length(cached))
var/atom/smoothing_atom = cached[length(cached)]
cached.len--
var/list/smooth_queue_cache = smooth_queue
while(length(smooth_queue_cache))
var/atom/smoothing_atom = smooth_queue_cache[length(smooth_queue_cache)]
smooth_queue_cache.len--
if(QDELETED(smoothing_atom) || !(smoothing_atom.smoothing_flags & SMOOTH_QUEUED))
continue
if(smoothing_atom.flags_1 & INITIALIZED_1)
@@ -24,10 +24,10 @@ SUBSYSTEM_DEF(icon_smooth)
if (MC_TICK_CHECK)
return
if (!cached.len)
if (!length(smooth_queue_cache))
if (deferred.len)
smooth_queue = deferred
deferred = cached
deferred = smooth_queue_cache
else
can_fire = FALSE
@@ -49,8 +49,7 @@ SUBSYSTEM_DEF(icon_smooth)
queue = blueprint_queue
blueprint_queue = null
for(var/item in queue)
var/atom/movable/movable_item = item
for(var/atom/movable/movable_item as anything in queue)
if(!isturf(movable_item.loc))
continue
var/turf/item_loc = movable_item.loc
+1
View File
@@ -40,6 +40,7 @@ SUBSYSTEM_DEF(mapping)
// Z-manager stuff
var/station_start // should only be used for maploading-related tasks
var/space_levels_so_far = 0
///list of all the z level datums created representing the z levels in the world
var/list/z_list
var/datum/space_level/transit
var/datum/space_level/empty_space
+42 -49
View File
@@ -1,32 +1,6 @@
///the subsystem creates this many [/mob/oranges_ear] mob instances during init. allocations that require more than this create more.
#define NUMBER_OF_PREGENERATED_ORANGES_EARS 2500
// macros meant specifically to add/remove movables from the hearing_contents and client_contents lists of
// /datum/spatial_grid_cell, when empty they become references to a single list in SSspatial_grid and when filled they become their own list
// this is to save memory without making them lazylists as that slows down iteration through them
#define GRID_CELL_ADD(cell_contents_list, movable_or_list) \
if(!length(cell_contents_list)) { \
cell_contents_list = list(); \
cell_contents_list += movable_or_list; \
} else { \
cell_contents_list += movable_or_list; \
};
#define GRID_CELL_SET(cell_contents_list, movable_or_list) \
if(!length(cell_contents_list)) { \
cell_contents_list = list(); \
cell_contents_list += movable_or_list; \
} else { \
cell_contents_list |= movable_or_list; \
};
//dont use these outside of SSspatial_grid's scope use the procs it has for this purpose
#define GRID_CELL_REMOVE(cell_contents_list, movable_or_list) \
cell_contents_list -= movable_or_list; \
if(!length(cell_contents_list)) {\
cell_contents_list = dummy_list; \
};
/**
* # Spatial Grid Cell
*
@@ -64,7 +38,6 @@
if(length(dummy_list))
dummy_list.Cut()
stack_trace("SSspatial_grid.dummy_list had something inserted into it at some point! this is a problem as it is supposed to stay empty")
hearing_contents = dummy_list
client_contents = dummy_list
@@ -296,6 +269,7 @@ SUBSYSTEM_DEF(spatial_grid)
//technically THIS list only contains lists, but inside those lists are grid cell datums and we can go without a SINGLE var init if we do this
var/list/datum/spatial_grid_cell/grid_level = grids_by_z_level[center_turf.z]
switch(type)
if(SPATIAL_GRID_CONTENTS_TYPE_CLIENTS)
for(var/row in BOUNDING_BOX_MIN(center_y) to BOUNDING_BOX_MAX(center_y, cells_on_y_axis))
@@ -363,15 +337,15 @@ SUBSYSTEM_DEF(spatial_grid)
var/datum/spatial_grid_cell/intersecting_cell = grids_by_z_level[z_index][y_index][x_index]
if(new_target.important_recursive_contents[RECURSIVE_CONTENTS_CLIENT_MOBS])
if(new_target.important_recursive_contents[SPATIAL_GRID_CONTENTS_TYPE_CLIENTS])
GRID_CELL_SET(intersecting_cell.client_contents, new_target.important_recursive_contents[SPATIAL_GRID_CONTENTS_TYPE_CLIENTS])
SEND_SIGNAL(intersecting_cell, SPATIAL_GRID_CELL_ENTERED(RECURSIVE_CONTENTS_CLIENT_MOBS), new_target)
SEND_SIGNAL(intersecting_cell, SPATIAL_GRID_CELL_ENTERED(SPATIAL_GRID_CONTENTS_TYPE_CLIENTS), new_target.important_recursive_contents[SPATIAL_GRID_CONTENTS_TYPE_CLIENTS])
if(new_target.important_recursive_contents[RECURSIVE_CONTENTS_HEARING_SENSITIVE])
GRID_CELL_SET(intersecting_cell.hearing_contents, new_target.important_recursive_contents[RECURSIVE_CONTENTS_HEARING_SENSITIVE])
if(new_target.important_recursive_contents[SPATIAL_GRID_CONTENTS_TYPE_HEARING])
GRID_CELL_SET(intersecting_cell.hearing_contents, new_target.important_recursive_contents[SPATIAL_GRID_CONTENTS_TYPE_HEARING])
SEND_SIGNAL(intersecting_cell, SPATIAL_GRID_CELL_ENTERED(RECURSIVE_CONTENTS_HEARING_SENSITIVE), new_target)
SEND_SIGNAL(intersecting_cell, SPATIAL_GRID_CELL_ENTERED(SPATIAL_GRID_CONTENTS_TYPE_HEARING), new_target.important_recursive_contents[SPATIAL_GRID_CONTENTS_TYPE_HEARING])
/**
* find the spatial map cell that target used to belong to, then subtract target's important_recusive_contents from it.
@@ -385,35 +359,54 @@ SUBSYSTEM_DEF(spatial_grid)
if(!initialized)
return
if(!target_turf || !old_target?.important_recursive_contents)
CRASH("/datum/controller/subsystem/spatial_grid/proc/exit_cell() was given null arguments or a new_target without important_recursive_contents!")
stack_trace("/datum/controller/subsystem/spatial_grid/proc/exit_cell() was given null arguments or a new_target without important_recursive_contents!")
return FALSE
var/x_index = ROUND_UP(target_turf.x / SPATIAL_GRID_CELLSIZE)
var/y_index = ROUND_UP(target_turf.y / SPATIAL_GRID_CELLSIZE)
var/z_index = target_turf.z
var/list/grid = grids_by_z_level[z_index]
var/datum/spatial_grid_cell/intersecting_cell = grid[y_index][x_index]
var/datum/spatial_grid_cell/intersecting_cell = grids_by_z_level[z_index][y_index][x_index]
var/list/old_target_contents = old_target.important_recursive_contents //cache for sanic speeds (lists are references anyways)
if(exclusive_type && old_target.important_recursive_contents[exclusive_type])
switch(exclusive_type)
if(RECURSIVE_CONTENTS_CLIENT_MOBS)
GRID_CELL_REMOVE(intersecting_cell.client_contents, old_target.important_recursive_contents[RECURSIVE_CONTENTS_CLIENT_MOBS])
if(old_target_contents[SPATIAL_GRID_CONTENTS_TYPE_CLIENTS])
GRID_CELL_REMOVE(intersecting_cell.client_contents, old_target_contents[SPATIAL_GRID_CONTENTS_TYPE_CLIENTS])
if(RECURSIVE_CONTENTS_HEARING_SENSITIVE)
GRID_CELL_REMOVE(intersecting_cell.hearing_contents, old_target.important_recursive_contents[RECURSIVE_CONTENTS_HEARING_SENSITIVE])
SEND_SIGNAL(intersecting_cell, SPATIAL_GRID_CELL_EXITED(SPATIAL_GRID_CONTENTS_TYPE_CLIENTS), old_target_contents[SPATIAL_GRID_CONTENTS_TYPE_CLIENTS])
SEND_SIGNAL(intersecting_cell, SPATIAL_GRID_CELL_EXITED(exclusive_type), old_target)
return
if(old_target_contents[SPATIAL_GRID_CONTENTS_TYPE_HEARING])
GRID_CELL_REMOVE(intersecting_cell.hearing_contents, old_target_contents[SPATIAL_GRID_CONTENTS_TYPE_HEARING])
if(old_target.important_recursive_contents[RECURSIVE_CONTENTS_CLIENT_MOBS])
GRID_CELL_REMOVE(intersecting_cell.client_contents, old_target.important_recursive_contents[RECURSIVE_CONTENTS_CLIENT_MOBS])
SEND_SIGNAL(intersecting_cell, SPATIAL_GRID_CELL_EXITED(SPATIAL_GRID_CONTENTS_TYPE_HEARING), old_target_contents[SPATIAL_GRID_CONTENTS_TYPE_HEARING])
SEND_SIGNAL(intersecting_cell, SPATIAL_GRID_CELL_EXITED(SPATIAL_GRID_CONTENTS_TYPE_CLIENTS), old_target)
return TRUE
if(old_target.important_recursive_contents[RECURSIVE_CONTENTS_HEARING_SENSITIVE])
GRID_CELL_REMOVE(intersecting_cell.hearing_contents, old_target.important_recursive_contents[RECURSIVE_CONTENTS_HEARING_SENSITIVE])
///acts like exit_cell() but only removes the target from the specified type of grid cell contents list
/datum/controller/subsystem/spatial_grid/proc/remove_single_contents_type(atom/movable/old_target, turf/target_turf, exclusive_type)
if(!target_turf || !old_target?.important_recursive_contents || !exclusive_type)
stack_trace("/datum/controller/subsystem/spatial_grid/proc/remove_single_contents_type() was given null arguments or a new_target without important_recursive_contents!")
return FALSE
if(!old_target.important_recursive_contents[exclusive_type])
return FALSE
var/x_index = ROUND_UP(target_turf.x / SPATIAL_GRID_CELLSIZE)
var/y_index = ROUND_UP(target_turf.y / SPATIAL_GRID_CELLSIZE)
var/z_index = target_turf.z
var/datum/spatial_grid_cell/intersecting_cell = grids_by_z_level[z_index][y_index][x_index]
switch(exclusive_type)
if(SPATIAL_GRID_CONTENTS_TYPE_CLIENTS)
GRID_CELL_REMOVE(intersecting_cell.client_contents, old_target.important_recursive_contents[SPATIAL_GRID_CONTENTS_TYPE_CLIENTS])
if(SPATIAL_GRID_CONTENTS_TYPE_HEARING)
GRID_CELL_REMOVE(intersecting_cell.hearing_contents, old_target.important_recursive_contents[SPATIAL_GRID_CONTENTS_TYPE_HEARING])
SEND_SIGNAL(intersecting_cell, SPATIAL_GRID_CELL_EXITED(exclusive_type), old_target)
return TRUE
SEND_SIGNAL(intersecting_cell, SPATIAL_GRID_CELL_EXITED(RECURSIVE_CONTENTS_HEARING_SENSITIVE), old_target)
///find the cell this movable is associated with and removes it from all lists
/datum/controller/subsystem/spatial_grid/proc/force_remove_from_cell(atom/movable/to_remove, datum/spatial_grid_cell/input_cell)
+5 -3
View File
@@ -1,11 +1,13 @@
/datum/component/igniter
var/fire_stacks
var/fire_type
/datum/component/igniter/Initialize(fire_stacks=1)
/datum/component/igniter/Initialize(fire_stacks = 1, fire_type = /datum/status_effect/fire_handler/fire_stacks)
if(!isitem(parent) && !ishostile(parent) && !isgun(parent) && !ismachinery(parent) && !isstructure(parent))
return COMPONENT_INCOMPATIBLE
src.fire_stacks = fire_stacks
src.fire_type = fire_type
/datum/component/igniter/RegisterWithParent()
if(ismachinery(parent) || isstructure(parent) || isgun(parent)) // turrets, etc
@@ -40,5 +42,5 @@
/datum/component/igniter/proc/do_igniter(atom/target)
if(isliving(target))
var/mob/living/L = target
L.adjust_fire_stacks(fire_stacks)
L.IgniteMob()
L.adjust_fire_stacks(fire_stacks, fire_type)
L.ignite_mob()
@@ -51,12 +51,12 @@
to_chat(M, span_warning("[pick("You feel hot.", "You hear a crackling noise.", "You smell smoke.")]"))
if(4)
Firestacks_stage_4(M, A)
M.IgniteMob()
M.ignite_mob()
to_chat(M, span_userdanger("Your skin bursts into flames!"))
M.emote("scream")
if(5)
Firestacks_stage_5(M, A)
M.IgniteMob()
M.ignite_mob()
to_chat(M, span_userdanger("Your skin erupts into an inferno!"))
M.emote("scream")
@@ -134,7 +134,7 @@ Bonus
M.visible_message(span_warning("[M]'s sweat sizzles and pops on contact with water!"))
explosion(M, devastation_range = -1, heavy_impact_range = (-1 + explosion_power), light_impact_range = (2 * explosion_power), explosion_cause = src)
Alkali_fire_stage_4(M, A)
M.IgniteMob()
M.ignite_mob()
to_chat(M, span_userdanger("Your sweat bursts into flames!"))
M.emote("scream")
if(5)
@@ -142,7 +142,7 @@ Bonus
M.visible_message(span_warning("[M]'s sweat sizzles and pops on contact with water!"))
explosion(M, devastation_range = -1, heavy_impact_range = (-1 + explosion_power), light_impact_range = (2 * explosion_power), explosion_cause = src)
Alkali_fire_stage_5(M, A)
M.IgniteMob()
M.ignite_mob()
to_chat(M, span_userdanger("Your skin erupts into an inferno!"))
M.emote("scream")
@@ -455,7 +455,7 @@
. = 0
var/mob/living/M = A.affected_mob
if(M.fire_stacks < 0)
M.set_fire_stacks(min(M.fire_stacks + 1 * absorption_coeff, 0))
M.adjust_fire_stacks(min(absorption_coeff, -M.fire_stacks))
. += power
if(M.reagents.has_reagent(/datum/reagent/water/holywater, needs_metabolizing = FALSE))
M.reagents.remove_reagent(/datum/reagent/water/holywater, 0.5 * absorption_coeff)
+1 -1
View File
@@ -32,7 +32,7 @@
if(DT_PROB(10, delta_time))
if(prob(50))
affected_mob.adjust_fire_stacks(2)
affected_mob.IgniteMob()
affected_mob.ignite_mob()
else
affected_mob.emote("gasp")
to_chat(affected_mob, span_danger("You feel a burning beat inside..."))
+322 -80
View File
@@ -2,6 +2,10 @@
GLOBAL_LIST_EMPTY(all_huds)
///gets filled by each /datum/atom_hud/New().
///associative list of the form: list(hud category = list(all global atom huds that use that category))
GLOBAL_LIST_EMPTY(huds_by_category)
//GLOBAL HUD LIST
GLOBAL_LIST_INIT(huds, list(
DATA_HUD_SECURITY_BASIC = new/datum/atom_hud/data/human/security/basic(),
@@ -18,116 +22,354 @@ GLOBAL_LIST_INIT(huds, list(
))
/datum/atom_hud
var/list/atom/hudatoms = list() //list of all atoms which display this hud
var/list/hudusers = list() //list with all mobs who can see the hud
var/list/hud_icons = list() //these will be the indexes for the atom's hud_list
///associative list of the form: list(z level = list(hud atom)).
///tracks what hud atoms for this hud exists in what z level so we can only give users
///the hud images that they can actually see.
var/list/atom/hud_atoms = list()
var/list/next_time_allowed = list() //mobs associated with the next time this hud can be added to them
var/list/queued_to_see = list() //mobs that have triggered the cooldown and are queued to see the hud, but do not yet
var/hud_exceptions = list() // huduser = list(ofatomswiththeirhudhidden) - aka everyone hates targeted invisiblity
///associative list of the form: list(z level = list(hud user client mobs)).
///tracks mobs that can "see" us
// by z level so when they change z's we can adjust what images they see from this hud.
var/list/hud_users = list()
///used for signal tracking purposes, associative list of the form: list(hud atom = TRUE) that isnt separated by z level
var/list/atom/hud_atoms_all_z_levels = list()
///used for signal tracking purposes, associative list of the form: list(hud user = number of times this hud was added to this user).
///that isnt separated by z level
var/list/mob/hud_users_all_z_levels = list()
///these will be the indexes for the atom's hud_list
var/list/hud_icons = list()
///mobs associated with the next time this hud can be added to them
var/list/next_time_allowed = list()
///mobs that have triggered the cooldown and are queued to see the hud, but do not yet
var/list/queued_to_see = list()
/// huduser = list(atoms with their hud hidden) - aka everyone hates targeted invisiblity
var/list/hud_exceptions = list()
///whether or not this atom_hud type updates the global huds_by_category list.
///some subtypes cant work like this since theyre supposed to "belong" to
///one target atom each. it will still go in the other global hud lists.
var/uses_global_hud_category = TRUE
/datum/atom_hud/New()
GLOB.all_huds += src
for(var/z_level in 1 to world.maxz)
hud_atoms += list(list())
hud_users += list(list())
RegisterSignal(SSdcs, COMSIG_GLOB_NEW_Z, .proc/add_z_level_huds)
if(uses_global_hud_category)
for(var/hud_icon in hud_icons)
GLOB.huds_by_category[hud_icon] += list(src)
/datum/atom_hud/Destroy()
for(var/v in hudusers)
remove_hud_from(v)
for(var/v in hudatoms)
remove_from_hud(v)
for(var/mob/mob as anything in hud_users_all_z_levels)
hide_from(mob)
for(var/atom/atom as anything in hud_atoms_all_z_levels)
remove_atom_from_hud(atom)
if(uses_global_hud_category)
for(var/hud_icon in hud_icons)
LAZYREMOVEASSOC(GLOB.huds_by_category, hud_icon, src)
GLOB.all_huds -= src
return ..()
/datum/atom_hud/proc/remove_hud_from(mob/M, absolute = FALSE)
if(!M || !hudusers[M])
return
if (absolute || !--hudusers[M])
UnregisterSignal(M, COMSIG_PARENT_QDELETING)
hudusers -= M
if(next_time_allowed[M])
next_time_allowed -= M
if(queued_to_see[M])
queued_to_see -= M
else
for(var/atom/A in hudatoms)
remove_from_single_hud(M, A)
/datum/atom_hud/proc/add_z_level_huds()
SIGNAL_HANDLER
hud_atoms += list(list())
hud_users += list(list())
/datum/atom_hud/proc/remove_from_hud(atom/A)
if(!A)
///returns a list of all hud atoms in the given z level and linked lower z levels (because hud users in higher z levels can see below)
/datum/atom_hud/proc/get_hud_atoms_for_z_level(z_level)
if(z_level <= 0)
return FALSE
for(var/mob/M in hudusers)
remove_from_single_hud(M, A)
hudatoms -= A
if(z_level > length(hud_atoms))
stack_trace("get_hud_atoms_for_z_level() was given a z level index out of bounds of hud_atoms!")
return FALSE
. = list()
. += hud_atoms[z_level]
var/max_number_of_linked_z_levels_i_care_to_support_here = 10
while(max_number_of_linked_z_levels_i_care_to_support_here)
var/lower_z_level_exists = SSmapping.level_trait(z_level, ZTRAIT_DOWN)
if(lower_z_level_exists)
z_level--
. += hud_atoms[z_level]
max_number_of_linked_z_levels_i_care_to_support_here--
continue
else
break
///returns a list of all hud users in the given z level and linked upper z levels (because hud users in higher z levels can see below)
/datum/atom_hud/proc/get_hud_users_for_z_level(z_level)
if(z_level > length(hud_users) || z_level <= 0)
stack_trace("get_hud_atoms_for_z_level() was given a z level index [z_level] out of bounds 1->[length(hud_users)] of hud_atoms!")
return FALSE
. = list()
. += hud_users[z_level]
var/max_number_of_linked_z_levels_i_care_to_support_here = 10
while(max_number_of_linked_z_levels_i_care_to_support_here)
var/upper_level_exists = SSmapping.level_trait(z_level, ZTRAIT_UP)
if(upper_level_exists)
z_level++
. += hud_users[z_level]
max_number_of_linked_z_levels_i_care_to_support_here--
continue
else
break
///show this hud to the passed in user
/datum/atom_hud/proc/show_to(mob/new_viewer)
if(!new_viewer)
return
var/turf/their_turf = get_turf(new_viewer)
if(!their_turf)
return
if(!hud_users[their_turf.z][new_viewer])
hud_users[their_turf.z][new_viewer] = TRUE
hud_users_all_z_levels[new_viewer] = 1
RegisterSignal(new_viewer, COMSIG_PARENT_QDELETING, .proc/unregister_atom, override = TRUE) //both hud users and hud atoms use these signals
RegisterSignal(new_viewer, COMSIG_MOVABLE_Z_CHANGED, .proc/on_atom_or_user_z_level_changed, override = TRUE)
if(next_time_allowed[new_viewer] > world.time)
if(!queued_to_see[new_viewer])
addtimer(CALLBACK(src, .proc/show_hud_images_after_cooldown, new_viewer), next_time_allowed[new_viewer] - world.time)
queued_to_see[new_viewer] = TRUE
else
next_time_allowed[new_viewer] = world.time + ADD_HUD_TO_COOLDOWN
for(var/atom/hud_atom_to_add as anything in get_hud_atoms_for_z_level(their_turf.z))
add_atom_to_single_mob_hud(new_viewer, hud_atom_to_add)
else
hud_users_all_z_levels[new_viewer] += 1 //increment the number of times this hud has been added to this hud user
///Hides the images in this hud from former_viewer
///If absolute is set to true, this will forcefully remove the hud, even if sources in theory remain
/datum/atom_hud/proc/hide_from(mob/former_viewer, absolute = FALSE)
if(!former_viewer || !hud_users_all_z_levels[former_viewer])
return
var/turf/their_turf = get_turf(former_viewer)
if(!their_turf)
return
hud_users_all_z_levels[former_viewer] -= 1//decrement number of sources for this hud on this user (bad way to track i know)
if (absolute || hud_users_all_z_levels[former_viewer] <= 0)//if forced or there arent any sources left, remove the user
if(!hud_atoms_all_z_levels[former_viewer])//make sure we arent unregistering changes on a mob thats also a hud atom for this hud
UnregisterSignal(former_viewer, COMSIG_MOVABLE_Z_CHANGED)
UnregisterSignal(former_viewer, COMSIG_PARENT_QDELETING)
hud_users[their_turf.z] -= former_viewer
hud_users_all_z_levels -= former_viewer
if(next_time_allowed[former_viewer])
next_time_allowed -= former_viewer
if(queued_to_see[former_viewer])
queued_to_see -= former_viewer
else
for(var/atom/hud_atom as anything in get_hud_atoms_for_z_level(their_turf.z))
remove_atom_from_single_hud(former_viewer, hud_atom)
/// add new_hud_atom to this hud
/datum/atom_hud/proc/add_atom_to_hud(atom/new_hud_atom)
if(!new_hud_atom)
return FALSE
var/turf/atom_turf = get_turf(new_hud_atom)
if(!atom_turf)
return
RegisterSignal(new_hud_atom, COMSIG_MOVABLE_Z_CHANGED, .proc/on_atom_or_user_z_level_changed, override = TRUE)
RegisterSignal(new_hud_atom, COMSIG_PARENT_QDELETING, .proc/unregister_atom, override = TRUE) //both hud atoms and hud users use these signals
hud_atoms[atom_turf.z] |= new_hud_atom
hud_atoms_all_z_levels[new_hud_atom] = TRUE
for(var/mob/mob_to_show as anything in get_hud_users_for_z_level(atom_turf.z))
if(!queued_to_see[mob_to_show])
add_atom_to_single_mob_hud(mob_to_show, new_hud_atom)
return TRUE
/datum/atom_hud/proc/remove_from_single_hud(mob/M, atom/A) //unsafe, no sanity apart from client
if(!M || !M.client || !A)
return
for(var/i in hud_icons)
M.client.images -= A.hud_list[i]
/// remove this atom from this hud completely
/datum/atom_hud/proc/remove_atom_from_hud(atom/hud_atom_to_remove)
if(!hud_atom_to_remove || !hud_atoms_all_z_levels[hud_atom_to_remove])
return FALSE
/datum/atom_hud/proc/add_hud_to(mob/M)
if(!M)
return
if(!hudusers[M])
hudusers[M] = 1
RegisterSignal(M, COMSIG_PARENT_QDELETING, .proc/unregister_mob)
if(next_time_allowed[M] > world.time)
if(!queued_to_see[M])
addtimer(CALLBACK(src, .proc/show_hud_images_after_cooldown, M), next_time_allowed[M] - world.time)
queued_to_see[M] = TRUE
else
next_time_allowed[M] = world.time + ADD_HUD_TO_COOLDOWN
for(var/atom/A in hudatoms)
add_to_single_hud(M, A)
else
hudusers[M]++
//make sure we arent unregistering a hud atom thats also a hud user mob
if(!hud_users_all_z_levels[hud_atom_to_remove])
UnregisterSignal(hud_atom_to_remove, COMSIG_MOVABLE_Z_CHANGED)
UnregisterSignal(hud_atom_to_remove, COMSIG_PARENT_QDELETING)
/datum/atom_hud/proc/unregister_mob(datum/source, force)
for(var/mob/mob_to_remove as anything in hud_users_all_z_levels)
remove_atom_from_single_hud(mob_to_remove, hud_atom_to_remove)
var/turf/atom_turf = get_turf(hud_atom_to_remove)
if(!atom_turf)
return
hud_atoms[atom_turf.z] -= hud_atom_to_remove
hud_atoms_all_z_levels -= hud_atom_to_remove
return TRUE
///adds a newly active hud category's image on a hud atom to every mob that could see it
/datum/atom_hud/proc/add_single_hud_category_on_atom(atom/hud_atom, hud_category_to_add)
if(!hud_atom?.active_hud_list?[hud_category_to_add] || QDELING(hud_atom) || !(hud_category_to_add in hud_icons))
return FALSE
var/turf/atom_turf = get_turf(hud_atom)
if(!atom_turf)
return FALSE
if(!hud_atoms_all_z_levels[hud_atom])
add_atom_to_hud(hud_atom)
return TRUE
for(var/mob/hud_user as anything in get_hud_users_for_z_level(atom_turf.z))
if(!hud_user.client)
continue
if(!hud_exceptions[hud_user] || !(hud_atom in hud_exceptions[hud_user]))
hud_user.client.images |= hud_atom.active_hud_list[hud_category_to_add]
return TRUE
///removes the image or images in hud_atom.hud_list[hud_category_to_remove] from every mob that can see it but leaves every other image
///from that atom there.
/datum/atom_hud/proc/remove_single_hud_category_on_atom(atom/hud_atom, hud_category_to_remove)
if(QDELETED(hud_atom) || !(hud_category_to_remove in hud_icons) || !hud_atoms_all_z_levels[hud_atom])
return FALSE
if(!hud_atom.active_hud_list)
remove_atom_from_hud(hud_atom)
return TRUE
var/turf/atom_turf = get_turf(hud_atom)
if(!atom_turf)
return FALSE
for(var/mob/hud_user as anything in get_hud_users_for_z_level(atom_turf.z))
if(!hud_user.client)
continue
hud_user.client.images -= hud_atom.active_hud_list[hud_category_to_remove]//by this point it shouldnt be in active_hud_list
return TRUE
///when a hud atom or hud user changes z levels this makes sure it gets the images it needs and removes the images it doesnt need.
///because of how signals work we need the same proc to handle both use cases because being a hud atom and being a hud user arent mutually exclusive
/datum/atom_hud/proc/on_atom_or_user_z_level_changed(atom/movable/moved_atom, turf/old_turf, turf/new_turf)
SIGNAL_HANDLER
remove_hud_from(source, TRUE)
/datum/atom_hud/proc/hide_single_atomhud_from(hud_user,hidden_atom)
if(hudusers[hud_user])
remove_from_single_hud(hud_user,hidden_atom)
if(old_turf)
if(hud_users_all_z_levels[moved_atom])
hud_users[old_turf.z] -= moved_atom
for(var/atom/formerly_seen_hud_atom as anything in get_hud_atoms_for_z_level(old_turf.z))
remove_atom_from_single_hud(moved_atom, formerly_seen_hud_atom)
if(hud_atoms_all_z_levels[moved_atom])
hud_atoms[old_turf.z] -= moved_atom
for(var/mob/formerly_seeing as anything in get_hud_users_for_z_level(old_turf.z))//this wont include moved_atom since its removed
remove_atom_from_single_hud(formerly_seeing, moved_atom)
if(new_turf)
if(hud_users_all_z_levels[moved_atom])
hud_users[new_turf.z][moved_atom] = TRUE //hud users is associative, hud atoms isnt
for(var/atom/newly_seen_hud_atom as anything in get_hud_atoms_for_z_level(new_turf.z))
add_atom_to_single_mob_hud(moved_atom, newly_seen_hud_atom)
if(hud_atoms_all_z_levels[moved_atom])
hud_atoms[new_turf.z] |= moved_atom
for(var/mob/newly_seeing as anything in get_hud_users_for_z_level(new_turf.z))
add_atom_to_single_mob_hud(newly_seeing, moved_atom)
/// add just hud_atom's hud images (that are part of this atom_hud) to requesting_mob's client.images list
/datum/atom_hud/proc/add_atom_to_single_mob_hud(mob/requesting_mob, atom/hud_atom) //unsafe, no sanity apart from client
if(!requesting_mob || !requesting_mob.client || !hud_atom)
return
for(var/hud_category in (hud_icons & hud_atom.active_hud_list))
if(!hud_exceptions[requesting_mob] || !(hud_atom in hud_exceptions[requesting_mob]))
requesting_mob.client.images |= hud_atom.active_hud_list[hud_category]
/// remove every hud image for this hud on atom_to_remove from client_mob's client.images list
/datum/atom_hud/proc/remove_atom_from_single_hud(mob/client_mob, atom/atom_to_remove)
if(!client_mob || !client_mob.client || !atom_to_remove?.active_hud_list)
return
for(var/hud_image in hud_icons)
client_mob.client.images -= atom_to_remove.active_hud_list[hud_image]
/datum/atom_hud/proc/unregister_atom(datum/source, force)
SIGNAL_HANDLER
hide_from(source, TRUE)
remove_atom_from_hud(source)
/datum/atom_hud/proc/hide_single_atomhud_from(mob/hud_user, atom/hidden_atom)
if(hud_users_all_z_levels[hud_user])
remove_atom_from_single_hud(hud_user, hidden_atom)
if(!hud_exceptions[hud_user])
hud_exceptions[hud_user] = list(hidden_atom)
else
hud_exceptions[hud_user] += hidden_atom
/datum/atom_hud/proc/unhide_single_atomhud_from(hud_user,hidden_atom)
/datum/atom_hud/proc/unhide_single_atomhud_from(mob/hud_user, atom/hidden_atom)
hud_exceptions[hud_user] -= hidden_atom
if(hudusers[hud_user])
add_to_single_hud(hud_user,hidden_atom)
/datum/atom_hud/proc/show_hud_images_after_cooldown(M)
if(queued_to_see[M])
queued_to_see -= M
next_time_allowed[M] = world.time + ADD_HUD_TO_COOLDOWN
for(var/atom/A in hudatoms)
add_to_single_hud(M, A)
var/turf/hud_atom_turf = get_turf(hidden_atom)
/datum/atom_hud/proc/add_to_hud(atom/A)
if(!A)
return FALSE
hudatoms |= A
for(var/mob/M in hudusers)
if(!queued_to_see[M])
add_to_single_hud(M, A)
return TRUE
/datum/atom_hud/proc/add_to_single_hud(mob/M, atom/A) //unsafe, no sanity apart from client
if(!M || !M.client || !A)
if(!hud_atom_turf)
return
for(var/i in hud_icons)
if(A.hud_list[i] && (!hud_exceptions[M] || !(A in hud_exceptions[M])))
M.client.images |= A.hud_list[i]
if(hud_users[hud_atom_turf.z][hud_user])
add_atom_to_single_mob_hud(hud_user, hidden_atom)
/datum/atom_hud/proc/show_hud_images_after_cooldown(mob/queued_hud_user)
if(!queued_to_see[queued_hud_user])
return
queued_to_see -= queued_hud_user
next_time_allowed[queued_hud_user] = world.time + ADD_HUD_TO_COOLDOWN
var/turf/user_turf = get_turf(queued_hud_user)
if(!user_turf)
return
for(var/atom/hud_atom_to_show as anything in get_hud_atoms_for_z_level(user_turf.z))
add_atom_to_single_mob_hud(queued_hud_user, hud_atom_to_show)
//MOB PROCS
/mob/proc/reload_huds()
var/turf/our_turf = get_turf(src)
if(!our_turf)
return
for(var/datum/atom_hud/hud in GLOB.all_huds)
if(hud?.hudusers[src])
for(var/atom/A in hud.hudatoms)
hud.add_to_single_hud(src, A)
if(hud?.hud_users_all_z_levels[src])
for(var/atom/hud_atom as anything in hud.get_hud_atoms_for_z_level(our_turf.z))
hud.add_atom_to_single_mob_hud(src, hud_atom)
/mob/dead/new_player/reload_huds()
return
+6 -3
View File
@@ -52,11 +52,14 @@
var/static/default_martial_art = new/datum/martial_art
var/miming = FALSE // Mime's vow of silence
var/list/antag_datums
var/antag_hud_icon_state = null //this mind's ANTAG_HUD should have this icon_state
var/datum/atom_hud/alternate_appearance/basic/antagonist_hud/antag_hud = null //this mind's antag HUD
///this mind's ANTAG_HUD should have this icon_state
var/antag_hud_icon_state = null
///this mind's antag HUD
var/datum/atom_hud/alternate_appearance/basic/antagonist_hud/antag_hud = null
var/holy_role = NONE //is this person a chaplain or admin role allowed to use bibles, Any rank besides 'NONE' allows for this.
var/mob/living/enslaved_to //If this mind's master is another mob (i.e. adamantine golems)
///If this mind's master is another mob (i.e. adamantine golems)
var/mob/living/enslaved_to
var/datum/language_holder/language_holder
var/unconvertable = FALSE
var/late_joiner = FALSE
+2 -2
View File
@@ -146,7 +146,7 @@
return
our_lizard.adjust_fire_stacks(cone_levels)
our_lizard.IgniteMob()
our_lizard.ignite_mob()
to_chat(our_lizard, span_warning("Something in front of your mouth catches fire!"))
/obj/effect/proc_holder/spell/cone/staggered/firebreath/cast(list/targets, mob/user)
@@ -171,7 +171,7 @@
// The actual burn damage application is not blocked by fireproofing, like space dragons.
target_mob.apply_damage(max(10, 40 - (5 * level)), BURN, spread_damage = TRUE)
target_mob.adjust_fire_stacks(max(2, 5 - level))
target_mob.IgniteMob()
target_mob.ignite_mob()
/obj/effect/proc_holder/spell/cone/staggered/firebreath/do_obj_cone_effect(obj/target_obj, level)
// Further out objects experience less exposed_temperature and exposed_volume
+1 -1
View File
@@ -298,7 +298,7 @@
/datum/mutation/human/fire/on_life(delta_time, times_fired)
if(DT_PROB((0.05+(100-dna.stability)/19.5) * GET_MUTATION_SYNCHRONIZER(src), delta_time))
owner.adjust_fire_stacks(2 * GET_MUTATION_POWER(src))
owner.IgniteMob()
owner.ignite_mob()
/datum/mutation/human/fire/on_acquiring(mob/living/carbon/human/owner)
if(..())
+2 -2
View File
@@ -77,7 +77,7 @@
/datum/quirk/item_quirk/clown_enjoyer/add()
var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN]
fan.add_hud_to(quirk_holder)
fan.show_to(quirk_holder)
/datum/quirk/item_quirk/mime_fan
name = "Mime Fan"
@@ -94,7 +94,7 @@
/datum/quirk/item_quirk/mime_fan/add()
var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN]
fan.add_hud_to(quirk_holder)
fan.show_to(quirk_holder)
/datum/quirk/freerunning
name = "Freerunning"
+3 -3
View File
@@ -78,12 +78,12 @@
// Status effect process. Handles adjusting it's duration and ticks.
// If you're adding processed effects, put them in [proc/tick]
// instead of extending / overriding ththe process() proc.
/datum/status_effect/process(delta_time)
/datum/status_effect/process(delta_time, times_fired)
if(QDELETED(owner))
qdel(src)
return
if(tick_interval < world.time)
tick()
tick(delta_time, times_fired)
tick_interval = world.time + initial(tick_interval)
if(duration != -1 && duration < world.time)
qdel(src)
@@ -94,7 +94,7 @@
return TRUE
/// Called every tick from process().
/datum/status_effect/proc/tick()
/datum/status_effect/proc/tick(delta_time, times_fired)
return
/// Called whenever the buff expires or is removed (qdeleted)
@@ -40,7 +40,8 @@
// Create the status effect with our mob + our arguments
var/datum/status_effect/new_instance = new new_effect(arguments)
return new_instance
if(!QDELETED(new_instance))
return new_instance
/**
* Removes all instances of a given status effect from this mob
+4 -4
View File
@@ -238,15 +238,15 @@
//Makes the user passive, it's in their oath not to harm!
ADD_TRAIT(owner, TRAIT_PACIFISM, HIPPOCRATIC_OATH_TRAIT)
var/datum/atom_hud/H = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
H.add_hud_to(owner)
var/datum/atom_hud/med_hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
med_hud.show_to(owner)
return ..()
/datum/status_effect/hippocratic_oath/on_remove()
QDEL_NULL(aura_healing)
REMOVE_TRAIT(owner, TRAIT_PACIFISM, HIPPOCRATIC_OATH_TRAIT)
var/datum/atom_hud/H = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
H.remove_hud_from(owner)
var/datum/atom_hud/med_hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
med_hud.hide_from(owner)
/datum/status_effect/hippocratic_oath/tick()
if(owner.stat == DEAD)
@@ -0,0 +1,260 @@
/datum/status_effect/fire_handler
duration = -1
alert_type = null
status_type = STATUS_EFFECT_REFRESH //Custom code
on_remove_on_mob_delete = TRUE
tick_interval = 2 SECONDS
/// Current amount of stacks we have
var/stacks
/// Maximum of stacks that we could possibly get
var/stack_limit = 20
/// What status effect types do we remove uppon being applied. These are just deleted without any deduction from our or their stacks when forced.
var/list/enemy_types
/// What status effect types do we merge into if they exist. Ignored when forced.
var/list/merge_types
/// What status effect types do we override if they exist. These are simply deleted when forced.
var/list/override_types
/// For how much firestacks does one our stack count
var/stack_modifier = 1
/datum/status_effect/fire_handler/refresh(mob/living/new_owner, new_stacks, forced = FALSE)
if(forced)
set_stacks(new_stacks)
else
adjust_stacks(new_stacks)
/datum/status_effect/fire_handler/on_creation(mob/living/new_owner, new_stacks, forced = FALSE)
. = ..()
if(isanimal(owner))
qdel(src)
return
owner = new_owner
set_stacks(new_stacks)
for(var/enemy_type in enemy_types)
var/datum/status_effect/fire_handler/enemy_effect = owner.has_status_effect(enemy_type)
if(enemy_effect)
if(forced)
qdel(enemy_effect)
continue
var/cur_stacks = stacks
adjust_stacks(-enemy_effect.stacks * enemy_effect.stack_modifier / stack_modifier)
enemy_effect.adjust_stacks(-cur_stacks * stack_modifier / enemy_effect.stack_modifier)
if(enemy_effect.stacks <= 0)
qdel(enemy_effect)
if(stacks <= 0)
qdel(src)
return
if(!forced)
var/list/merge_effects = list()
for(var/merge_type in merge_types)
var/datum/status_effect/fire_handler/merge_effect = owner.has_status_effect(merge_type)
if(merge_effect)
merge_effects += merge_effects
if(LAZYLEN(merge_effects))
for(var/datum/status_effect/fire_handler/merge_effect in merge_effects)
merge_effect.adjust_stacks(stacks * stack_modifier / merge_effect.stack_modifier / LAZYLEN(merge_effects))
qdel(src)
return
for(var/override_type in override_types)
var/datum/status_effect/fire_handler/override_effect = owner.has_status_effect(override_type)
if(override_effect)
if(forced)
qdel(override_effect)
continue
adjust_stacks(override_effect.stacks)
qdel(override_effect)
/**
* Setter and adjuster procs for firestacks
*
* Arguments:
* - new_stacks
*
*/
/datum/status_effect/fire_handler/proc/set_stacks(new_stacks)
stacks = max(0, min(stack_limit, new_stacks))
cache_stacks()
/datum/status_effect/fire_handler/proc/adjust_stacks(new_stacks)
stacks = max(0, min(stack_limit, stacks + new_stacks))
cache_stacks()
/**
* Refresher for mob's fire_stacks
*/
/datum/status_effect/fire_handler/proc/cache_stacks()
owner.fire_stacks = 0
var/was_on_fire = owner.on_fire
owner.on_fire = FALSE
for(var/datum/status_effect/fire_handler/possible_fire in owner.status_effects)
owner.fire_stacks += possible_fire.stacks * possible_fire.stack_modifier
if(!istype(possible_fire, /datum/status_effect/fire_handler/fire_stacks))
continue
var/datum/status_effect/fire_handler/fire_stacks/our_fire = possible_fire
if(our_fire.on_fire)
owner.on_fire = TRUE
if(was_on_fire && !owner.on_fire)
owner.clear_alert(ALERT_FIRE)
else if(!was_on_fire && owner.on_fire)
owner.throw_alert(ALERT_FIRE, /atom/movable/screen/alert/fire)
/**
* Used to update owner's effect overlay
*/
/datum/status_effect/fire_handler/proc/update_overlay()
/datum/status_effect/fire_handler/fire_stacks
id = "fire_stacks" //fire_stacks and wet_stacks should have different IDs or else has_status_effect won't work
enemy_types = list(/datum/status_effect/fire_handler/wet_stacks)
stack_modifier = 1
/// If we're on fire
var/on_fire = FALSE
/// A weakref to the mob light emitter
var/datum/weakref/firelight_ref
/// Type of mob light emitter we use when on fire
var/firelight_type = /obj/effect/dummy/lighting_obj/moblight/fire
/// Stores current fire overlay icon state, for optimisation purposes
var/last_icon_state
/datum/status_effect/fire_handler/fire_stacks/tick(delta_time, times_fired)
if(stacks <= 0)
qdel(src)
return TRUE
if(!on_fire || isanimal(owner))
return TRUE
if(iscyborg(owner))
adjust_stacks(-0.55 * delta_time)
else
adjust_stacks(-0.05 * delta_time)
if(stacks <= 0)
qdel(src)
return TRUE
var/datum/gas_mixture/air = owner.loc.return_air()
if(!air.gases[/datum/gas/oxygen] || air.gases[/datum/gas/oxygen][MOLES] < 1)
qdel(src)
return TRUE
deal_damage(delta_time, times_fired)
update_overlay()
/**
* Proc that handles damage dealing and all special effects
*
* Arguments:
* - delta_time
* - times_fired
*
*/
/datum/status_effect/fire_handler/fire_stacks/proc/deal_damage(delta_time, times_fired)
owner.on_fire_stack(delta_time, times_fired, src)
var/turf/location = get_turf(owner)
location.hotspot_expose(700, 25 * delta_time, TRUE)
/**
* Used to deal damage to humans and count their protection.
*
* Arguments:
* - delta_time
* - times_fired
* - no_protection: When set to TRUE, fire will ignore any possible fire protection
*
*/
/datum/status_effect/fire_handler/fire_stacks/proc/harm_human(delta_time, times_fired, no_protection = FALSE)
var/mob/living/carbon/human/victim = owner
var/thermal_protection = victim.get_thermal_protection()
if(thermal_protection >= FIRE_IMMUNITY_MAX_TEMP_PROTECT && !no_protection)
return
if(thermal_protection >= FIRE_SUIT_MAX_TEMP_PROTECT && !no_protection)
victim.adjust_bodytemperature(5.5 * delta_time)
return
victim.adjust_bodytemperature((BODYTEMP_HEATING_MAX + (stacks * 12)) * 0.5 * delta_time)
SEND_SIGNAL(victim, COMSIG_ADD_MOOD_EVENT, "on_fire", /datum/mood_event/on_fire)
victim.mind?.add_memory(MEMORY_FIRE, list(DETAIL_PROTAGONIST = victim), story_value = STORY_VALUE_OKAY)
/**
* Handles mob ignition, should be the only way to set on_fire to TRUE
*
* Arguments:
* - silent: When set to TRUE, no message is displayed
*
*/
/datum/status_effect/fire_handler/fire_stacks/proc/ignite(silent = FALSE)
if(HAS_TRAIT(owner, TRAIT_NOFIRE))
return FALSE
on_fire = TRUE
if(!silent)
owner.visible_message(span_warning("[owner] catches fire!"), span_userdanger("You're set on fire!"))
if(firelight_type)
firelight_ref = WEAKREF(new firelight_type(owner))
SEND_SIGNAL(owner, COMSIG_LIVING_IGNITED, owner)
cache_stacks()
update_overlay()
/**
* Handles mob extinguishing, should be the only way to set on_fire to FALSE
*/
/datum/status_effect/fire_handler/fire_stacks/proc/extinguish()
if(firelight_ref)
qdel(firelight_ref)
on_fire = FALSE
SEND_SIGNAL(owner, COMSIG_CLEAR_MOOD_EVENT, "on_fire")
SEND_SIGNAL(owner, COMSIG_LIVING_EXTINGUISHED, owner)
cache_stacks()
update_overlay()
/datum/status_effect/fire_handler/fire_stacks/on_remove()
if(on_fire)
extinguish()
set_stacks(0)
update_overlay()
/datum/status_effect/fire_handler/fire_stacks/update_overlay()
last_icon_state = owner.update_fire_overlay(stacks, on_fire, last_icon_state)
/datum/status_effect/fire_handler/fire_stacks/on_apply()
. = ..()
update_overlay()
/datum/status_effect/fire_handler/wet_stacks
id = "wet_stacks"
enemy_types = list(/datum/status_effect/fire_handler/fire_stacks)
stack_modifier = -1
/datum/status_effect/fire_handler/wet_stacks/tick(delta_time)
adjust_stacks(-0.5 * delta_time)
if(stacks <= 0)
qdel(src)
+1 -1
View File
@@ -213,7 +213,7 @@ GLOBAL_LIST_INIT(voice_of_god_commands, init_voice_of_god_commands())
/datum/voice_of_god_command/burn/execute(list/listeners, mob/living/user, power_multiplier = 1, message)
for(var/mob/living/target as anything in listeners)
target.adjust_fire_stacks(1 * power_multiplier)
target.IgniteMob()
target.ignite_mob()
/// This command heats the listeners up like boiling water.
/datum/voice_of_god_command/hot
+18 -12
View File
@@ -5,7 +5,7 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances)
for(var/K in alternate_appearances)
var/datum/atom_hud/alternate_appearance/AA = alternate_appearances[K]
if(AA.appearance_key == key)
AA.remove_from_hud(src)
AA.remove_atom_from_hud(src)
break
/atom/proc/add_alt_appearance(type, key, ...)
@@ -24,13 +24,16 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances)
var/transfer_overlays = FALSE
/datum/atom_hud/alternate_appearance/New(key)
..()
GLOB.active_alternate_appearances += src
// We use hud_icons to register our hud, so we need to do this before the parent call
appearance_key = key
hud_icons = list(appearance_key)
..()
GLOB.active_alternate_appearances += src
for(var/mob in GLOB.player_list)
if(mobShouldSee(mob))
add_hud_to(mob)
show_to(mob)
/datum/atom_hud/alternate_appearance/Destroy()
GLOB.active_alternate_appearances -= src
@@ -38,18 +41,18 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances)
/datum/atom_hud/alternate_appearance/proc/onNewMob(mob/M)
if(mobShouldSee(M))
add_hud_to(M)
show_to(M)
/datum/atom_hud/alternate_appearance/proc/mobShouldSee(mob/M)
return FALSE
/datum/atom_hud/alternate_appearance/add_to_hud(atom/A, image/I)
/datum/atom_hud/alternate_appearance/add_atom_to_hud(atom/A, image/I)
. = ..()
if(.)
LAZYINITLIST(A.alternate_appearances)
A.alternate_appearances[appearance_key] = src
/datum/atom_hud/alternate_appearance/remove_from_hud(atom/A)
/datum/atom_hud/alternate_appearance/remove_atom_from_hud(atom/A)
. = ..()
if(.)
LAZYREMOVE(A.alternate_appearances, appearance_key)
@@ -63,6 +66,7 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances)
var/image/image
var/add_ghost_version = FALSE
var/ghost_appearance
uses_global_hud_category = FALSE
/datum/atom_hud/alternate_appearance/basic/New(key, image/I, options = AA_TARGET_SEE_APPEARANCE)
..()
@@ -72,10 +76,11 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances)
if(transfer_overlays)
I.copy_overlays(target)
hud_icons = list(appearance_key)
add_to_hud(target, I)
add_atom_to_hud(target)
target.set_hud_image_active(appearance_key, exclusive_hud = src)
if((options & AA_TARGET_SEE_APPEARANCE) && ismob(target))
add_hud_to(target)
show_to(target)
if(add_ghost_version)
var/image/ghost_image = image(icon = I.icon , icon_state = I.icon_state, loc = I.loc)
ghost_image.override = FALSE
@@ -89,14 +94,15 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances)
if(ghost_appearance)
QDEL_NULL(ghost_appearance)
/datum/atom_hud/alternate_appearance/basic/add_to_hud(atom/A)
/datum/atom_hud/alternate_appearance/basic/add_atom_to_hud(atom/A)
LAZYINITLIST(A.hud_list)
A.hud_list[appearance_key] = image
. = ..()
/datum/atom_hud/alternate_appearance/basic/remove_from_hud(atom/A)
/datum/atom_hud/alternate_appearance/basic/remove_atom_from_hud(atom/A)
. = ..()
A.hud_list -= appearance_key
A.set_hud_image_inactive(appearance_key)
if(. && !QDELETED(src))
qdel(src)
+6 -2
View File
@@ -30,8 +30,12 @@
///Reagents holder
var/datum/reagents/reagents = null
///This atom's HUD (med/sec, etc) images. Associative list.
///all of this atom's HUD (med/sec, etc) images. Associative list of the form: list(hud category = hud image or images for that category).
///most of the time hud category is associated with a single image, sometimes its associated with a list of images.
///not every hud in this list is actually used. for ones available for others to see, look at active_hud_list.
var/list/image/hud_list = null
///all of this atom's HUD images which can actually be seen by players with that hud
var/list/image/active_hud_list = null
///HUD images that this atom can provide.
var/list/hud_possible
@@ -300,7 +304,7 @@
if(alternate_appearances)
for(var/current_alternate_appearance in alternate_appearances)
var/datum/atom_hud/alternate_appearance/selected_alternate_appearance = alternate_appearances[current_alternate_appearance]
selected_alternate_appearance.remove_from_hud(src)
selected_alternate_appearance.remove_atom_from_hud(src)
if(reagents)
QDEL_NULL(reagents)
+1 -1
View File
@@ -850,7 +850,7 @@
var/turf/our_turf = get_turf(src)
if(our_turf && SSspatial_grid.initialized)
SSspatial_grid.exit_cell(src, our_turf, RECURSIVE_CONTENTS_CLIENT_MOBS)
SSspatial_grid.remove_single_contents_type(src, our_turf, RECURSIVE_CONTENTS_CLIENT_MOBS)
else if(our_turf && !SSspatial_grid.initialized)
SSspatial_grid.remove_from_pre_init_queue(src, RECURSIVE_CONTENTS_CLIENT_MOBS)
+55 -25
View File
@@ -9,11 +9,11 @@
/atom/proc/add_to_all_human_data_huds()
for(var/datum/atom_hud/data/human/hud in GLOB.huds)
hud.add_to_hud(src)
hud.add_atom_to_hud(src)
/atom/proc/remove_from_all_data_huds()
for(var/datum/atom_hud/data/hud in GLOB.huds)
hud.remove_from_hud(src)
hud.remove_atom_from_hud(src)
/datum/atom_hud/data
@@ -32,12 +32,12 @@
return FALSE
return TRUE
/datum/atom_hud/data/human/medical/basic/add_to_single_hud(mob/M, mob/living/carbon/H)
/datum/atom_hud/data/human/medical/basic/add_atom_to_single_mob_hud(mob/M, mob/living/carbon/H)
if(check_sensors(H))
..()
/datum/atom_hud/data/human/medical/basic/proc/update_suit_sensors(mob/living/carbon/H)
check_sensors(H) ? add_to_hud(H) : remove_from_hud(H)
check_sensors(H) ? add_atom_to_hud(H) : remove_atom_from_hud(H)
/datum/atom_hud/data/human/medical/advanced
@@ -61,6 +61,8 @@
hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_CIRCUIT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_LAUNCHPAD_HUD, DIAG_PATH_HUD)
/datum/atom_hud/data/bot_path
// This hud exists so the bot can see itself, that's all
uses_global_hud_category = FALSE
hud_icons = list(DIAG_PATH_HUD)
/datum/atom_hud/abductor
@@ -72,12 +74,12 @@
/datum/atom_hud/ai_detector
hud_icons = list(AI_DETECT_HUD)
/datum/atom_hud/ai_detector/add_hud_to(mob/M)
/datum/atom_hud/ai_detector/show_to(mob/new_viewer)
..()
if(M && (hudusers.len == 1))
for(var/V in GLOB.aiEyes)
var/mob/camera/ai_eye/E = V
E.update_ai_detect_hud()
if(!new_viewer || hud_users.len != 1)
return
for(var/mob/camera/ai_eye/eye as anything in GLOB.aiEyes)
eye.update_ai_detect_hud()
/* MED/SEC/DIAG HUD HOOKS */
@@ -231,11 +233,19 @@ FAN HUDs! For identifying other fans on-sight.
holder.pixel_y = I.Height() - world.icon_size
holder.icon_state = "hudfan_no"
var/obj/item/clothing/under/U = get_item_by_slot(ITEM_SLOT_ICLOTHING)
if(U)
if(istype(U.attached_accessory, /obj/item/clothing/accessory/mime_fan_pin))
holder.icon_state = "mime_fan_pin"
else if(istype(U.attached_accessory, /obj/item/clothing/accessory/clown_enjoyer_pin))
holder.icon_state = "clown_enjoyer_pin"
if(!U)
set_hud_image_inactive(FAN_HUD)
return
if(istype(U.attached_accessory, /obj/item/clothing/accessory/mime_fan_pin))
holder.icon_state = "mime_fan_pin"
else if(istype(U.attached_accessory, /obj/item/clothing/accessory/clown_enjoyer_pin))
holder.icon_state = "clown_enjoyer_pin"
set_hud_image_active(FAN_HUD)
return
/***********************************************
Security HUDs! Basic mode shows only the job.
@@ -266,22 +276,29 @@ Security HUDs! Basic mode shows only the job.
for(var/i in list(IMPTRACK_HUD, IMPLOYAL_HUD, IMPCHEM_HUD))
holder = hud_list[i]
holder.icon_state = null
set_hud_image_inactive(i)
for(var/obj/item/implant/I in implants)
if(istype(I, /obj/item/implant/tracking))
holder = hud_list[IMPTRACK_HUD]
var/icon/IC = icon(icon, icon_state, dir)
holder.pixel_y = IC.Height() - world.icon_size
holder.icon_state = "hud_imp_tracking"
set_hud_image_active(IMPTRACK_HUD)
else if(istype(I, /obj/item/implant/chem))
holder = hud_list[IMPCHEM_HUD]
var/icon/IC = icon(icon, icon_state, dir)
holder.pixel_y = IC.Height() - world.icon_size
holder.icon_state = "hud_imp_chem"
set_hud_image_active(IMPCHEM_HUD)
if(HAS_TRAIT(src, TRAIT_MINDSHIELD))
holder = hud_list[IMPLOYAL_HUD]
var/icon/IC = icon(icon, icon_state, dir)
holder.pixel_y = IC.Height() - world.icon_size
holder.icon_state = "hud_imp_loyal"
set_hud_image_active(IMPLOYAL_HUD)
/mob/living/carbon/human/proc/sec_hud_set_security_status()
var/image/holder = hud_list[WANTED_HUD]
@@ -291,23 +308,26 @@ Security HUDs! Basic mode shows only the job.
if(perpname && GLOB.data_core)
var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.security)
if(R)
var/has_criminal_entry = TRUE
switch(R.fields["criminal"])
if("*Arrest*")
holder.icon_state = "hudwanted"
return
if("Incarcerated")
holder.icon_state = "hudincarcerated"
return
if("Suspected")
holder.icon_state = "hudsuspected"
return
if("Paroled")
holder.icon_state = "hudparolled"
return
if("Discharged")
holder.icon_state = "huddischarged"
return
else
has_criminal_entry = FALSE
if(has_criminal_entry)
set_hud_image_active(WANTED_HUD)
return
holder.icon_state = null
set_hud_image_inactive(WANTED_HUD)
/***********************************************
Diagnostic HUDs!
@@ -371,10 +391,13 @@ Diagnostic HUDs!
holder.pixel_y = I.Height() - world.icon_size
if(!shell) //Not an AI shell
holder.icon_state = null
set_hud_image_inactive(DIAG_TRACK_HUD)
return
else if(deployed) //AI shell in use by an AI
holder.icon_state = "hudtrackingai"
else //Empty AI shell
holder.icon_state = "hudtracking"
set_hud_image_active(DIAG_TRACK_HUD)
//AI side tracking of AI shell control
/mob/living/silicon/ai/proc/diag_hud_set_deployed() //Shows tracking beacons on the mech
@@ -383,8 +406,10 @@ Diagnostic HUDs!
holder.pixel_y = I.Height() - world.icon_size
if(!deployed_shell)
holder.icon_state = null
set_hud_image_inactive(DIAG_TRACK_HUD)
else //AI is currently controlling a shell
holder.icon_state = "hudtrackingai"
set_hud_image_active(DIAG_TRACK_HUD)
/*~~~~~~~~~~~~~~~~~~~~
BIG STOMPY MECHS
@@ -411,11 +436,14 @@ Diagnostic HUDs!
var/image/holder = hud_list[DIAG_STAT_HUD]
var/icon/I = icon(icon, icon_state, dir)
holder.pixel_y = I.Height() - world.icon_size
holder.icon_state = null
if(internal_damage)
holder.icon_state = "hudwarn"
set_hud_image_active(DIAG_STAT_HUD)
holder.icon_state = null
set_hud_image_inactive(DIAG_STAT_HUD)
/obj/vehicle/sealed/mecha/proc/diag_hud_set_mechtracking() //Shows tracking beacons on the mech
///Shows tracking beacons on the mech
/obj/vehicle/sealed/mecha/proc/diag_hud_set_mechtracking()
var/image/holder = hud_list[DIAG_TRACK_HUD]
var/icon/I = icon(icon, icon_state, dir)
holder.pixel_y = I.Height() - world.icon_size
@@ -484,8 +512,10 @@ Diagnostic HUDs!
Airlocks!
~~~~~~~~~~~~~*/
/obj/machinery/door/airlock/proc/diag_hud_set_electrified()
if(secondsElectrified == MACHINE_NOT_ELECTRIFIED)
set_hud_image_inactive(DIAG_AIRLOCK_HUD)
return
var/image/holder = hud_list[DIAG_AIRLOCK_HUD]
if(secondsElectrified != MACHINE_NOT_ELECTRIFIED)
holder.icon_state = "electrified"
else
holder.icon_state = ""
holder.icon_state = "electrified"
set_hud_image_active(DIAG_AIRLOCK_HUD)
+1 -1
View File
@@ -368,7 +368,7 @@ GLOBAL_LIST_INIT(orion_events, generate_orion_events())
reason = "You ran out of fuel, and drift, slowly, into a star."
if(obj_flags & EMAGGED)
gamer.adjust_fire_stacks(5)
gamer.IgniteMob() //flew into a star, so you're on fire
gamer.ignite_mob() //flew into a star, so you're on fire
to_chat(gamer, span_userdanger("You feel an immense wave of heat emanate from the arcade machine. Your skin bursts into flames."))
if(obj_flags & EMAGGED)
+4 -2
View File
@@ -179,9 +179,11 @@
max_integrity = normal_integrity
if(damage_deflection == AIRLOCK_DAMAGE_DEFLECTION_N && security_level > AIRLOCK_SECURITY_IRON)
damage_deflection = AIRLOCK_DAMAGE_DEFLECTION_R
prepare_huds()
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
diag_hud.add_to_hud(src)
diag_hud.add_atom_to_hud(src)
diag_hud_set_electrified()
RegisterSignal(src, COMSIG_MACHINERY_BROKEN, .proc/on_break)
@@ -351,7 +353,7 @@
QDEL_NULL(note)
QDEL_NULL(seal)
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
diag_hud.remove_from_hud(src)
diag_hud.remove_atom_from_hud(src)
return ..()
/obj/machinery/door/airlock/handle_atom_del(atom/A)
+2 -2
View File
@@ -35,7 +35,7 @@
. = ..()
prepare_huds()
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
diag_hud.add_to_hud(src)
diag_hud.add_atom_to_hud(src)
var/image/holder = hud_list[DIAG_LAUNCHPAD_HUD]
var/mutable_appearance/MA = new /mutable_appearance()
@@ -49,7 +49,7 @@
/obj/machinery/launchpad/Destroy()
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
diag_hud.remove_from_hud(src)
diag_hud.remove_atom_from_hud(src)
return ..()
/obj/machinery/launchpad/examine(mob/user)
+1 -1
View File
@@ -131,7 +131,7 @@
if(.)
if(resistance_flags & ON_FIRE) //Sets the mob on fire if you buckle them to a burning atom/movableect
M.adjust_fire_stacks(1)
M.IgniteMob()
M.ignite_mob()
/**
* Set a mob as unbuckled from src
@@ -69,7 +69,7 @@
/obj/effect/particle_effect/foam/firefighting/foam_mob(mob/living/L)
if(!istype(L))
return
L.adjust_fire_stacks(-2)
L.adjust_wet_stacks(2)
/obj/effect/particle_effect/foam/metal
name = "aluminium foam"
+1 -1
View File
@@ -731,7 +731,7 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/e
SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum)
if(get_temperature() && isliving(hit_atom))
var/mob/living/L = hit_atom
L.IgniteMob()
L.ignite_mob()
var/itempush = 1
if(w_class < 4)
itempush = 0 //too light to push anything
+5 -5
View File
@@ -88,7 +88,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(!isliving(M))
return
if(lit && M.IgniteMob())
if(lit && M.ignite_mob())
message_admins("[ADMIN_LOOKUPFLW(user)] set [key_name_admin(M)] on fire with [src] at [AREACOORD(user)]")
log_game("[key_name(user)] set [key_name(M)] on fire with [src] at [AREACOORD(user)]")
@@ -323,7 +323,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/clothing/mask/cigarette/process(delta_time)
var/mob/living/user = isliving(loc) ? loc : null
user?.IgniteMob()
user?.ignite_mob()
if(!reagents.has_reagent(/datum/reagent/oxygen)) //cigarettes need oxygen
var/datum/gas_mixture/air = return_air()
if(!air || !air.has_gas(/datum/gas/oxygen, 1)) //or oxygen on a tile to burn
@@ -818,7 +818,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/lighter/attack(mob/living/carbon/M, mob/living/carbon/user)
if(lit && M.IgniteMob())
if(lit && M.ignite_mob())
message_admins("[ADMIN_LOOKUPFLW(user)] set [key_name_admin(M)] on fire with [src] at [AREACOORD(user)]")
log_game("[key_name(user)] set [key_name(M)] on fire with [src] at [AREACOORD(user)]")
var/obj/item/clothing/mask/cigarette/cig = help_light_cig(M)
@@ -1042,7 +1042,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(reagents.get_reagent_amount(/datum/reagent/fuel))
//HOT STUFF
vaper.adjust_fire_stacks(2)
vaper.IgniteMob()
vaper.ignite_mob()
if(reagents.get_reagent_amount(/datum/reagent/toxin/plasma)) // the plasma explodes when exposed to fire
var/datum/effect_system/reagents_explosion/e = new()
@@ -1057,7 +1057,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
var/mob/living/M = loc
if(isliving(loc))
M.IgniteMob()
M.ignite_mob()
if(!reagents.total_volume)
if(ismob(loc))
+3 -3
View File
@@ -108,8 +108,8 @@
var/atom/movable/screen/plane_master/camera_static/ai_detect_plane = user.hud_used.plane_masters["[CAMERA_STATIC_PLANE]"]
ai_detect_plane.alpha = 64
var/datum/atom_hud/hud = GLOB.huds[hud_type]
if(!hud.hudusers[user])
hud.add_hud_to(user)
if(!hud.hud_users[user])
hud.show_to(user)
eye.eye_user = user
eye.setLoc(get_turf(src))
@@ -118,7 +118,7 @@
var/atom/movable/screen/plane_master/camera_static/ai_detect_plane = user.hud_used.plane_masters["[CAMERA_STATIC_PLANE]"]
ai_detect_plane.alpha = 255
var/datum/atom_hud/hud = GLOB.huds[hud_type]
hud.remove_hud_from(user)
hud.hide_from(user)
if(eye)
eye.setLoc(null)
eye.eye_user = null
+2 -2
View File
@@ -153,7 +153,7 @@
if(isOn() && !QDELETED(attacked_atom) && isliving(attacked_atom)) // can't ignite something that doesn't exist
handle_fuel_and_temps(1, user)
var/mob/living/attacked_mob = attacked_atom
if(attacked_mob.IgniteMob())
if(attacked_mob.ignite_mob())
message_admins("[ADMIN_LOOKUPFLW(user)] set [key_name_admin(attacked_mob)] on fire with [src] at [AREACOORD(user)]")
log_game("[key_name(user)] set [key_name(attacked_mob)] on fire with [src] at [AREACOORD(user)]")
@@ -172,7 +172,7 @@
if(!QDELETED(attacked_atom) && isliving(attacked_atom)) // can't ignite something that doesn't exist
var/mob/living/attacked_mob = attacked_atom
if(attacked_mob.IgniteMob())
if(attacked_mob.ignite_mob())
message_admins("[ADMIN_LOOKUPFLW(user)] set [key_name_admin(attacked_mob)] on fire with [src] at [AREACOORD(user)]")
log_game("[key_name(user)] set [key_name(attacked_mob)] on fire with [src] at [AREACOORD(user)]")
+1 -1
View File
@@ -145,7 +145,7 @@
else if(isliving(burn_target))
var/mob/living/burn_victim = burn_target
burn_victim.adjust_fire_stacks(BONFIRE_FIRE_STACK_STRENGTH * 0.5 * delta_time)
burn_victim.IgniteMob()
burn_victim.ignite_mob()
else if(isobj(burn_target))
var/obj/burned_object = burn_target
if(grill && isitem(burned_object))
+1 -1
View File
@@ -220,7 +220,7 @@
burn_living.adjustFireLoss(lava_damage * delta_time)
if(!QDELETED(burn_living)) //mobs turning into object corpses could get deleted here.
burn_living.adjust_fire_stacks(lava_firestacks * delta_time)
burn_living.IgniteMob()
burn_living.ignite_mob()
/turf/open/lava/smooth
name = "lava"
+4 -4
View File
@@ -385,10 +385,10 @@ Traitors and the like can also be revived with the previous role mostly intact.
for (var/hudtype in list(DATA_HUD_SECURITY_ADVANCED, DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC_ADVANCED))
var/datum/atom_hud/atom_hud = GLOB.huds[hudtype]
atom_hud.add_hud_to(mob)
atom_hud.show_to(mob)
for (var/datum/atom_hud/alternate_appearance/basic/antagonist_hud/antag_hud in GLOB.active_alternate_appearances)
antag_hud.add_hud_to(mob)
antag_hud.show_to(mob)
mob.lighting_alpha = mob.default_lighting_alpha()
mob.update_sight()
@@ -401,10 +401,10 @@ Traitors and the like can also be revived with the previous role mostly intact.
for (var/hudtype in list(DATA_HUD_SECURITY_ADVANCED, DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC_ADVANCED))
var/datum/atom_hud/atom_hud = GLOB.huds[hudtype]
atom_hud.remove_hud_from(mob)
atom_hud.hide_from(mob)
for (var/datum/atom_hud/alternate_appearance/basic/antagonist_hud/antag_hud in GLOB.active_alternate_appearances)
antag_hud.remove_hud_from(mob)
antag_hud.hide_from(mob)
mob.lighting_alpha = mob.default_lighting_alpha()
mob.update_sight()
@@ -220,7 +220,7 @@ GLOBAL_LIST_EMPTY(antagonists)
var/mob/living/current = owner.current
for (var/datum/atom_hud/alternate_appearance/basic/has_antagonist/antag_hud as anything in GLOB.has_antagonist_huds)
if (!antag_hud.mobShouldSee(current))
antag_hud.remove_hud_from(current)
antag_hud.hide_from(current)
qdel(src)
// SKYRAT EDIT START
@@ -428,7 +428,7 @@ GLOBAL_LIST_EMPTY(antagonists)
// Add HUDs that they couldn't see before
for (var/datum/atom_hud/alternate_appearance/basic/has_antagonist/antag_hud as anything in GLOB.has_antagonist_huds)
if (antag_hud.mobShouldSee(owner.current))
antag_hud.add_hud_to(owner.current)
antag_hud.show_to(owner.current)
//This one is created by admin tools for custom objectives
/datum/antagonist/custom
@@ -85,7 +85,7 @@
if(initial(uses) == 1)
uses = initial(uses)
var/datum/atom_hud/abductor/hud = GLOB.huds[DATA_HUD_ABDUCTOR]
hud.remove_from_hud(owner)
hud.remove_atom_from_hud(owner)
clear_mind_control()
..()
@@ -94,7 +94,7 @@
if(special != 2 && uses) // Special 2 means abductor surgery
Start()
var/datum/atom_hud/abductor/hud = GLOB.huds[DATA_HUD_ABDUCTOR]
hud.add_to_hud(owner)
hud.add_atom_to_hud(owner)
update_gland_hud()
/obj/item/organ/heart/gland/on_life(delta_time, times_fired)
@@ -36,7 +36,7 @@
. = ..()
reac_volume = return_mob_expose_reac_volume(exposed_mob, methods, reac_volume, show_message, touch_protection, overmind)
exposed_mob.adjust_fire_stacks(round(reac_volume/10))
exposed_mob.IgniteMob()
exposed_mob.ignite_mob()
if(exposed_mob)
exposed_mob.apply_damage(0.8*reac_volume, BURN, wound_bonus=CANT_WOUND)
if(iscarbon(exposed_mob))
@@ -31,7 +31,7 @@
for(var/obj/O in T)
O.extinguish()
for(var/mob/living/L in T)
L.adjust_fire_stacks(-2.5)
L.adjust_wet_stacks(2.5)
L.extinguish_mob()
/datum/reagent/blob/pressurized_slime
@@ -45,7 +45,7 @@
var/turf/open/location_turf = get_turf(exposed_mob)
if(istype(location_turf) && prob(reac_volume))
location_turf.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
exposed_mob.adjust_fire_stacks(-(reac_volume / 10))
exposed_mob.adjust_wet_stacks(reac_volume / 10)
exposed_mob.apply_damage(0.4*reac_volume, BRUTE, wound_bonus=CANT_WOUND)
if(exposed_mob)
exposed_mob.adjustStaminaLoss(reac_volume, FALSE)
@@ -317,7 +317,7 @@
/obj/structure/blob/examine(mob/user)
. = ..()
var/datum/atom_hud/hud_to_check = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
if(HAS_TRAIT(user, TRAIT_RESEARCH_SCANNER) || hud_to_check.hudusers[user])
if(HAS_TRAIT(user, TRAIT_RESEARCH_SCANNER) || hud_to_check.hud_users[user])
. += "<b>Your HUD displays an extensive report...</b><br>"
if(overmind)
. += overmind.blobstrain.examine(user)
+10 -4
View File
@@ -941,6 +941,7 @@ structure_check() searches for nearby cultist structures required for the invoca
if(rune_in_use)
return
. = ..()
var/area/place = get_area(src)
var/mob/living/user = invokers[1]
var/datum/antagonist/cult/user_antag = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
@@ -951,8 +952,10 @@ structure_check() searches for nearby cultist structures required for the invoca
if(!(place in summon_objective.summon_spots))
to_chat(user, span_cultlarge("The Apocalypse rune will remove a ritual site, where Nar'Sie can be summoned, it can only be scribed in [english_list(summon_objective.summon_spots)]!"))
return
summon_objective.summon_spots -= place
rune_in_use = TRUE
var/turf/T = get_turf(src)
new /obj/effect/temp_visual/dir_setting/curse/grasp_portal/fading(T)
var/intensity = 0
@@ -961,20 +964,23 @@ structure_check() searches for nearby cultist structures required for the invoca
intensity++
intensity = max(60, 360 - (360*(intensity/length(GLOB.player_list) + 0.3)**2)) //significantly lower intensity for "winning" cults
var/duration = intensity*10
playsound(T, 'sound/magic/enter_blood.ogg', 100, TRUE)
visible_message(span_warning("A colossal shockwave of energy bursts from the rune, disintegrating it in the process!"))
for(var/mob/living/target in range(src, 3))
target.Paralyze(30)
empulse(T, 0.42*(intensity), 1)
var/list/images = list()
var/zmatch = T.z
var/datum/atom_hud/AH = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
var/datum/atom_hud/sec_hud = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
for(var/mob/living/M in GLOB.alive_mob_list)
if(M.z != zmatch)
continue
if(ishuman(M))
if(!IS_CULTIST(M))
AH.remove_hud_from(M)
sec_hud.hide_from(M)
addtimer(CALLBACK(GLOBAL_PROC, .proc/hudFix, M), duration)
var/image/A = image('icons/mob/cult.dmi',M,"cultist", ABOVE_MOB_LAYER)
A.override = 1
@@ -1066,5 +1072,5 @@ structure_check() searches for nearby cultist structures required for the invoca
return
var/obj/O = target.get_item_by_slot(ITEM_SLOT_EYES)
if(istype(O, /obj/item/clothing/glasses/hud/security))
var/datum/atom_hud/AH = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
AH.add_hud_to(target)
var/datum/atom_hud/sec_hud = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
sec_hud.show_to(target)
@@ -66,7 +66,7 @@ the new instance inside the host to be updated to the template's stats.
SSdisease.archive_diseases[disease_template.GetDiseaseID()] = disease_template //important for stuff that uses disease IDs
var/datum/atom_hud/my_hud = GLOB.huds[DATA_HUD_SENTIENT_DISEASE]
my_hud.add_hud_to(src)
my_hud.show_to(src)
browser = new /datum/browser(src, "disease_menu", "Adaptation Menu", 1000, 770, src)
@@ -163,7 +163,7 @@ the new instance inside the host to be updated to the template's stats.
if(!mind.has_antag_datum(/datum/antagonist/disease))
mind.add_antag_datum(/datum/antagonist/disease)
var/datum/atom_hud/medsensor = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
medsensor.add_hud_to(src)
medsensor.show_to(src)
/mob/camera/disease/proc/pick_name()
var/static/list/taken_names
@@ -255,7 +255,7 @@ the new instance inside the host to be updated to the template's stats.
MA.alpha = 200
holder.appearance = MA
var/datum/atom_hud/my_hud = GLOB.huds[DATA_HUD_SENTIENT_DISEASE]
my_hud.add_to_hud(V.affected_mob)
my_hud.add_atom_to_hud(V.affected_mob)
to_chat(src, span_notice("A new host, <b>[V.affected_mob.real_name]</b>, has been infected."))
@@ -271,7 +271,7 @@ the new instance inside the host to be updated to the template's stats.
to_chat(src, span_notice("One of your hosts, <b>[V.affected_mob.real_name]</b>, has been purged of your infection."))
var/datum/atom_hud/my_hud = GLOB.huds[DATA_HUD_SENTIENT_DISEASE]
my_hud.remove_from_hud(V.affected_mob)
my_hud.remove_atom_from_hud(V.affected_mob)
if(following_host == V.affected_mob)
follow_next()
@@ -146,7 +146,7 @@
return
target.adjust_fire_stacks(1)
target.IgniteMob()
target.ignite_mob()
/datum/heretic_knowledge/spell/flame_birth
name = "Nightwater's Rebirth"
@@ -61,7 +61,7 @@
*/
/datum/status_effect/unholy_determination/proc/adjust_all_damages(amount)
owner.set_fire_stacks(max(owner.fire_stacks - 1, 0))
owner.adjust_fire_stacks(-1)
owner.losebreath = max(owner.losebreath - 0.5, 0)
owner.adjustToxLoss(-amount, FALSE, TRUE)
+1 -1
View File
@@ -15,7 +15,7 @@
/obj/item/assembly/igniter/suicide_act(mob/living/carbon/user)
user.visible_message(span_suicide("[user] is trying to ignite [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!"))
user.IgniteMob()
user.ignite_mob()
return FIRELOSS
/obj/item/assembly/igniter/Initialize(mapload)
@@ -57,8 +57,8 @@
///The bitflag that's being checked on ventcrawling. Default is to allow ventcrawling and seeing pipes.
var/vent_movement = VENTCRAWL_ALLOWED | VENTCRAWL_CAN_SEE
///keeps the name of the object from being overridden if it's vareditted.
///keeps the name of the object from being overridden if it's vareditted.
var/override_naming
/obj/machinery/atmospherics/LateInitialize()
@@ -89,7 +89,7 @@
/obj/machinery/atmospherics/Initialize(mapload)
if(mapload && name != initial(name))
override_naming = TRUE
return ..()
return ..()
/obj/machinery/atmospherics/Destroy()
for(var/i in 1 to device_type)
@@ -6,7 +6,7 @@
requires_power = FALSE
static_lighting = FALSE
base_lighting_alpha = 255
/area/awaymission/snowdin/outside
name = "Snowdin Tundra Plains"
icon_state = "awaycontent25"
@@ -219,7 +219,7 @@
burn_human.visible_message(span_warning("[burn_human]'s [burn_limb.name] melts down to the bone!"), \
span_userdanger("You scream out in pain as your [burn_limb.name] melts down to the bone, leaving an eerie plasma-like glow where flesh used to be!"))
if(!plasma_parts.len && !robo_parts.len) //a person with no potential organic limbs left AND no robotic limbs, time to turn them into a plasmaman
burn_human.IgniteMob()
burn_human.ignite_mob()
burn_human.set_species(/datum/species/plasmaman)
burn_human.visible_message(span_warning("[burn_human] bursts into a brilliant purple flame as [burn_human.p_their()] entire body is that of a skeleton!"), \
span_userdanger("Your senses numb as all of your remaining flesh is turned into a purple slurry, sloshing off your body and leaving only your bones to show in a vibrant purple!"))
-1
View File
@@ -1164,7 +1164,6 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
holder.filteriffic = new /datum/filter_editor(in_atom)
holder.filteriffic.ui_interact(mob)
/client/proc/set_right_click_menu_mode(shift_only)
if(shift_only)
winset(src, "mapwindow.map", "right-click=true")
+4 -4
View File
@@ -551,8 +551,8 @@
return
if(ishuman(user))
for(var/hud in hudlist)
var/datum/atom_hud/H = GLOB.huds[hud]
H.add_hud_to(user)
var/datum/atom_hud/our_hud = GLOB.huds[hud]
our_hud.show_to(user)
ADD_TRAIT(user, TRAIT_MEDICAL_HUD, GLASSES_TRAIT)
ADD_TRAIT(user, TRAIT_SECURITY_HUD, GLASSES_TRAIT)
@@ -562,8 +562,8 @@
REMOVE_TRAIT(user, TRAIT_SECURITY_HUD, GLASSES_TRAIT)
if(ishuman(user))
for(var/hud in hudlist)
var/datum/atom_hud/H = GLOB.huds[hud]
H.remove_hud_from(user)
var/datum/atom_hud/our_hud = GLOB.huds[hud]
our_hud.hide_from(user)
/obj/item/clothing/glasses/debug/AltClick(mob/user)
. = ..()
+8 -8
View File
@@ -11,8 +11,8 @@
if(slot != ITEM_SLOT_EYES)
return
if(hud_type)
var/datum/atom_hud/H = GLOB.huds[hud_type]
H.add_hud_to(user)
var/datum/atom_hud/our_hud = GLOB.huds[hud_type]
our_hud.show_to(user)
if(hud_trait)
ADD_TRAIT(user, hud_trait, GLASSES_TRAIT)
@@ -21,8 +21,8 @@
if(!istype(user) || user.glasses != src)
return
if(hud_type)
var/datum/atom_hud/H = GLOB.huds[hud_type]
H.remove_hud_from(user)
var/datum/atom_hud/our_hud = GLOB.huds[hud_type]
our_hud.hide_from(user)
if(hud_trait)
REMOVE_TRAIT(user, hud_trait, GLASSES_TRAIT)
@@ -196,8 +196,8 @@
return
if (hud_type)
var/datum/atom_hud/H = GLOB.huds[hud_type]
H.remove_hud_from(user)
var/datum/atom_hud/our_hud = GLOB.huds[hud_type]
our_hud.hide_from(user)
if (hud_type == DATA_HUD_MEDICAL_ADVANCED)
hud_type = null
@@ -207,8 +207,8 @@
hud_type = DATA_HUD_SECURITY_ADVANCED
if (hud_type)
var/datum/atom_hud/H = GLOB.huds[hud_type]
H.add_hud_to(user)
var/datum/atom_hud/our_hud = GLOB.huds[hud_type]
our_hud.show_to(user)
/obj/item/clothing/glasses/hud/toggle/thermal
name = "thermal HUD scanner"
+4 -4
View File
@@ -31,15 +31,15 @@
return
to_chat(user, "You roll the balaclava over your face, and a data display appears before your eyes.")
ADD_TRAIT(user, TRAIT_DIAGNOSTIC_HUD, MASK_TRAIT)
var/datum/atom_hud/H = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC]
H.add_hud_to(user)
var/datum/atom_hud/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC]
diag_hud.show_to(user)
voice_unknown = TRUE
/obj/item/clothing/mask/infiltrator/dropped(mob/living/carbon/human/user)
to_chat(user, "You pull off the balaclava, and the mask's internal hud system switches off quietly.")
REMOVE_TRAIT(user, TRAIT_DIAGNOSTIC_HUD, MASK_TRAIT)
var/datum/atom_hud/H = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC]
H.remove_hud_from(user)
var/datum/atom_hud/diag_hud = GLOB.huds[DATA_HUD_DIAGNOSTIC_BASIC]
diag_hud.hide_from(user)
voice_unknown = FALSE
return ..()
@@ -22,7 +22,7 @@
if(!istype(H))
return
if(H.fire_stacks)
if(H.fire_stacks > 0)
if(extinguishes_left)
if(next_extinguish > world.time)
return
+3 -3
View File
@@ -40,7 +40,7 @@
var/mob/living/carbon/user = loc
var/datum/atom_hud/hud = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
ADD_TRAIT(user, TRAIT_SECURITY_HUD, HELMET_TRAIT)
hud.add_hud_to(user)
hud.show_to(user)
balloon_alert(user, "you put on the hood, and enable the hud")
return ..()
@@ -48,8 +48,8 @@
if (!hood_up)
return ..()
var/mob/living/carbon/user = loc
var/datum/atom_hud/hud = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
var/datum/atom_hud/sec_hud = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
REMOVE_TRAIT(user, TRAIT_SECURITY_HUD, HELMET_TRAIT)
hud.remove_hud_from(user)
sec_hud.hide_from(user)
balloon_alert(user, "you take off the hood, and disable the hud")
return ..()
@@ -152,8 +152,8 @@
for(var/mob/living/carbon/carbon_victim in range(6, owner))
if(carbon_victim != owner)
carbon_victim.adjust_fire_stacks(8)
carbon_victim.IgniteMob()
owner.set_fire_stacks(-20)
carbon_victim.ignite_mob()
owner.set_wet_stacks(20)
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return TRUE
@@ -161,7 +161,7 @@
owner.visible_message(span_danger("[src] just makes [attack_text] worse by spewing molten death on [owner]!"))
playsound(get_turf(owner),'sound/magic/fireball.ogg', 100, TRUE)
owner.adjust_fire_stacks(12)
owner.IgniteMob()
owner.ignite_mob()
reactivearmor_cooldown = world.time + reactivearmor_cooldown_duration
return FALSE
+1 -1
View File
@@ -1474,7 +1474,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
set waitfor = FALSE
..()
target.set_fire_stacks(max(target.fire_stacks, 0.1)) //Placebo flammability
fire_overlay = image('icons/mob/OnFire.dmi', target, "Standing", ABOVE_MOB_LAYER)
fire_overlay = image('icons/mob/onfire.dmi', target, "human_burning", ABOVE_MOB_LAYER)
if(target.client)
target.client.images += fire_overlay
to_chat(target, span_userdanger("You're set on fire!"))
@@ -89,7 +89,7 @@
var/obj/item/seeds/our_seed = our_plant.get_plant_seed()
to_chat(target, "<span class='danger'>You are lit on fire from the intense heat of [our_plant]!</span>")
target.adjust_fire_stacks(our_seed.potency / 20)
if(target.IgniteMob())
if(target.ignite_mob())
message_admins("[ADMIN_LOOKUPFLW(user)] set [ADMIN_LOOKUPFLW(target)] on fire with [our_plant] at [AREACOORD(user)]")
log_game("[key_name(user)] set [key_name(target)] on fire with [our_plant] at [AREACOORD(user)]")
our_plant.investigate_log("was used by [key_name(user)] to burn [key_name(target)] at [AREACOORD(user)]", INVESTIGATE_BOTANY)
+2 -2
View File
@@ -98,7 +98,7 @@
for(var/datum/mutation/human/clumsy/M in H.dna.mutations)
M.mutadone_proof = TRUE
var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN]
fan.add_hud_to(H)
fan.show_to(H)
H.faction |= FACTION_CLOWN
//Skyrat Edit Start: Floor Demon
@@ -143,5 +143,5 @@
for(var/datum/mutation/human/clumsy/M in H.dna.mutations)
M.mutadone_proof = FALSE
var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN]
fan.add_hud_to(H)
fan.show_to(H)
//Skyrat Edit Stop: Floor Demon
+1 -1
View File
@@ -77,7 +77,7 @@
H.mind.miming = TRUE
var/datum/atom_hud/fan = GLOB.huds[DATA_HUD_FAN]
fan.add_hud_to(H)
fan.show_to(H)
/obj/item/book/mimery
name = "Guide to Dank Mimery"
+4 -4
View File
@@ -741,13 +741,13 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/proc/show_data_huds()
for(var/hudtype in datahuds)
var/datum/atom_hud/H = GLOB.huds[hudtype]
H.add_hud_to(src)
var/datum/atom_hud/data_hud = GLOB.huds[hudtype]
data_hud.show_to(src)
/mob/dead/observer/proc/remove_data_huds()
for(var/hudtype in datahuds)
var/datum/atom_hud/H = GLOB.huds[hudtype]
H.remove_hud_from(src)
var/datum/atom_hud/data_hud = GLOB.huds[hudtype]
data_hud.hide_from(src)
/mob/dead/observer/verb/toggle_data_huds()
set name = "Toggle Sec/Med/Diag HUD"
@@ -131,3 +131,6 @@ In all, this is a lot like the monkey code. /N
/mob/living/carbon/alien/acid_act(acidpwr, acid_volume)
return FALSE//aliens are immune to acid.
/mob/living/carbon/alien/on_fire_stack(delta_time, times_fired, datum/status_effect/fire_handler/fire_stacks/fire_handler)
adjust_bodytemperature(BODYTEMP_HEATING_MAX * 0.5 * delta_time)
@@ -46,9 +46,3 @@
//natural reduction of movement delay due to stun.
if(move_delay_add > 0)
move_delay_add = max(0, move_delay_add - (0.5 * rand(1, 2) * delta_time))
/mob/living/carbon/alien/handle_fire(delta_time, times_fired)//Aliens on fire code
. = ..()
if(.) //if the mob isn't on fire anymore
return
adjust_bodytemperature(BODYTEMP_HEATING_MAX * 0.5 * delta_time) //If you're on fire, you heat up!
+24 -10
View File
@@ -268,7 +268,6 @@
if(fire_stacks <= 0 && !QDELETED(src))
visible_message(span_danger("[src] successfully extinguishes [p_them()]self!"), \
span_notice("You extinguish yourself."))
extinguish_mob()
return
/mob/living/carbon/resist_restraints()
@@ -978,15 +977,6 @@
I.extinguish() //extinguishes our clothes
..()
/mob/living/carbon/fakefire(fire_icon = "Generic_mob_burning")
var/mutable_appearance/new_fire_overlay = mutable_appearance('icons/mob/OnFire.dmi', fire_icon, -FIRE_LAYER)
new_fire_overlay.appearance_flags = RESET_COLOR
overlays_standing[FIRE_LAYER] = new_fire_overlay
apply_overlay(FIRE_LAYER)
/mob/living/carbon/fakefireextinguish()
remove_overlay(FIRE_LAYER)
/mob/living/carbon/proc/create_bodyparts()
var/l_arm_index_next = -1
@@ -1445,3 +1435,27 @@
our_splatter.blood_dna_info = get_blood_dna_list()
var/turf/targ = get_ranged_target_turf(src, splatter_direction, splatter_strength)
our_splatter.fly_towards(targ, splatter_strength)
/mob/living/carbon/update_fire_overlay(stacks, on_fire, last_icon_state, suffix = "")
var/fire_icon = "generic_burning[suffix]"
if(!GLOB.fire_appearances[fire_icon])
var/mutable_appearance/new_fire_overlay = mutable_appearance('icons/mob/onfire.dmi', fire_icon, -FIRE_LAYER)
new_fire_overlay.appearance_flags = RESET_COLOR
GLOB.fire_appearances[fire_icon] = new_fire_overlay
if((stacks > 0 && on_fire) || HAS_TRAIT(src, TRAIT_PERMANENTLY_ONFIRE))
if(fire_icon == last_icon_state)
return last_icon_state
remove_overlay(FIRE_LAYER)
overlays_standing[FIRE_LAYER] = GLOB.fire_appearances[fire_icon]
apply_overlay(FIRE_LAYER)
return fire_icon
if(!last_icon_state)
return last_icon_state
remove_overlay(FIRE_LAYER)
apply_overlay(FIRE_LAYER)
return null
@@ -47,7 +47,6 @@
update_fire()
update_body_parts()
/mob/living/carbon/update_inv_hands()
remove_overlay(HANDS_LAYER)
if (handcuffed)
@@ -78,16 +77,6 @@
overlays_standing[HANDS_LAYER] = hands
apply_overlay(HANDS_LAYER)
/mob/living/carbon/update_fire(fire_icon = "Generic_mob_burning")
remove_overlay(FIRE_LAYER)
if(on_fire || HAS_TRAIT(src, TRAIT_PERMANENTLY_ONFIRE))
var/mutable_appearance/new_fire_overlay = mutable_appearance('icons/mob/OnFire.dmi', fire_icon, -FIRE_LAYER)
new_fire_overlay.appearance_flags = RESET_COLOR
overlays_standing[FIRE_LAYER] = new_fire_overlay
apply_overlay(FIRE_LAYER)
/mob/living/carbon/update_damage_overlays()
remove_overlay(DAMAGE_LAYER)
+2 -2
View File
@@ -99,9 +99,9 @@
if(HAS_TRAIT(src, TRAIT_DUMB))
msg += "[t_He] seem[p_s()] to be clumsy and unable to think.\n"
if(fire_stacks > 0)
if(has_status_effect(/datum/status_effect/fire_handler/fire_stacks))
msg += "[t_He] [t_is] covered in something flammable.\n"
if(fire_stacks < 0)
if(has_status_effect(/datum/status_effect/fire_handler/wet_stacks))
msg += "[t_He] look[p_s()] a little soaked.\n"
if(pulledby?.grab_state)
@@ -252,9 +252,9 @@
msg += "<b>[t_He] [t_has] severe cellular damage!</b>\n"
if(fire_stacks > 0)
if(has_status_effect(/datum/status_effect/fire_handler/fire_stacks))
msg += "[t_He] [t_is] covered in something flammable.\n"
if(fire_stacks < 0)
if(has_status_effect(/datum/status_effect/fire_handler/wet_stacks))
msg += "[t_He] look[p_s()] a little soaked.\n"
@@ -992,3 +992,97 @@
for(var/obj/item/I in torn_items)
I.take_damage(damage_amount, damage_type, damage_flag, 0)
/**
* Used by fire code to damage worn items.
*
* Arguments:
* - delta_time
* - times_fired
* - stacks: Current amount of firestacks
*
*/
/mob/living/carbon/human/proc/burn_clothing(delta_time, times_fired, stacks)
var/list/burning_items = list()
var/obscured = check_obscured_slots(TRUE)
//HEAD//
if(glasses && !(obscured & ITEM_SLOT_EYES))
burning_items += glasses
if(wear_mask && !(obscured & ITEM_SLOT_MASK))
burning_items += wear_mask
if(wear_neck && !(obscured & ITEM_SLOT_NECK))
burning_items += wear_neck
if(ears && !(obscured & ITEM_SLOT_EARS))
burning_items += ears
if(head)
burning_items += head
//CHEST//
if(w_uniform && !(obscured & ITEM_SLOT_ICLOTHING))
burning_items += w_uniform
if(wear_suit)
burning_items += wear_suit
//ARMS & HANDS//
var/obj/item/clothing/arm_clothes = null
if(gloves && !(obscured & ITEM_SLOT_GLOVES))
arm_clothes = gloves
else if(wear_suit && ((wear_suit.body_parts_covered & HANDS) || (wear_suit.body_parts_covered & ARMS)))
arm_clothes = wear_suit
else if(w_uniform && ((w_uniform.body_parts_covered & HANDS) || (w_uniform.body_parts_covered & ARMS)))
arm_clothes = w_uniform
if(arm_clothes)
burning_items |= arm_clothes
//LEGS & FEET//
var/obj/item/clothing/leg_clothes = null
if(shoes && !(obscured & ITEM_SLOT_FEET))
leg_clothes = shoes
else if(wear_suit && ((wear_suit.body_parts_covered & FEET) || (wear_suit.body_parts_covered & LEGS)))
leg_clothes = wear_suit
else if(w_uniform && ((w_uniform.body_parts_covered & FEET) || (w_uniform.body_parts_covered & LEGS)))
leg_clothes = w_uniform
if(leg_clothes)
burning_items |= leg_clothes
for(var/obj/item/burning in burning_items)
burning.fire_act((stacks * 25 * delta_time)) //damage taken is reduced to 2% of this value by fire_act()
/mob/living/carbon/human/update_fire_overlay(stacks, on_fire, last_icon_state, suffix = "")
var/fire_icon = "generic_burning[suffix]"
if(stacks > HUMAN_FIRE_STACK_ICON_NUM)
if(dna && dna.species)
fire_icon = "[dna.species.fire_overlay][suffix]"
else
fire_icon = "human_burning[suffix]"
if(!GLOB.fire_appearances[fire_icon])
var/mutable_appearance/new_fire_overlay = mutable_appearance('icons/mob/onfire.dmi', fire_icon, -FIRE_LAYER)
new_fire_overlay.appearance_flags = RESET_COLOR
GLOB.fire_appearances[fire_icon] = new_fire_overlay
if((stacks > 0 && on_fire) || HAS_TRAIT(src, TRAIT_PERMANENTLY_ONFIRE))
if(fire_icon == last_icon_state)
return last_icon_state
remove_overlay(FIRE_LAYER)
overlays_standing[FIRE_LAYER] = GLOB.fire_appearances[fire_icon]
apply_overlay(FIRE_LAYER)
return fire_icon
if(!last_icon_state)
return last_icon_state
remove_overlay(FIRE_LAYER)
apply_overlay(FIRE_LAYER)
return null
/mob/living/carbon/human/on_fire_stack(delta_time, times_fired, datum/status_effect/fire_handler/fire_stacks/fire_handler)
SEND_SIGNAL(src, COMSIG_HUMAN_BURNING)
burn_clothing(delta_time, times_fired, fire_handler.stacks)
var/no_protection = FALSE
if(dna && dna.species)
no_protection = dna.species.handle_fire(src, delta_time, times_fired, no_protection)
fire_handler.harm_human(delta_time, times_fired, no_protection)
@@ -70,7 +70,6 @@
/// What types of mobs are allowed to ride/buckle to this mob
var/static/list/can_ride_typecache = typecacheof(list(/mob/living/carbon/human, /mob/living/simple_animal/slime, /mob/living/simple_animal/parrot))
var/lastpuke = 0
var/last_fire_update
var/account_id
var/hardcore_survival_score = 0
@@ -68,10 +68,6 @@ There are several things that need to be remembered:
dna.species.handle_body(src)
..()
/mob/living/carbon/human/update_fire()
..((fire_stacks > HUMAN_FIRE_STACK_ICON_NUM) ? "Standing" : "Generic_mob_burning")
/* --------------------------------------- */
//For legacy support.
/mob/living/carbon/human/regenerate_icons()
@@ -154,22 +154,6 @@
/mob/living/carbon/human/get_body_temp_cold_damage_limit()
return dna.species.bodytemp_cold_damage_limit
///FIRE CODE
/mob/living/carbon/human/handle_fire(delta_time, times_fired)
. = ..()
if(.) //if the mob isn't on fire anymore
return
if(dna)
. = dna.species.handle_fire(src, delta_time, times_fired) //do special handling based on the mob's species. TRUE = they are immune to the effects of the fire.
if(!last_fire_update)
last_fire_update = fire_stacks
if((fire_stacks > HUMAN_FIRE_STACK_ICON_NUM && last_fire_update <= HUMAN_FIRE_STACK_ICON_NUM) || (fire_stacks <= HUMAN_FIRE_STACK_ICON_NUM && last_fire_update > HUMAN_FIRE_STACK_ICON_NUM))
last_fire_update = fire_stacks
update_fire()
/mob/living/carbon/human/proc/get_thermal_protection()
var/thermal_protection = 0 //Simple check to estimate how protected we are against multiple temperatures
if(wear_suit)
@@ -181,20 +165,8 @@
thermal_protection = round(thermal_protection)
return thermal_protection
/mob/living/carbon/human/IgniteMob()
//If have no DNA or can be Ignited, call parent handling to light user
//If firestacks are high enough
if(!dna || dna.species.CanIgniteMob(src))
return ..()
. = FALSE //No ignition
/mob/living/carbon/human/extinguish_mob()
if(!dna || !dna.species.extinguish_mob(src))
last_fire_update = null
..()
//END FIRE CODE
//This proc returns a number made up of the flags for body parts which you are protected on. (such as HEAD, CHEST, GROIN, etc. See setup.dm for the full list)
/mob/living/carbon/human/proc/get_heat_protection_flags(temperature) //Temperature is the temperature you're being exposed to.
var/thermal_protection_flags = 0
@@ -166,7 +166,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
var/bodytemp_cold_damage_limit = BODYTEMP_COLD_DAMAGE_LIMIT
/// The icon_state of the fire overlay added when sufficently ablaze and standing. see onfire.dmi
var/fire_overlay = "Standing"
var/fire_overlay = "human_burning"
///the species that body parts are surgically compatible with (found in _DEFINES/mobs.dm)
///current acceptable bitfields are HUMAN_BODY, ALIEN_BODY, LARVA_BODY, MONKEY_BODY, or NONE
@@ -1825,77 +1825,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
//////////
/datum/species/proc/handle_fire(mob/living/carbon/human/H, delta_time, times_fired, no_protection = FALSE)
if(!CanIgniteMob(H))
return TRUE
if(H.on_fire)
SEND_SIGNAL(H, COMSIG_HUMAN_BURNING)
//the fire tries to damage the exposed clothes and items
var/list/burning_items = list()
var/obscured = H.check_obscured_slots(TRUE)
//HEAD//
if(H.glasses && !(obscured & ITEM_SLOT_EYES))
burning_items += H.glasses
if(H.wear_mask && !(obscured & ITEM_SLOT_MASK))
burning_items += H.wear_mask
if(H.wear_neck && !(obscured & ITEM_SLOT_NECK))
burning_items += H.wear_neck
if(H.ears && !(obscured & ITEM_SLOT_EARS))
burning_items += H.ears
if(H.head)
burning_items += H.head
//CHEST//
if(H.w_uniform && !(obscured & ITEM_SLOT_ICLOTHING))
burning_items += H.w_uniform
if(H.wear_suit)
burning_items += H.wear_suit
//ARMS & HANDS//
var/obj/item/clothing/arm_clothes = null
if(H.gloves && !(obscured & ITEM_SLOT_GLOVES))
arm_clothes = H.gloves
else if(H.wear_suit && ((H.wear_suit.body_parts_covered & HANDS) || (H.wear_suit.body_parts_covered & ARMS)))
arm_clothes = H.wear_suit
else if(H.w_uniform && ((H.w_uniform.body_parts_covered & HANDS) || (H.w_uniform.body_parts_covered & ARMS)))
arm_clothes = H.w_uniform
if(arm_clothes)
burning_items |= arm_clothes
//LEGS & FEET//
var/obj/item/clothing/leg_clothes = null
if(H.shoes && !(obscured & ITEM_SLOT_FEET))
leg_clothes = H.shoes
else if(H.wear_suit && ((H.wear_suit.body_parts_covered & FEET) || (H.wear_suit.body_parts_covered & LEGS)))
leg_clothes = H.wear_suit
else if(H.w_uniform && ((H.w_uniform.body_parts_covered & FEET) || (H.w_uniform.body_parts_covered & LEGS)))
leg_clothes = H.w_uniform
if(leg_clothes)
burning_items |= leg_clothes
for(var/X in burning_items)
var/obj/item/I = X
I.fire_act((H.fire_stacks * 50)) //damage taken is reduced to 2% of this value by fire_act()
var/thermal_protection = H.get_thermal_protection()
if(thermal_protection >= FIRE_IMMUNITY_MAX_TEMP_PROTECT && !no_protection)
return
if(thermal_protection >= FIRE_SUIT_MAX_TEMP_PROTECT && !no_protection)
H.adjust_bodytemperature(5.5 * delta_time)
else
H.adjust_bodytemperature((BODYTEMP_HEATING_MAX + (H.fire_stacks * 12)) * 0.5 * delta_time)
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "on_fire", /datum/mood_event/on_fire)
H.mind?.add_memory(MEMORY_FIRE, list(DETAIL_PROTAGONIST = H), story_value = STORY_VALUE_OKAY)
/datum/species/proc/CanIgniteMob(mob/living/carbon/human/H)
if(HAS_TRAIT(H, TRAIT_NOFIRE))
return FALSE
return TRUE
/datum/species/proc/extinguish_mob(mob/living/carbon/human/H)
return
return no_protection
////////////
// Stun //
@@ -28,11 +28,11 @@
/datum/species/abductor/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
var/datum/atom_hud/abductor_hud = GLOB.huds[DATA_HUD_ABDUCTOR]
abductor_hud.add_hud_to(C)
abductor_hud.show_to(C)
C.set_safe_hunger_level()
/datum/species/abductor/on_species_loss(mob/living/carbon/C)
. = ..()
var/datum/atom_hud/abductor_hud = GLOB.huds[DATA_HUD_ABDUCTOR]
abductor_hud.remove_hud_from(C)
abductor_hud.hide_from(C)
@@ -173,7 +173,7 @@
to_chat(owner, span_notice("You ignite yourself!"))
else
to_chat(owner, span_warning("You try to ignite yourself, but fail!"))
H.IgniteMob() //firestacks are already there passively
H.ignite_mob() //firestacks are already there passively
//Harder to hurt
/datum/species/golem/diamond
@@ -54,7 +54,7 @@
BODY_ZONE_R_LEG = /obj/item/bodypart/r_leg/monkey,
BODY_ZONE_CHEST = /obj/item/bodypart/chest/monkey,
)
fire_overlay = "Monkey_burning"
fire_overlay = "monkey_burning"
dust_anim = "dust-m"
gib_anim = "gibbed-m"
@@ -64,7 +64,7 @@
/datum/species/plasmaman/spec_life(mob/living/carbon/human/H, delta_time, times_fired)
var/atmos_sealed = TRUE
if(CanIgniteMob(H))
if(!HAS_TRAIT(H, TRAIT_NOFIRE))
atmos_sealed = FALSE
else if(!isclothing(H.wear_suit) || !(H.wear_suit.clothing_flags & STOPSPRESSUREDAMAGE))
atmos_sealed = FALSE
@@ -99,7 +99,7 @@
H.adjust_fire_stacks(0.25 * delta_time)
if(!H.on_fire && H.fire_stacks > 0)
H.visible_message(span_danger("[H]'s body reacts with the atmosphere and bursts into flames!"),span_userdanger("Your body reacts with the atmosphere and bursts into flame!"))
H.IgniteMob()
H.ignite_mob()
internal_fire = TRUE
else if(H.fire_stacks)
@@ -117,7 +117,6 @@
no_protection = TRUE
. = ..()
/datum/species/plasmaman/pre_equip_species_outfit(datum/job/job, mob/living/carbon/human/equipping, visuals_only = FALSE)
if(job.plasmaman_outfit)
equipping.equipOutfit(job.plasmaman_outfit, visuals_only)
@@ -68,7 +68,7 @@
to_chat(vampire, span_warning("You don't belong here!"))
vampire.adjustFireLoss(10 * delta_time)
vampire.adjust_fire_stacks(3 * delta_time)
vampire.IgniteMob()
vampire.ignite_mob()
/datum/species/vampire/check_species_weakness(obj/item/weapon, mob/living/attacker)
if(istype(weapon, /obj/item/nullrod/whip))
-19
View File
@@ -71,8 +71,6 @@
handle_traits(delta_time, times_fired) // eye, ear, brain damages
handle_status_effects(delta_time, times_fired) //all special effects, stun, knockdown, jitteryness, hallucination, sleeping, etc
handle_fire(delta_time, times_fired)
if(machine)
machine.check_eye(src)
@@ -110,23 +108,6 @@
else // this is a hot place
adjust_bodytemperature(min(min(temp_delta / BODYTEMP_DIVISOR, BODYTEMP_HEATING_MAX) * delta_time, temp_delta))
/mob/living/proc/handle_fire(delta_time, times_fired)
if(fire_stacks < 0) //If we've doused ourselves in water to avoid fire, dry off slowly
set_fire_stacks(min(0, fire_stacks + (0.5 * delta_time))) //So we dry ourselves back to default, nonflammable.
if(!on_fire)
return TRUE //the mob is no longer on fire, no need to do the rest.
if(fire_stacks > 0)
adjust_fire_stacks(-0.05 * delta_time) //the fire is slowly consumed
else
extinguish_mob()
return TRUE //mob was put out, on_fire = FALSE via extinguish_mob(), no need to update everything down the chain.
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
if(!G.gases[/datum/gas/oxygen] || G.gases[/datum/gas/oxygen][MOLES] < 1)
extinguish_mob() //If there's no oxygen in the tile we're on, put out the fire
return TRUE
var/turf/location = get_turf(src)
location.hotspot_expose(700, 25 * delta_time, TRUE)
/**
* Get the fullness of the mob
*
+112 -54
View File
@@ -4,9 +4,9 @@
if(unique_name)
set_name()
var/datum/atom_hud/data/human/medical/advanced/medhud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
medhud.add_to_hud(src)
medhud.add_atom_to_hud(src)
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
diag_hud.add_to_hud(src)
diag_hud.add_atom_to_hud(src)
faction += "[REF(src)]"
GLOB.mob_living_list += src
SSpoints_of_interest.make_point_of_interest(src)
@@ -887,7 +887,6 @@
hallucination = 0
heal_overall_damage(INFINITY, INFINITY, INFINITY, null, TRUE) //heal brute and burn dmg on both organic and robotic limbs, and update health right away.
extinguish_mob()
fire_stacks = 0
set_confusion(0)
dizziness = 0
set_drowsyness(0)
@@ -1447,27 +1446,28 @@
G.Recall()
to_chat(G, span_holoparasite("Your summoner has changed form!"))
/mob/living/proc/fakefireextinguish()
return
/mob/living/proc/fakefire()
return
/mob/living/proc/unfry_mob() //Callback proc to tone down spam from multiple sizzling frying oil dipping.
REMOVE_TRAIT(src, TRAIT_OIL_FRIED, "cooking_oil_react")
//Mobs on Fire
/mob/living/proc/IgniteMob()
if(fire_stacks <= 0 || on_fire)
/// Global list that containes cached fire overlays for mobs
GLOBAL_LIST_EMPTY(fire_appearances)
/mob/living/proc/ignite_mob()
if(fire_stacks <= 0)
return FALSE
on_fire = TRUE
src.visible_message(span_warning("[src] catches fire!"), \
span_userdanger("You're set on fire!"))
firelight_ref = WEAKREF(new /obj/effect/dummy/lighting_obj/moblight/fire(src))
throw_alert(ALERT_FIRE, /atom/movable/screen/alert/fire)
update_fire()
SEND_SIGNAL(src, COMSIG_LIVING_IGNITED,src)
return TRUE
var/datum/status_effect/fire_handler/fire_stacks/fire_status = has_status_effect(/datum/status_effect/fire_handler/fire_stacks)
if(!fire_status || fire_status.on_fire)
return FALSE
return fire_status.ignite()
/mob/living/proc/update_fire()
var/datum/status_effect/fire_handler/fire_handler = has_status_effect(/datum/status_effect/fire_handler)
if(fire_handler)
fire_handler.update_overlay()
/**
* Extinguish all fire on the mob
@@ -1476,15 +1476,10 @@
* Signals the extinguishing.
*/
/mob/living/proc/extinguish_mob()
if(!on_fire)
var/datum/status_effect/fire_handler/fire_stacks/fire_status = has_status_effect(/datum/status_effect/fire_handler/fire_stacks)
if(!fire_status || !fire_status.on_fire)
return
on_fire = FALSE
fire_stacks = min(0, fire_stacks) //Makes sure we don't get rid of negative firestacks.
QDEL_NULL(firelight_ref)
clear_alert(ALERT_FIRE)
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "on_fire")
SEND_SIGNAL(src, COMSIG_LIVING_EXTINGUISHED, src)
update_fire()
remove_status_effect(/datum/status_effect/fire_handler/fire_stacks)
/**
* Adjust the amount of fire stacks on a mob
@@ -1492,10 +1487,19 @@
* This modifies the fire stacks on a mob.
*
* Vars:
* * add_fire_stacks: int The amount to modify the fire stacks
* * stacks: int The amount to modify the fire stacks
* * fire_type: type Type of fire status effect that we apply, should be subtype of /datum/status_effect/fire_handler/fire_stacks
*/
/mob/living/proc/adjust_fire_stacks(add_fire_stacks)
set_fire_stacks(fire_stacks + add_fire_stacks)
/mob/living/proc/adjust_fire_stacks(stacks, fire_type = /datum/status_effect/fire_handler/fire_stacks)
if(stacks < 0)
stacks = max(-fire_stacks, stacks)
apply_status_effect(fire_type, stacks)
/mob/living/proc/adjust_wet_stacks(stacks, wet_type = /datum/status_effect/fire_handler/wet_stacks)
if(stacks < 0)
stacks = max(fire_stacks, stacks)
apply_status_effect(wet_type, stacks)
/**
* Set the fire stacks on a mob
@@ -1505,38 +1509,95 @@
*
* Vars:
* * stacks: int The amount to set fire_stacks to
* * fire_type: type Type of fire status effect that we apply, should be subtype of /datum/status_effect/fire_handler/fire_stacks
* * remove_wet_stacks: bool If we remove all wet stacks upon doing this
*/
/mob/living/proc/set_fire_stacks(stacks)
fire_stacks = clamp(stacks, -20, 20)
if(fire_stacks <= 0)
extinguish_mob()
/mob/living/proc/set_fire_stacks(stacks, fire_type = /datum/status_effect/fire_handler/fire_stacks, remove_wet_stacks = TRUE)
if(stacks < 0) //Shouldn't happen, ever
CRASH("set_fire_stacks recieved negative [stacks] fire stacks")
if(remove_wet_stacks)
remove_status_effect(/datum/status_effect/fire_handler/wet_stacks)
if(stacks == 0)
remove_status_effect(fire_type)
return
apply_status_effect(fire_type, stacks, TRUE)
/mob/living/proc/set_wet_stacks(stacks, wet_type = /datum/status_effect/fire_handler/wet_stacks, remove_fire_stacks = TRUE)
if(stacks < 0)
CRASH("set_wet_stacks recieved negative [stacks] wet stacks")
if(remove_fire_stacks)
remove_status_effect(/datum/status_effect/fire_handler/fire_stacks)
if(stacks == 0)
remove_status_effect(wet_type)
return
apply_status_effect(wet_type, stacks, TRUE)
//Share fire evenly between the two mobs
//Called in MobBump() and Crossed()
/mob/living/proc/spreadFire(mob/living/L)
if(!istype(L))
/mob/living/proc/spreadFire(mob/living/spread_to)
if(!istype(spread_to))
return
// can't spread fire to mobs that don't catch on fire
if(HAS_TRAIT(L, TRAIT_NOFIRE_SPREAD) || HAS_TRAIT(src, TRAIT_NOFIRE_SPREAD))
if(HAS_TRAIT(spread_to, TRAIT_NOFIRE_SPREAD) || HAS_TRAIT(src, TRAIT_NOFIRE_SPREAD))
return
if(on_fire)
if(L.on_fire) // If they were also on fire
var/firesplit = (fire_stacks + L.fire_stacks)/2
set_fire_stacks(firesplit)
L.set_fire_stacks(firesplit)
else // If they were not
set_fire_stacks(fire_stacks / 2)
L.adjust_fire_stacks(fire_stacks)
if(L.IgniteMob()) // Ignite them
log_game("[key_name(src)] bumped into [key_name(L)] and set them on fire")
var/datum/status_effect/fire_handler/fire_stacks/fire_status = has_status_effect(/datum/status_effect/fire_handler/fire_stacks)
var/datum/status_effect/fire_handler/fire_stacks/their_fire_status = spread_to.has_status_effect(/datum/status_effect/fire_handler/fire_stacks)
if(fire_status && fire_status.on_fire)
if(their_fire_status && their_fire_status.on_fire)
var/firesplit = (fire_stacks + spread_to.fire_stacks) / 2
var/fire_type = (spread_to.fire_stacks > fire_stacks) ? their_fire_status.type : fire_status.type
set_fire_stacks(firesplit, fire_type)
spread_to.set_fire_stacks(firesplit, fire_type)
return
else if(L.on_fire) // If they were on fire and we were not
L.set_fire_stacks(L.fire_stacks / 2)
adjust_fire_stacks(L.fire_stacks)
IgniteMob() // Ignite us
adjust_fire_stacks(-fire_stacks / 2, fire_status.type)
spread_to.adjust_fire_stacks(fire_stacks, fire_status.type)
if(spread_to.ignite_mob())
log_game("[key_name(src)] bumped into [key_name(spread_to)] and set them on fire")
return
if(!their_fire_status || !their_fire_status.on_fire)
return
spread_to.adjust_fire_stacks(-spread_to.fire_stacks / 2, their_fire_status.type)
adjust_fire_stacks(spread_to.fire_stacks, their_fire_status.type)
ignite_mob()
/**
* Sets fire overlay of the mob.
*
* Vars:
* * stacks: Current amount of fire_stacks
* * on_fire: If we're lit on fire
* * last_icon_state: Holds last fire overlay icon state, used for optimization
* * suffix: Suffix for the fire icon state for special fire types
*
* This should return last_icon_state for the fire status efect
*/
/mob/living/proc/update_fire_overlay(stacks, on_fire, last_icon_state, suffix = "")
return last_icon_state
/**
* Handles effects happening when mob is on normal fire
*
* Vars:
* * delta_time
* * times_fired
* * fire_handler: Current fire status effect that called the proc
*/
/mob/living/proc/on_fire_stack(delta_time, times_fired, datum/status_effect/fire_handler/fire_stacks/fire_handler)
return
//Mobs on Fire end
@@ -1697,9 +1758,6 @@
if(NAMEOF(src, resting))
set_resting(var_value)
. = TRUE
if(NAMEOF(src, fire_stacks))
set_fire_stacks(var_value)
. = TRUE
if(NAMEOF(src, lying_angle))
set_lying_angle(var_value)
. = TRUE
+1 -1
View File
@@ -141,7 +141,7 @@
/mob/living/fire_act()
adjust_fire_stacks(3)
IgniteMob()
ignite_mob()
/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = FALSE)
if(user == src || anchored || !isturf(user.loc))
+4 -5
View File
@@ -55,6 +55,10 @@
var/last_special = 0 ///Used by the resist verb, likely used to prevent players from bypassing next_move by logging in/out.
var/timeofdeath = 0
/// Helper vars for quick access to firestacks, these should be updated every time firestacks are adjusted
var/on_fire = FALSE
var/fire_stacks = 0
/**
* Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects.
*
@@ -76,11 +80,6 @@
/// Time of death
var/tod = null
var/on_fire = FALSE ///The "Are we on fire?" var
/// Weak reference to the light our fire is causing, if there is one
var/datum/weakref/firelight_ref
var/fire_stacks = 0 ///Tracks how many stacks of fire we have on, max is usually 20
var/limb_destroyer = 0 //1 Sets AI behavior that allows mobs to target and dismember limbs with their basic attack.
var/mob_size = MOB_SIZE_HUMAN
+2 -3
View File
@@ -241,9 +241,8 @@
if(istype(A, initial(AM.power_type)))
qdel(A)
/mob/living/silicon/ai/IgniteMob()
fire_stacks = 0
. = ..()
/mob/living/silicon/ai/ignite_mob()
return FALSE
/mob/living/silicon/ai/proc/set_core_display_icon(input, client/C)
if(client && !C)
@@ -35,14 +35,14 @@
var/datum/atom_hud/ai_detector/hud = GLOB.huds[DATA_HUD_AI_DETECT]
var/list/old_images = hud_list[AI_DETECT_HUD]
if(!ai_detector_visible)
hud.remove_from_hud(src)
hud.remove_atom_from_hud(src)
QDEL_LIST(old_images)
return
if(!length(hud.hudusers))
if(!length(hud.hud_users))
return //no one is watching, do not bother updating anything
hud.remove_from_hud(src)
hud.remove_atom_from_hud(src)
var/static/list/vis_contents_opaque = list()
var/obj/effect/overlay/ai_detect_hud/hud_obj = vis_contents_opaque[ai_detector_color]
@@ -61,7 +61,7 @@
for(var/i in (new_images.len + 1) to old_images.len)
qdel(old_images[i])
hud_list[AI_DETECT_HUD] = new_images
hud.add_to_hud(src)
hud.add_atom_to_hud(src)
/mob/camera/ai_eye/proc/get_visible_turfs()
if(!isturf(loc))
@@ -124,7 +124,7 @@
GLOB.aiEyes -= src
if(ai_detector_visible)
var/datum/atom_hud/ai_detector/hud = GLOB.huds[DATA_HUD_AI_DETECT]
hud.remove_from_hud(src)
hud.remove_atom_from_hud(src)
var/list/L = hud_list[AI_DETECT_HUD]
QDEL_LIST(L)
return ..()
@@ -61,9 +61,8 @@
src.visible_message(span_warning("The electrically-charged projectile disrupts [src]'s holomatrix, forcing [src] to fold in!"))
. = ..(Proj)
/mob/living/silicon/pai/IgniteMob()
fire_stacks = 0
. = ..()
/mob/living/silicon/pai/ignite_mob()
return FALSE
/mob/living/silicon/pai/proc/take_holo_damage(amount)
emitterhealth = clamp((emitterhealth - amount), -50, emittermaxhealth)
@@ -119,10 +119,10 @@
medHUD = !medHUD
if(medHUD)
var/datum/atom_hud/med = GLOB.huds[med_hud]
med.add_hud_to(src)
med.show_to(src)
else
var/datum/atom_hud/med = GLOB.huds[med_hud]
med.remove_hud_from(src)
med.hide_from(src)
if("newscaster")
newscaster.ui_interact(src)
if("photography_module")
@@ -147,10 +147,10 @@
secHUD = !secHUD
if(secHUD)
var/datum/atom_hud/sec = GLOB.huds[sec_hud]
sec.add_hud_to(src)
sec.show_to(src)
else
var/datum/atom_hud/sec = GLOB.huds[sec_hud]
sec.remove_hud_from(src)
sec.hide_from(src)
if("universal_translator")
if(!languages_granted)
grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_SOFTWARE)
@@ -70,23 +70,3 @@
throw_alert(ALERT_CHARGE, /atom/movable/screen/alert/emptycell)
else
throw_alert(ALERT_CHARGE, /atom/movable/screen/alert/nocell)
//Robots on fire
/mob/living/silicon/robot/handle_fire(delta_time, times_fired)
. = ..()
if(.) //if the mob isn't on fire anymore
return
if(fire_stacks > 0)
adjust_fire_stacks(-0.5 * delta_time)
else
extinguish_mob()
return TRUE
//adjustFireLoss(3)
/mob/living/silicon/robot/update_fire()
var/mutable_appearance/fire_overlay = mutable_appearance('icons/mob/OnFire.dmi', "Generic_mob_burning")
if(on_fire)
add_overlay(fire_overlay)
else
cut_overlay(fire_overlay)
@@ -1004,3 +1004,23 @@
/mob/living/silicon/robot/proc/untip_roleplay()
to_chat(src, span_notice("Your frustration has empowered you! You can now right yourself faster!"))
/mob/living/silicon/robot/update_fire_overlay(stacks, on_fire, last_icon_state, suffix = "")
var/fire_icon = "generic_burning[suffix]"
if(!GLOB.fire_appearances[fire_icon])
var/mutable_appearance/new_fire_overlay = mutable_appearance('icons/mob/onfire.dmi', fire_icon, -FIRE_LAYER)
new_fire_overlay.appearance_flags = RESET_COLOR
GLOB.fire_appearances[fire_icon] = new_fire_overlay
if(stacks && on_fire)
if(last_icon_state == fire_icon)
return last_icon_state
add_overlay(GLOB.fire_appearances[fire_icon])
return fire_icon
if(!last_icon_state)
return last_icon_state
cut_overlay(GLOB.fire_appearances[fire_icon])
return null
@@ -312,7 +312,7 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real
/mob/living/silicon/robot/fire_act()
if(!on_fire) //Silicons don't gain stacks from hotspots, but hotspots can ignite them
IgniteMob()
ignite_mob()
/mob/living/silicon/robot/emp_act(severity)
. = ..()
+7 -7
View File
@@ -57,7 +57,7 @@
if(ispath(radio))
radio = new radio(src)
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
diag_hud.add_to_hud(src)
diag_hud.add_atom_to_hud(src)
diag_hud_set_status()
diag_hud_set_health()
add_sensors()
@@ -377,17 +377,17 @@
var/datum/atom_hud/secsensor = GLOB.huds[sec_hud]
var/datum/atom_hud/medsensor = GLOB.huds[med_hud]
var/datum/atom_hud/diagsensor = GLOB.huds[d_hud]
secsensor.remove_hud_from(src)
medsensor.remove_hud_from(src)
diagsensor.remove_hud_from(src)
secsensor.hide_from(src)
medsensor.hide_from(src)
diagsensor.hide_from(src)
/mob/living/silicon/proc/add_sensors()
var/datum/atom_hud/secsensor = GLOB.huds[sec_hud]
var/datum/atom_hud/medsensor = GLOB.huds[med_hud]
var/datum/atom_hud/diagsensor = GLOB.huds[d_hud]
secsensor.add_hud_to(src)
medsensor.add_hud_to(src)
diagsensor.add_hud_to(src)
secsensor.show_to(src)
medsensor.show_to(src)
diagsensor.show_to(src)
/mob/living/silicon/proc/toggle_sensors()
if(incapacitated())
@@ -104,7 +104,7 @@
var/beacon_freq = FREQ_NAV_BEACON
///The type of data HUD the bot uses. Diagnostic by default.
var/data_hud_type = DATA_HUD_DIAGNOSTIC_BASIC
var/datum/atom_hud/data/bot_path/path_hud = new /datum/atom_hud/data/bot_path()
var/datum/atom_hud/data/bot_path/path_hud
var/path_image_icon = 'icons/mob/aibots.dmi'
var/path_image_icon_state = "path_indicator"
var/path_image_color = "#FFFFFF"
@@ -164,6 +164,11 @@
/mob/living/simple_animal/bot/Initialize(mapload)
. = ..()
GLOB.bots_list += src
path_hud = new /datum/atom_hud/data/bot_path()
for(var/hud in path_hud.hud_icons) // You get to see your own path
set_hud_image_active(hud, exclusive_hud = path_hud)
// Give bots a fancy new ID card that can hold any access.
access_card = new /obj/item/card/id/advanced/simple_bot(src)
// This access is so bots can be immediately set to patrol and leave Robotics, instead of having to be let out first.
@@ -178,7 +183,7 @@
//Adds bot to the diagnostic HUD system
prepare_huds()
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
diag_hud.add_to_hud(src)
diag_hud.add_atom_to_hud(src)
diag_hud_set_bothealth()
diag_hud_set_botstat()
diag_hud_set_botmode()
@@ -186,10 +191,10 @@
//If a bot has its own HUD (for player bots), provide it.
if(!isnull(data_hud_type))
var/datum/atom_hud/datahud = GLOB.huds[data_hud_type]
datahud.add_hud_to(src)
datahud.show_to(src)
if(path_hud)
path_hud.add_to_hud(src)
path_hud.add_hud_to(src)
path_hud.add_atom_to_hud(src)
path_hud.show_to(src)
/mob/living/simple_animal/bot/Destroy()
@@ -1022,11 +1027,10 @@ Pass a positive integer as an argument to override a bot's default speed.
var/list/path_huds_watching_me = list(GLOB.huds[DATA_HUD_DIAGNOSTIC_ADVANCED])
if(path_hud)
path_huds_watching_me += path_hud
for(var/V in path_huds_watching_me)
var/datum/atom_hud/H = V
H.remove_from_hud(src)
for(var/datum/atom_hud/hud as anything in path_huds_watching_me)
hud.remove_atom_from_hud(src)
var/list/path_images = hud_list[DIAG_PATH_HUD]
var/list/path_images = active_hud_list[DIAG_PATH_HUD]
QDEL_LIST(path_images)
if(newpath)
for(var/i in 1 to newpath.len)
@@ -1065,9 +1069,8 @@ Pass a positive integer as an argument to override a bot's default speed.
path[T] = I
path_images += I
for(var/V in path_huds_watching_me)
var/datum/atom_hud/H = V
H.add_to_hud(src)
for(var/datum/atom_hud/hud as anything in path_huds_watching_me)
hud.add_atom_to_hud(src)
/mob/living/simple_animal/bot/proc/increment_path()
if(!length(path))
@@ -306,7 +306,7 @@
/mob/living/simple_animal/hostile/construct/artificer/Initialize(mapload)
. = ..()
var/datum/atom_hud/datahud = GLOB.huds[health_hud]
datahud.add_hud_to(src)
datahud.show_to(src)
/mob/living/simple_animal/hostile/construct/artificer/Found(atom/A) //what have we found here?
if(isconstruct(A)) //is it a construct?
@@ -182,7 +182,7 @@
alert_drones(DRONE_NET_CONNECT)
for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds)
diag_hud.add_to_hud(src)
diag_hud.add_atom_to_hud(src)
ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT)
ADD_TRAIT(src, TRAIT_NEGATES_GRAVITY, INNATE_TRAIT)
@@ -56,11 +56,11 @@
/mob/living/simple_animal/robot_customer/MouseEntered(location, control, params)
. = ..()
hud_to_show_on_hover?.add_hud_to(usr)
hud_to_show_on_hover?.show_to(usr)
/mob/living/simple_animal/robot_customer/MouseExited(location, control, params)
. = ..()
hud_to_show_on_hover?.remove_hud_from(usr)
hud_to_show_on_hover?.hide_from(usr)
/mob/living/simple_animal/robot_customer/update_overlays()
. = ..()
@@ -49,4 +49,4 @@
var/mob/living/M = AM
if(!hasmatchingsummoner(M) && M != summoner && M.fire_stacks < 7)
M.set_fire_stacks(7)
M.IgniteMob()
M.ignite_mob()
@@ -20,7 +20,7 @@
/mob/living/simple_animal/hostile/guardian/healer/Initialize(mapload)
. = ..()
var/datum/atom_hud/medsensor = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
medsensor.add_hud_to(src)
medsensor.show_to(src)
/mob/living/simple_animal/hostile/guardian/healer/get_status_tab_items()
. = ..()
@@ -142,7 +142,7 @@
/mob/living/simple_animal/hostile/giant_spider/nurse/Initialize(mapload)
. = ..()
var/datum/atom_hud/datahud = GLOB.huds[health_hud]
datahud.add_hud_to(src)
datahud.show_to(src)
/mob/living/simple_animal/hostile/giant_spider/nurse/AttackingTarget()
if(is_busy)
@@ -163,7 +163,7 @@
K.transform = final
living_target.adjustFireLoss(30)
living_target.adjust_fire_stacks(0.2)//Just here for the showmanship
living_target.IgniteMob()
living_target.ignite_mob()
playsound(living_target,'sound/weapons/sear.ogg', 50, TRUE)
addtimer(CALLBACK(src, .proc/AttackRecovery), 5)
return

Some files were not shown because too many files have changed in this diff Show More