Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"See who is boss of the GYM" (Global playtimes section) #6931

Closed
Closed
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
36 changes: 35 additions & 1 deletion code/controllers/subsystem/playtime.dm
Original file line number Diff line number Diff line change
@@ -1,11 +1,45 @@
SUBSYSTEM_DEF(playtime)
name = "Playtime"
wait = 1 MINUTES
init_order = SS_INIT_PLAYTIME
priority = SS_PRIORITY_PLAYTIME
flags = SS_NO_INIT | SS_KEEP_TIMING
flags = SS_KEEP_TIMING

var/list/best_playtimes = list()
var/list/currentrun = list()

/datum/controller/subsystem/playtime/Initialize()
get_best_playtimes()
return SS_INIT_SUCCESS

/datum/controller/subsystem/playtime/proc/get_best_playtimes()
set waitfor = FALSE
set background = TRUE

WAIT_DB_READY

var/list/datum/view_record/playtime/all_records = DB_VIEW(/datum/view_record/playtime)
var/list/real_best_playtimes = list()
for(var/datum/view_record/playtime/record as anything in all_records)
CHECK_TICK
if(!real_best_playtimes[record.role_id])
real_best_playtimes[record.role_id] = list(record.total_minutes, record)
continue
if(real_best_playtimes[record.role_id][1] > record.total_minutes)
continue
real_best_playtimes[record.role_id] = list(record.total_minutes, record)

for(var/role_name in real_best_playtimes)
CHECK_TICK
var/list/info_list = real_best_playtimes[role_name]
var/datum/view_record/playtime/record = info_list[2]
if(!record)
continue
var/datum/view_record/players/player = SAFEPICK(DB_VIEW(/datum/view_record/players, DB_COMP("id", DB_EQUALS, record.player_id)))
if(!player)
continue
best_playtimes += list(list("ckey" = player.glob_pt_visibility ? player.ckey : "Anon #[player.id]") + record.get_nanoui_data())

/datum/controller/subsystem/playtime/fire(resumed = FALSE)
if (!resumed)
src.currentrun = GLOB.clients.Copy()
Expand Down
7 changes: 6 additions & 1 deletion code/datums/entities/player.dm
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
var/byond_account_age
var/first_join_date

var/glob_pt_visibility = FALSE


// UNTRACKED FIELDS
var/name // Used for NanoUI statistics menu
Expand Down Expand Up @@ -83,6 +85,7 @@ BSQL_PROTECT_DATUM(/datum/entity/player)
"stickyban_whitelisted" = DB_FIELDTYPE_INT,
"byond_account_age" = DB_FIELDTYPE_STRING_MEDIUM,
"first_join_date" = DB_FIELDTYPE_STRING_MEDIUM,
"glob_pt_visibility" = DB_FIELDTYPE_INT,
)

// NOTE: good example of database operations using NDatabase, so it is well commented
Expand Down Expand Up @@ -764,6 +767,7 @@ BSQL_PROTECT_DATUM(/datum/entity/player)
var/last_known_ip
var/discord_link_id
var/whitelist_status
var/glob_pt_visibility

/datum/entity_view_meta/players
root_record_type = /datum/entity/player
Expand All @@ -781,5 +785,6 @@ BSQL_PROTECT_DATUM(/datum/entity/player)
"last_known_ip",
"last_known_cid",
"discord_link_id",
"whitelist_status"
"whitelist_status",
"glob_pt_visibility",
)
11 changes: 10 additions & 1 deletion code/datums/entities/player_times.dm
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ BSQL_PROTECT_DATUM(/datum/entity/player_time)
/datum/entity/player/ui_data(mob/user)
if(!LAZYACCESS(playtime_data, "loaded"))
load_timestat_data()
return playtime_data
return list("playtime" = playtime_data, "playtimeglob" = SSplaytime.best_playtimes)

/datum/entity/player/ui_state(mob/user)
return GLOB.always_state
Expand Down Expand Up @@ -141,3 +141,12 @@ BSQL_PROTECT_DATUM(/datum/entity/player_time)
/proc/get_total_living_playtime(player_id)
for(var/datum/view_record/playtime/time in DB_VIEW(/datum/view_record/playtime, DB_AND(DB_COMP("player_id", DB_EQUALS, player_id), DB_COMP("role_id", DB_NOTEQUAL, "Observer"))))
. += time.total_minutes

/client/verb/toggle_ckey_visiblity_playtime()
set name = "Toggle Ckey Visibility In Playtimes"
set category = "Preferences.UI"
set desc = ".Enable or Disable your own ckey visiblity in global playtimes"
if(player_data)
player_data.glob_pt_visibility = !player_data.glob_pt_visibility
to_chat(src, SPAN_BOLDNOTICE("Now your ckey [player_data.glob_pt_visibility ? "showing" : "hidden"] in global playtimes (effect will be taken on next round)"))
player_data.save()
138 changes: 109 additions & 29 deletions tgui/packages/tgui/interfaces/Playtime.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,26 @@ interface PlaytimeRecord {
icondisplay: string | undefined;
}

interface PlaytimeData {
interface PlaytimeRecordGlob {
ckey: string;
job: string;
playtime: number;
bgcolor: string;
textcolor: string;
icondisplay: string | undefined;
}

interface PlaytimeRowsPrivate {
stored_human_playtime: PlaytimeRecord[];
stored_xeno_playtime: PlaytimeRecord[];
stored_other_playtime: PlaytimeRecord[];
}

interface PlaytimeRows {
playtime: PlaytimeRowsPrivate;
playtimeglob: PlaytimeRecordGlob[];
}

const PlaytimeRow = (props: { readonly data: PlaytimeRecord }) => {
return (
<>
Expand All @@ -44,6 +58,33 @@ const PlaytimeRow = (props: { readonly data: PlaytimeRecord }) => {
);
};

const PlaytimeRowGlob = (props: { readonly data: PlaytimeRecordGlob }) => {
return (
<>
<TableCell className="AwardCell">
{props.data.icondisplay && (
<span
className={classes([
'AwardIcon',
'playtimerank32x32',
props.data.icondisplay,
])}
/>
)}
</TableCell>
<TableCell>
<span className="LabelSpan">{props.data.job}</span>
</TableCell>
<TableCell>
<span className="CkeySpan">{props.data.ckey}</span>
</TableCell>
<TableCell>
<span className="TimeSpan">{props.data.playtime.toFixed(1)} hr</span>
</TableCell>
</>
);
};

const PlaytimeTable = (props: { readonly data: PlaytimeRecord[] }) => {
return (
<Table>
Expand All @@ -59,52 +100,91 @@ const PlaytimeTable = (props: { readonly data: PlaytimeRecord[] }) => {
);
};

const PlaytimeTableGlob = (props: { readonly data: PlaytimeRecordGlob[] }) => {
return (
<Table>
{props.data
.filter((x) => x.playtime !== 0)
.map((x) => (
<TableRow key={x.job} className="PlaytimeRowGlob">
<PlaytimeRowGlob data={x} />
</TableRow>
))}
</Table>
);
};

export const Playtime = (props) => {
const { data } = useBackend<PlaytimeData>();
const [selected, setSelected] = useState('human');
const { data } = useBackend<PlaytimeRows>();
const { playtime, playtimeglob } = data;
const [selected, setSelected] = useState('private');
const [selectedplaytime, setSelectedplaytime] = useState('human');
const humanTime =
data.stored_human_playtime.length > 0
? data.stored_human_playtime[0].playtime
playtime.stored_human_playtime.length > 0
? playtime.stored_human_playtime[0].playtime
: 0;
const xenoTime =
data.stored_xeno_playtime.length > 0
? data.stored_xeno_playtime[0].playtime
playtime.stored_xeno_playtime.length > 0
? playtime.stored_xeno_playtime[0].playtime
: 0;
const otherTime =
data.stored_other_playtime.length > 0
? data.stored_other_playtime[0].playtime
playtime.stored_other_playtime.length > 0
? playtime.stored_other_playtime[0].playtime
: 0;

return (
<Window theme={selected !== 'xeno' ? 'usmc' : 'hive_status'}>
<Window.Content className="PlaytimeInterface" scrollable>
<Tabs fluid>
<Tabs.Tab
selected={selected === 'human'}
onClick={() => setSelected('human')}
>
Human ({humanTime} hr)
</Tabs.Tab>
<Tabs.Tab
selected={selected === 'xeno'}
onClick={() => setSelected('xeno')}
selected={selected === 'global'}
onClick={() => setSelected('global')}
>
Xeno ({xenoTime} hr)
Global
</Tabs.Tab>
<Tabs.Tab
selected={selected === 'other'}
onClick={() => setSelected('other')}
selected={selected === 'private'}
onClick={() => setSelected('private')}
>
Other ({otherTime} hr)
Private
</Tabs.Tab>
</Tabs>
{selected === 'human' && (
<PlaytimeTable data={data.stored_human_playtime} />
)}
{selected === 'xeno' && (
<PlaytimeTable data={data.stored_xeno_playtime} />
)}
{selected === 'other' && (
<PlaytimeTable data={data.stored_other_playtime} />
{selected === 'global' ? (
<Table>
<PlaytimeTableGlob data={playtimeglob} />
</Table>
) : (
<Table>
<Tabs fluid>
<Tabs.Tab
selected={selectedplaytime === 'human'}
onClick={() => setSelectedplaytime('human')}
>
Human ({humanTime} hr)
</Tabs.Tab>
<Tabs.Tab
selected={selectedplaytime === 'xeno'}
onClick={() => setSelectedplaytime('xeno')}
>
Xeno ({xenoTime} hr)
</Tabs.Tab>
<Tabs.Tab
selected={selectedplaytime === 'other'}
onClick={() => setSelectedplaytime('other')}
>
Other ({otherTime} hr)
</Tabs.Tab>
</Tabs>
{selectedplaytime === 'human' && (
<PlaytimeTable data={playtime.stored_human_playtime} />
)}
{selectedplaytime === 'xeno' && (
<PlaytimeTable data={playtime.stored_xeno_playtime} />
)}
{selectedplaytime === 'other' && (
<PlaytimeTable data={playtime.stored_other_playtime} />
)}
</Table>
)}
</Window.Content>
</Window>
Expand Down
Loading