mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 13:10:02 +01:00
Merge branch 'master' of https://github.com/Bubberstation/Bubberstation
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -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>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user