Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
| Code | [https://github.com/PyrelightSS13/Pyrelight](https://github.com/PyrelightSS13/Pyrelight) |
| Issues | [https://github.com/PyrelightSS13/Pyrelight/issues](https://github.com/PyrelightSS13/Pyrelight/issues) |
| Upstream Issues | [https://github.com/NebulaSS13/Nebula/issues](https://github.com/NebulaSS13/Nebula/issues) |
| Discord | Currently private, sorry! |
| Discord | [https://discord.gg/BqXq6Mkys5](https://discord.gg/BqXq6Mkys5) |
| Nebula Discord | [https://discord.gg/DYGXkN2S](https://discord.gg/DYGXkN2S) |

This is the codebase for Pyrelight, a middle-fantasy total conversion project for Space Station 13, derived from Nebula SS13.
Expand Down
11 changes: 10 additions & 1 deletion code/_helpers/global_lists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,13 @@ var/global/list/bodytype_species_pairs = list() // A list of bodytypes -> specie
. = global.playable_species
/proc/get_bodytype_species_pairs()
build_species_lists()
. = global.bodytype_species_pairs
. = global.bodytype_species_pairs

// Used to avoid constantly generating new lists during movement.
var/global/list/all_stance_limbs = list(
ORGAN_CATEGORY_STANCE,
ORGAN_CATEGORY_STANCE_ROOT
)
var/global/list/child_stance_limbs = list(
ORGAN_CATEGORY_STANCE
)
7 changes: 6 additions & 1 deletion code/controllers/master.dm
Original file line number Diff line number Diff line change
Expand Up @@ -220,12 +220,17 @@ var/global/datum/controller/master/Master = new
CRASH("Attempted to set invalid runlevel: [new_runlevel]")

// Starts the mc, and sticks around to restart it if the loop ever ends.
var/global/_announced_start = FALSE
/datum/controller/master/proc/StartProcessing(delay)
set waitfor = 0
if(delay)
sleep(delay)
report_progress("Master starting processing")
SSwebhooks.send(WEBHOOK_ROUNDPREP, list("map" = station_name(), "url" = get_world_url()))

if(!global._announced_start) // Only announce roundstart once.
SSwebhooks.send(WEBHOOK_ROUNDPREP, list("map" = station_name(), "url" = get_world_url()))
global._announced_start = TRUE

var/rtn = Loop()
if (rtn > 0 || processing < 0)
return //this was suppose to happen.
Expand Down
26 changes: 6 additions & 20 deletions code/game/objects/effects/decals/Cleanable/humans.dm
Original file line number Diff line number Diff line change
Expand Up @@ -91,26 +91,12 @@
/obj/effect/decal/cleanable/blood/Crossed(atom/movable/AM)
if(!isliving(AM) || amount < 1)
return

var/mob/living/M = AM
var/obj/item/organ/external/l_foot = GET_EXTERNAL_ORGAN(M, BP_L_FOOT)
var/obj/item/organ/external/r_foot = GET_EXTERNAL_ORGAN(M, BP_R_FOOT)
var/hasfeet = l_foot && r_foot

var/transferred_data = blood_data ? blood_data[pick(blood_data)] : null
var/obj/item/clothing/shoes/shoes = M.get_equipped_item(slot_shoes_str)
if(istype(shoes) && !M.buckled)//Adding blood to shoes
shoes.add_coating(chemical, amount, transferred_data)
else if (hasfeet)//Or feet
if(l_foot)
l_foot.add_coating(chemical, amount, transferred_data)
if(r_foot)
r_foot.add_coating(chemical, amount, transferred_data)
else if (M.buckled && istype(M.buckled, /obj/structure/bed/chair/wheelchair))
var/obj/structure/bed/chair/wheelchair/W = M.buckled
W.bloodiness = 4

M.update_equipment_overlay(slot_shoes_str)
var/mob/living/walker = AM
if(istype(walker.buckled, /obj/structure/bed/chair/wheelchair))
var/obj/structure/bed/chair/wheelchair/wheelchair = walker.buckled
wheelchair.bloodiness = 4
else
walker.add_walking_contaminant(chemical, amount, (blood_data ? blood_data[pick(blood_data)] : null))
amount--

/obj/effect/decal/cleanable/blood/proc/dry()
Expand Down
13 changes: 12 additions & 1 deletion code/game/objects/effects/decals/Cleanable/misc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,20 @@
if(prob(75))
set_rotation(pick(90, 180, 270))

/obj/effect/decal/cleanable/vomit/mapped/Initialize(ml, _age)
. = ..()
add_to_reagents(/decl/material/liquid/acid/stomach, rand(3,5))
add_to_reagents(/decl/material/liquid/nutriment, rand(5,8))

/obj/effect/decal/cleanable/vomit/on_update_icon()
. = ..()
color = reagents.get_color()
color = reagents?.get_color()

/obj/effect/decal/cleanable/vomit/Crossed(atom/movable/AM)
. = ..()
if(!QDELETED(src) && reagents?.total_volume >= 1 && isliving(AM))
var/mob/living/walker = AM
walker.add_walking_contaminant(reagents, rand(2, 3))

/obj/effect/decal/cleanable/tomato_smudge
name = "tomato smudge"
Expand Down
6 changes: 3 additions & 3 deletions code/game/objects/item_mob_overlay.dm
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ var/global/list/icon_state_cache = list()
if(!use_single_icon)
var/mob_state = "[item_state || icon_state][state_modifier]"
var/mob_icon = global.default_onmob_icons[slot]
var/decl/bodytype/root_bodytype = user_mob?.get_bodytype()
var/decl/bodytype/root_bodytype = user_mob?.get_equipment_bodytype(slot, bodypart)
if(istype(root_bodytype))
var/use_slot = (bodypart in root_bodytype.equip_adjust) ? bodypart : slot
var/use_slot = (bodypart in root_bodytype.get_equip_adjustments(user_mob)) ? bodypart : slot
return root_bodytype.get_offset_overlay_image(user_mob, mob_icon, mob_state, color, use_slot)
return overlay_image(mob_icon, mob_state, color, RESET_COLOR)

Expand Down Expand Up @@ -153,7 +153,7 @@ var/global/list/icon_state_cache = list()
overlay.icon_state = wielded_state
apply_additional_mob_overlays(user_mob, bodytype, overlay, slot, bodypart, use_fallback_if_icon_missing)

var/decl/bodytype/root_bodytype = user_mob?.get_bodytype()
var/decl/bodytype/root_bodytype = user_mob?.get_equipment_bodytype(slot, bodypart)
if(root_bodytype && root_bodytype.bodytype_category != bodytype)
var/list/overlays_to_offset = overlay.overlays
overlay = root_bodytype.get_offset_overlay_image(user_mob, overlay.icon, overlay.icon_state, color, (bodypart || slot))
Expand Down
45 changes: 24 additions & 21 deletions code/game/objects/items/__item.dm
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
/// Set to false to skip state checking and never draw an icon on the mob (except when held)
var/draw_on_mob_when_equipped = TRUE

var/image/blood_overlay = null //this saves our blood splatter overlay, which will be processed not to go over the edges of the sprite
/// this saves our blood splatter/coating overlay, which will be processed not to go over the edges of the sprite.
var/image/coating_overlay
var/randpixel = 6
var/material_health_multiplier = 0.2
var/hitsound
Expand Down Expand Up @@ -245,7 +246,7 @@
/obj/item/PopulateClone(obj/item/clone)
clone = ..()
clone.contaminated = contaminated
clone.blood_overlay = image(blood_overlay)
clone.coating_overlay = image(coating_overlay)
clone.current_health = current_health

//#TODO: once item damage in, check health!
Expand Down Expand Up @@ -790,7 +791,7 @@
if(was_bloodied && !fluorescent)
fluorescent = FLUORESCENT_GLOWS
blood_color = COLOR_LUMINOL
blood_overlay.color = COLOR_LUMINOL
coating_overlay.color = COLOR_LUMINOL
update_icon()

/obj/item/add_blood(mob/living/M, amount = 2, list/blood_data)
Expand All @@ -814,21 +815,21 @@
LAZYSET(blood_DNA, unique_enzymes, blood_type)
return TRUE

var/global/list/_blood_overlay_cache = list()
var/global/icon/_item_blood_mask = icon('icons/effects/blood.dmi', "itemblood")
/obj/item/proc/generate_blood_overlay(force = FALSE)
if(blood_overlay && !force)
var/global/list/_coating_overlay_cache = list()
var/global/icon/_item_coating_mask = icon('icons/effects/blood.dmi', "itemblood")
/obj/item/proc/generate_coating_overlay(force = FALSE)
if(coating_overlay && !force)
return
var/cache_key = "[icon]-[icon_state]"
if(global._blood_overlay_cache[cache_key])
blood_overlay = global._blood_overlay_cache[cache_key]
if(global._coating_overlay_cache[cache_key])
coating_overlay = global._coating_overlay_cache[cache_key]
return
var/icon/I = new /icon(icon, icon_state)
I.MapColors(0,0,0, 0,0,0, 0,0,0, 1,1,1) // Sets the icon RGB channel to pure white.
I.Blend(global._item_blood_mask, ICON_MULTIPLY) // Masks the blood overlay against the generated mask.
blood_overlay = image(I)
blood_overlay.appearance_flags |= NO_CLIENT_COLOR|RESET_COLOR
global._blood_overlay_cache[cache_key] = blood_overlay
I.Blend(global._item_coating_mask, ICON_MULTIPLY) // Masks the coating overlay against the generated mask.
coating_overlay = image(I)
coating_overlay.appearance_flags |= NO_CLIENT_COLOR|RESET_COLOR
global._coating_overlay_cache[cache_key] = coating_overlay

/obj/item/proc/showoff(mob/user)
for(var/mob/M in view(user))
Expand Down Expand Up @@ -1018,13 +1019,15 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out.

/obj/item/proc/add_coating(reagent_type, amount, data)
if(!coating)
coating = new/datum/reagents(10, src)
coating.add_reagent(reagent_type, amount, data)

if(!blood_overlay)
generate_blood_overlay()
blood_overlay.color = coating.get_color()

coating = new /datum/reagents(10, src)
if(ispath(reagent_type))
coating.add_reagent(reagent_type, amount, data)
else if(istype(reagent_type, /datum/reagents))
var/datum/reagents/source = reagent_type
source.trans_to_holder(coating, amount)
if(!coating_overlay)
generate_coating_overlay()
coating_overlay.color = coating.get_color()
update_icon()

/obj/item/proc/remove_coating(amount)
Expand All @@ -1037,7 +1040,7 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out.
/obj/item/clean(clean_forensics=TRUE)
. = ..()
QDEL_NULL(coating)
blood_overlay = null
coating_overlay = null
if(clean_forensics)
var/datum/extension/forensic_evidence/forensics = get_extension(src, /datum/extension/forensic_evidence)
if(forensics)
Expand Down
4 changes: 2 additions & 2 deletions code/game/objects/items/_item_materials.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
if((material_alteration & MAT_FLAG_ALTERATION_COLOR) && material)
alpha = 100 + material.opacity * 255
color = get_color() // avoiding set_color() here as that will set it on paint_color
if(blood_overlay)
add_overlay(blood_overlay)
if(coating_overlay)
add_overlay(coating_overlay)
if(global.contamination_overlay && contaminated)
add_overlay(global.contamination_overlay)

Expand Down
4 changes: 2 additions & 2 deletions code/game/objects/items/weapons/swords_axes_etc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@
update_held_icon()

/obj/item/telebaton/on_update_icon()
if(length(blood_DNA))
generate_blood_overlay(TRUE) // Force recheck.
if(coating?.total_volume || blood_DNA)
generate_coating_overlay(TRUE) // Force recheck.
. = ..()
if(on)
icon = 'icons/obj/items/weapon/telebaton_extended.dmi'
Expand Down
6 changes: 6 additions & 0 deletions code/game/turfs/flooring/_flooring.dm
Original file line number Diff line number Diff line change
Expand Up @@ -350,3 +350,9 @@ var/global/list/flooring_cache = list()

/decl/flooring/proc/handle_turf_digging(turf/floor/target)
return TRUE

/decl/flooring/proc/turf_crossed(atom/movable/crosser)
return

/decl/flooring/proc/can_show_footsteps(turf/target)
return TRUE
9 changes: 9 additions & 0 deletions code/game/turfs/flooring/flooring_mud.dm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@
return
return ..()

/decl/flooring/mud/turf_crossed(atom/movable/crosser)
if(!isliving(crosser))
return
var/mob/living/walker = crosser
walker.add_walking_contaminant(/decl/material/solid/soil, rand(2,3))

/decl/flooring/mud/can_show_footsteps(turf/target)
return FALSE // So we don't end up covered in a million footsteps that we provided.

/decl/flooring/dry_mud
name = "dry mud"
desc = "This was once mud, but forgot to keep hydrated."
Expand Down
8 changes: 8 additions & 0 deletions code/game/turfs/floors/_floor.dm
Original file line number Diff line number Diff line change
Expand Up @@ -297,3 +297,11 @@
/turf/floor/get_plant_growth_rate()
var/decl/flooring/flooring = get_topmost_flooring()
return flooring ? flooring.growth_value : ..()

/turf/floor/Crossed(atom/movable/AM)
var/decl/flooring/flooring = get_topmost_flooring()
flooring?.turf_crossed(AM)
return ..()

/turf/floor/can_show_footsteps()
return ..() && get_topmost_flooring()?.can_show_footsteps(src)
3 changes: 3 additions & 0 deletions code/game/turfs/turf.dm
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,9 @@
if(IS_HOE(held) && can_dig_farm(held.material?.hardness))
LAZYDISTINCTADD(., /decl/interaction_handler/dig/farm)

/turf/proc/can_show_footsteps()
return simulated

/decl/interaction_handler/show_turf_contents
name = "Show Turf Contents"
expected_user_type = /mob
Expand Down
18 changes: 11 additions & 7 deletions code/modules/bodytype/bodytype_offsets.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ each one can be in the NORTH, SOUTH, EAST, and WEST direction. Specify
the x and y amounts to shift the thing for a given direction.

example:
equip_adjust = list(
slot_back_str = list("[NORTH]" = list(-12, 7), "[EAST]" = list(-2, -12))
_equip_adjust = list(
(slot_back_str) = list("[NORTH]" = list(-12, 7), "[EAST]" = list(-2, -12))
)

This would shift back items (backpacks, axes, etc.) when the mob
Expand All @@ -18,15 +18,19 @@ The slots that you can use are found in items_clothing.dm and are the inventory
*/

/decl/bodytype
var/list/equip_adjust
var/list/equip_overlays = list()
VAR_PRIVATE/list/_equip_adjust
VAR_PRIVATE/list/equip_overlays = list()

/decl/bodytype/proc/get_equip_adjust(mob/mob)
return equip_adjust
// Will be used by changelings/shapeshifters in the future
/decl/bodytype/proc/resolve_to_equipment_bodytype(mob/living/user)
return src

/decl/bodytype/proc/get_equip_adjustments(mob/mob)
return _equip_adjust

/decl/bodytype/proc/get_offset_overlay_image(mob/mob, mob_icon, mob_state, color, slot)
// If we don't actually need to offset this, don't bother with any of the generation/caching.
var/list/use_equip_adjust = get_equip_adjust(mob)
var/list/use_equip_adjust = get_equip_adjustments(mob)
if(length(use_equip_adjust) && use_equip_adjust[slot] && length(use_equip_adjust[slot]))

// Check the cache for previously made icons.
Expand Down
3 changes: 3 additions & 0 deletions code/modules/crafting/handmade_items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
if((. = ..()))
update_icon()

/obj/item/chems/glass/handmade/get_mould_difficulty()
return SKILL_NONE

/obj/item/chems/glass/handmade/teapot
name = "teapot"
desc = "A handmade, slightly lumpy teapot."
Expand Down
13 changes: 7 additions & 6 deletions code/modules/detectivework/evidence/_evidence_type.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@
var/max_entries = 10 //will hold that many entries, removing oldest when overflown
var/list/data
var/remove_on_transfer //if it should be removed when picked up by forensic samplers
var/spot_skill = SKILL_EXPERT // at what Forensics skill level someone can see it on examine. Set to null, can never see it
var/spot_skill = SKILL_EXPERT // at what Forensics skill level someone can see it on examine. Set to null, can never see it

//subtypes can implement any merging if needed before calling parent
/datum/forensics/proc/add_data(newdata)
if(!newdata)
return
if(unique && (newdata in data))
return
LAZYADD(data, newdata)
if(unique)
LAZYDISTINCTADD(data, newdata)
else
LAZYADD(data, newdata)
if(length(data) > max_entries)
data.Cut(1,2)
data.len = max_entries

/datum/forensics/proc/add_from_atom(atom/A)

Expand All @@ -28,7 +29,7 @@
for(var/D in data)
. += "<li>[D]"
return jointext(., "<br>")

/datum/forensics/proc/can_spot(mob/detective, atom/location)
. = FALSE
if(spot_skill && detective.skill_check(SKILL_FORENSICS,spot_skill))
Expand Down
1 change: 1 addition & 0 deletions code/modules/detectivework/evidence/fingerprints.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
continue
for(var/datum/fingerprint/F in data)
if(F.merge(newprint))
newdata -= newprint
continue
..()

Expand Down
7 changes: 4 additions & 3 deletions code/modules/detectivework/tools/uvlight.dm
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
add_overlay(emissive_overlay(icon, "[icon_state]-on"))
z_flags |= ZMM_MANGLE_PLANES

// TODO: does this even work with SSoverlays?
/obj/item/uv_light/proc/clear_last_scan()
if(scanned.len)
for(var/atom/O in scanned)
Expand All @@ -62,7 +63,7 @@
stored_alpha.Cut()
if(reset_objects.len)
for(var/obj/item/I in reset_objects)
I.overlays -= I.blood_overlay
I.overlays -= I.coating_overlay
if(I.fluorescent == FLUORESCENT_GLOWING)
I.fluorescent = FLUORESCENT_GLOWS
reset_objects.Cut()
Expand All @@ -86,6 +87,6 @@
A.alpha = use_alpha
if(istype(A, /obj/item))
var/obj/item/O = A
if(O.was_bloodied && !(O.blood_overlay in O.overlays))
O.overlays |= O.blood_overlay
if(O.was_bloodied && !(O.coating_overlay in O.overlays))
O.overlays |= O.coating_overlay
reset_objects |= O
Loading
Loading