This commit is contained in:
nevimer
2025-08-05 19:11:21 -04:00
12 changed files with 39 additions and 239 deletions
+3
View File
@@ -7,3 +7,6 @@ GLOBAL_DATUM_INIT(noncapital_i, /regex, regex("\\b\[i]\\b", "g")) */ // TODO: RE
/// Used for the trait for when a dragon looses a portal
#define DRAGON_PORTAL_LOSS "dragon_portal_loss"
/// Crew monitoring console update period. Why is this not a global define, why do I have to define it again
#define SENSORS_UPDATE_PERIOD (7 SECONDS)
+11 -10
View File
@@ -1,5 +1,5 @@
/// How often the sensor data is updated
#define SENSORS_UPDATE_PERIOD (10 SECONDS) //How often the sensor data updates.
/// How often the sensor data is updated // BUBBER EDIT REMOVAL - Defined in code/__DEFINES/~~bubber_defines/misc.dm
// #define SENSORS_UPDATE_PERIOD (10 SECONDS) //How often the sensor data updates.
/// The job sorting ID associated with otherwise unknown jobs
#define UNKNOWN_JOB_ID 998
@@ -182,7 +182,7 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
/datum/crewmonitor/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if (!ui)
ui = new(user, src, "CrewConsoleSkyrat")
ui = new(user, src, "CrewConsoleBubbers") // BUBBER EDIT CHANGE - Crew Console
ui.open()
/datum/crewmonitor/proc/show(mob/M, source)
@@ -285,7 +285,7 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
// Broken sensors show garbage data
if (uniform?.has_sensor == BROKEN_SENSORS) // BUBBER EDIT CHANGE - NANITES - Original: if (uniform.has_sensor == BROKEN_SENSORS)
entry["life_status"] = rand(0,1)
entry["life_status"] = 1 // BUBBER EDIT CHANGE - Original: rand(0,1) - Mob stays in consistent list position when sensors are broken
entry["area"] = pick_list (ION_FILE, "ionarea")
entry["oxydam"] = rand(0,175)
entry["toxdam"] = rand(0,175)
@@ -301,12 +301,13 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
if (sensor_mode >= SENSOR_LIVING)
entry["is_dnr"] = tracked_human.get_dnr()
// Current status
if(!isprotean(tracked_human))
entry["life_status"] = tracked_living_mob.stat
var/obj/item/organ/brain/protean/protean_brain = tracked_human.get_organ_slot(ORGAN_SLOT_BRAIN)
if(istype(protean_brain))
if(!isprotean(tracked_human))
stack_trace("[tracked_human] brain-species mismatch! Species is [tracked_human.dna.species] but brain is Protean")
entry["life_status"] = protean_brain?.dead ? DEAD : tracked_living_mob.stat // If brain not dead/no brain then handling as usual
else
// Check if protean is stuck in suit
var/obj/item/organ/brain/protean/brain = tracked_human.get_organ_slot(ORGAN_SLOT_BRAIN)
entry["life_status"] = brain?.dead ? DEAD : tracked_living_mob.stat // If brain not dead/no brain then handling as usual
entry["life_status"] = tracked_living_mob.stat
// BUBBERSTATION EDIT END
// Damage
@@ -346,5 +347,5 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
return
AI.ai_tracking_tool.track_name(AI, params["name"])
#undef SENSORS_UPDATE_PERIOD
// #undef SENSORS_UPDATE_PERIOD // BUBBER EDIT REMOVAL - Defined in code/__DEFINES/~~bubber_defines/misc.dm
#undef UNKNOWN_JOB_ID
+2 -7
View File
@@ -103,18 +103,13 @@ GLOBAL_LIST_INIT(holiday_mail, list())
if(PATTERN_RAINBOW)
var/datum/holiday/pride_week/rainbow_datum = new()
return rainbow_datum.get_holiday_colors(thing_to_color, PATTERN_DEFAULT)
//if(!length(GLOB.holidays)) // BUBBER EDIT REMOVAL - Pride Flag Colors
// return // BUBBER EDIT REMOVAL - Pride Flag Colors
if(!length(GLOB.holidays))
return
for(var/holiday_key in GLOB.holidays)
var/datum/holiday/holiday_real = GLOB.holidays[holiday_key]
if(!holiday_real.holiday_colors)
continue
return holiday_real.get_holiday_colors(thing_to_color, pattern || holiday_real.holiday_pattern)
// BUBBER EDIT ADDITION BEGIN - Pride Flag Colors
if(prob(20))
var/datum/holiday/pride_week/rainbow_datum = new()
return rainbow_datum.get_holiday_colors(thing_to_color, pattern)
// BUBBER EDIT ADDITION END - Pride Flag Colors
// The actual holidays
+1 -1
View File
@@ -1532,7 +1532,7 @@
return
//Bubber edit BEGIN - Allow for people to get hungry faster
if(HAS_TRAIT(src, TRAIT_FAST_METABOLISM) && change < 0)
change = change * 2
change = change * 1.5
//Bubber edit END
nutrition = max(0, nutrition + change)
@@ -1,4 +0,0 @@
author: "StrangeWeirdKitten"
delete-after: True
changes:
- rscadd: "MODsuit Remote Module that allows you to remotely control other people's modsuits"
@@ -43,3 +43,14 @@
Modular Suit Equipment research.
thegrb93:
- rscadd: Added vox hairstyles, vox braids, vox wise braids, vox flowing
2025-08-05:
LT3:
- bugfix: Fixed edge case of Proteans causing crew health monitor to bluescreen
- qol: Mobs with broken suit sensors now stay in order each screen update
StrangeWeirdKitten:
- rscadd: MODsuit Remote Module that allows you to remotely control other people's
modsuits
lessthnthree:
- bugfix: Station tile decal color should be back to normal
shayoki:
- balance: Vulpkanin hunger drain reduced from 2x -> 1.5x
@@ -2,9 +2,6 @@
* Trimmed and modified copy of ".../machinery/computer/crew.dm"
* for the sake of modularity. (Blueshield Monitor Console soon?)
*/
#define SENSORS_UPDATE_PERIOD (10 SECONDS)
GLOBAL_DATUM_INIT(blueshield_crewmonitor, /datum/crewmonitor/blueshield, new)
//list of all Command/CC jobs
@@ -129,5 +126,3 @@ GLOBAL_DATUM_INIT(blueshield_crewmonitor, /datum/crewmonitor/blueshield, new)
last_update["[z]"] = world.time
return results
#undef SENSORS_UPDATE_PERIOD
@@ -64,7 +64,7 @@
SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK,
SPECIES_PERK_ICON = "stomach",
SPECIES_PERK_NAME = "Hunger",
SPECIES_PERK_DESC = "Vulpkanin will get hungry twice as fast as most species",
SPECIES_PERK_DESC = "Vulpkanin will get hungrier 50% faster than most species",
))
return to_add
@@ -113,9 +113,3 @@
JOB_TERRAGOV_LIASON = 903
)
/datum/crewmonitor/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if (!ui)
ui = new(user, src, "CrewConsoleBubbers")
ui.open()
@@ -1,4 +1,3 @@
#define SENSORS_UPDATE_PERIOD 15 SECONDS //Why is this not a global define, why do I have to define it again
#define ALARM_PERIOD 45 SECONDS
/obj/machinery/computer/crew
@@ -51,5 +50,4 @@
return canalarm
#undef SENSORS_UPDATE_PERIOD
#undef ALARM_PERIOD
@@ -90,6 +90,15 @@ const areaSort = (a: CrewSensor, b: CrewSensor) => {
return 0;
};
const getHealthLevel = (healthSum: number): number => {
if (healthSum <= 74) return 0;
if (healthSum <= 95) return 1;
if (healthSum <= 116) return 2;
if (healthSum <= 137) return 3;
if (healthSum <= 158) return 4;
return 5; // over 158 (near crit)
};
const healthToAttribute = (
oxy: number,
tox: number,
@@ -98,7 +107,7 @@ const healthToAttribute = (
attributeList: string[],
) => {
const healthSum = oxy + tox + burn + brute;
const level = Math.min(Math.max(Math.ceil(healthSum / 25), 0), 5);
const level = getHealthLevel(healthSum);
return attributeList[level];
};
@@ -1,202 +0,0 @@
// THIS IS A SKYRAT UI FILE
import { sortBy } from 'es-toolkit';
import { Box, Button, Icon, Section, Table } from 'tgui-core/components';
import { useBackend } from '../backend';
import { COLORS } from '../constants';
import { Window } from '../layouts';
const HEALTH_COLOR_BY_LEVEL = [
'#17d568',
'#c4cf2d',
'#e67e22',
'#ed5100',
'#e74c3c',
'#801308',
];
const STAT_LIVING = 0;
const STAT_DEAD = 4;
const jobIsHead = (jobId) => jobId % 10 === 0;
const jobToColor = (jobId) => {
if (jobId === 0) {
return COLORS.department.captain;
}
if (jobId >= 10 && jobId < 20) {
return COLORS.department.security;
}
if (jobId >= 20 && jobId < 30) {
return COLORS.department.medbay;
}
if (jobId >= 30 && jobId < 40) {
return COLORS.department.science;
}
if (jobId >= 40 && jobId < 50) {
return COLORS.department.engineering;
}
if (jobId >= 50 && jobId < 60) {
return COLORS.department.cargo;
}
if (jobId >= 60 && jobId < 80) {
return COLORS.department.service;
}
if (jobId >= 200 && jobId < 240) {
return COLORS.department.centcom;
}
return COLORS.department.other;
};
const healthToAttribute = (oxy, tox, burn, brute, attributeList) => {
const healthSum = oxy + tox + burn + brute;
const level = Math.min(Math.max(Math.ceil(healthSum / 50), 0), 5);
// 200 Default Health, Sum Divided by 50, 6 Health States
return attributeList[level];
};
const HealthStat = (props) => {
const { type, value } = props;
return (
<Box inline width={2} color={COLORS.damageType[type]} textAlign="center">
{value}
</Box>
);
};
const statToIcon = (life_status) => {
switch (life_status) {
case STAT_LIVING:
return 'heart';
case STAT_DEAD:
return 'skull';
}
return 'heartbeat';
};
export const CrewConsoleSkyrat = () => {
return (
<Window title="Crew Monitor" width={600} height={600}>
<Window.Content scrollable>
<Section minHeight="540px">
<CrewTable />
</Section>
</Window.Content>
</Window>
);
};
const CrewTable = (props) => {
const { act, data } = useBackend();
const sensors = sortBy(data.sensors ?? [], (s) => s.ijob);
return (
<Table cellpadding="3">
<Table.Row>
<Table.Cell bold colspan="2">
Name
</Table.Cell>
<Table.Cell bold collapsing textAlign="center">
Status
</Table.Cell>
<Table.Cell bold collapsing textAlign="center">
Vitals
</Table.Cell>
<Table.Cell bold width="180px" collapsing textAlign="center">
Position
</Table.Cell>
</Table.Row>
{sensors.map((sensor) => (
<CrewTableEntry sensor_data={sensor} key={sensor.ref} />
))}
</Table>
);
};
const CrewTableEntry = (props) => {
const { act, data } = useBackend();
const { link_allowed } = data;
const { sensor_data } = props;
const {
name,
assignment,
ijob,
is_robot,
is_dnr,
life_status,
oxydam,
toxdam,
burndam,
brutedam,
area,
can_track,
} = sensor_data;
return (
<Table.Row>
<Table.Cell bold={jobIsHead(ijob)} color={jobToColor(ijob)}>
{name}
{assignment !== undefined ? ` (${assignment})` : ''}
</Table.Cell>
<Table.Cell collapsing textAlign="center">
{is_robot ? <Icon name="wrench" color="#B7410E" size={1} /> : ''}
</Table.Cell>
<Table.Cell collapsing textAlign="center">
{oxydam !== undefined ? (
<Icon
name={statToIcon(life_status)}
color={healthToAttribute(
oxydam,
toxdam,
burndam,
brutedam,
HEALTH_COLOR_BY_LEVEL,
)}
size={1}
/>
) : life_status !== STAT_DEAD ? (
<Icon name="heart" color="#17d568" size={1} />
) : (
<Icon name="skull" color="#801308" size={1} />
)}
{!life_status && is_dnr ? ' (DNR)' : ''}
</Table.Cell>
<Table.Cell collapsing textAlign="center">
{oxydam !== undefined ? (
<Box inline>
<HealthStat type="oxy" value={oxydam} />
{'/'}
<HealthStat type="toxin" value={toxdam} />
{'/'}
<HealthStat type="burn" value={burndam} />
{'/'}
<HealthStat type="brute" value={brutedam} />
</Box>
) : life_status !== STAT_DEAD ? (
'Alive'
) : (
'Dead'
)}
</Table.Cell>
<Table.Cell>
{area !== undefined ? (
area
) : (
<Icon name="question" color="#ffffff" size={1} />
)}
</Table.Cell>
{!!link_allowed && (
<Table.Cell collapsing>
<Button
content="Track"
disabled={!can_track}
onClick={() =>
act('select_person', {
name: name,
})
}
/>
</Table.Cell>
)}
</Table.Row>
);
};