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

TTT: Enable scoreboard to be sorted by different criteria other than score #1332

Merged
merged 74 commits into from Apr 19, 2017

Conversation

DirkyJerky
Copy link
Contributor

@DirkyJerky DirkyJerky commented Feb 15, 2017

Reasoning:

  • Sorting by score isn't very useful.
  • An unsorted scoreboard is very difficult to use efficiently on large servers
    --- It can take several seconds to find a specific person on it, especially if some of them are color coded.
  • Most people can search an alphabetically sorted list far quicker than one that is not.

Current status:

  • Titles in the column header row are clickable to make the scoreboard sort by that criteria
  • TTTScoreboardColumns hook extended so a sorting function can be optionally added for sortable custom columns
  • Pseudo-markdown pseudo-documentation for said hook

Pictures!: Name | Role - T | Role - D | Role - I | Score | Karma | Deaths | Ping | Custom column test

bt = k
end
end
return bt > at
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't this all be replaced by:

local function CompareRowsByName(rowa, rowb)
    local plya = rowa:GetPlayer()
    if not IsValid(plya) then return false end

    local plyb = rowb:GetPlayer()
    if not IsValid(plyb) then return true end

    return plya:GetName() < plyb:GetName() -- might be >
end

@@ -91,6 +94,8 @@ CreateConVar("ttt_det_credits_starting", "1")
CreateConVar("ttt_det_credits_traitorkill", "0")
CreateConVar("ttt_det_credits_traitordead", "1")

-- Other
CreateConVar("ttt_scoreboard_sorting", "1", FCVAR_NOTIFY + FCVAR_REPLICATED)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of a ConVar, why not allow the clients to sort by clicking on the column headings or something?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea; but I believe I need to keep the ConVar as I could not find a shared object needed to host the variable. There may be one though; I'm not very familiar with the codebase.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be a property of the scoreboard object





Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You seem to have quite a bit of whitespace here and above.


local function CompareDeath(pa, pb)
if not IsValid(pa) then return false end
if not IsValid(pb) then return true end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rows should always be valid at call time so these checks can be removed.

if not IsValid(pb) then return true end

local a = pa:GetPlayer()
local b = pb:GetPlayer()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to use some more descriptive variable names for the rows and players. It took me longer to figure out the purpose of this code than if they had been properly labelled.

@Kefta
Copy link
Contributor

Kefta commented Feb 15, 2017

A few things: you should use bit.* operations for bit flags instead of normal arithmetic. In this case, CreateConVar actually supports sending in a table of flags that it will merge internally. Next, you should always test pull requests before submitting them; community feedback is great, but it works even better on working code. Also, why are you doing all of that extra sorting work in CompareAlpha?

@DirkyJerky
Copy link
Contributor Author

I just finished testing it; it works fine.

I was not the one that created the initial code; I will work on cleaning it up now

And sorting by clicking on column headers sounds like a fabulous idea.

@bmwalters
Copy link
Contributor

bmwalters commented Feb 15, 2017

@DirkyJerky @Kefta
bmwalters@d8b7007

I implemented clicking on scoreboard headings to sort. It supports swapping the sort direction by clicking a heading multiple times. It's just missing sorting by name.

One quirk is that it sorts within ScoreGroups independently of each other, but it seems fine.

@DirkyJerky
Copy link
Contributor Author

Great job @bmwalters :D
We could probably make a few fake column labels alongside the other ones to set the name or role sorting options;
Maybe make the text of the labels could change color a bit if it is selected too?
I'll try it tomorrow.

It may even be useful to the end user; probably not
@robotboy655 robotboy655 added the TTT The pull request is for TTT and will be handled by svdm. label Feb 15, 2017
@@ -112,6 +112,23 @@ function PANEL:Init()

self.ply_groups = {}

concommand.Add( "ttt_scoreboard_setsort", function( _, _, args )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i honestly don't think we need this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A ConVar to store how the sorting should be in the scoreboard would be useful, wouldn't it?

return plya:GetRole() > plyb:GetRole()
elseif self.sort_mode == "karma" then
return plya:GetBaseKarma() < plyb:GetBaseKarma()
else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a hook, so you can also sort custom columnes too?

@DirkyJerky
Copy link
Contributor Author

Alright I added two more buttons to click to sort on; and made the active sorting option get highlighted.

@DirkyJerky
Copy link
Contributor Author

DirkyJerky commented Feb 15, 2017

Every option is working smoothly it seems.

http://imgur.com/a/HJQMj

@DirkyJerky
Copy link
Contributor Author

In my personal opinion; It would be a much better option to store the current sort option as a ConVar (with ARCHIVE flag set), because then it will be persistent across sessions.

@bmwalters
Copy link
Contributor

bmwalters commented Feb 16, 2017

@DirkyJerky
The extra column background created by the Name and Role headings and the headings themselves don't look very good IMO. I think a good way to sort by name may be clicking on the "Terrorists (10)" heading area of whatever the topmost score group is. We might be able to just forego sorting by role if there isn't a good way to fit it into the design as the row highlighting makes it easy to view roles even without grouping. I'd be interested in the input of others here.

About the ConVar, I don't think the current sort option is something that needs to persist. It's trivial to interact with the headings to change the sorting back when wanted, and it's sort of needless complexity.

Lastly, maybe the green from the "Terrorists (10)" heading background could be re-used for the text color.

Nice job getting some stuff made; it's good to have working prototypes of these features.

@DirkyJerky
Copy link
Contributor Author

Done.
Thanks for the review!

@DirkyJerky
Copy link
Contributor Author

DirkyJerky commented Mar 10, 2017

For the new translation, I was going to scour the internet to see if I could possibly find some existing locale files for the single translation, but I quick checked Google Translate (clichè I know) and through their "community translate" program they seem to have a whole bunch of "verified" translations, one of which is the one I need. Example: https://translate.google.com/#en/pt/Sort%20By%3A

Could we use those?

Scratch that I found differing translations from different sources, so I bet an actual translator would know what works best.

@Kefta
Copy link
Contributor

Kefta commented Mar 10, 2017

Don't put in empty translations; let it fall back to English

@Kefta
Copy link
Contributor

Kefta commented Mar 10, 2017

No, I meant delete the translation from the other files. The code will automatically make it fall back to english.

@markusmarkusz
Copy link
Contributor

German Translation:
Sortiere nach:

@Kefta
Copy link
Contributor

Kefta commented Mar 10, 2017

Spanish is "Ordene por:"

@Kefta
Copy link
Contributor

Kefta commented Apr 17, 2017

Can you squash?

Copy link
Collaborator

@svdm svdm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finally got around to testing this, and I did not get very far.

local comp = 0 -- Lua doesnt have an Ordering enumeration, I think?

local sort_mode = GetConVar("ttt_scoreboard_sorting"):GetString()
local sort_func = sboard_panel.sort_table[sort_mode]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This use of sboard_panel breaks things. UpdateSortCache is called while initializing the scoreboard. At that point, sboard_panel is nil (because the panel is still being created).

As a result, if 2+ players exist when you first open the scoreboard, then this sboard_panel.sort_table access will of course break and throw your face full of errors.

Note that simply not sorting if sboard_panel == nil probably will not work, because it will just leave the sort cache in an unsorted state until something triggers an update.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh I am bad I should have investigated this more earlier.

I had uncorrectly assumed that because existing code in sb_row.lua and sb_team.lua used that variable without any nil checks, that it was something out of the scope of this PR.

Which I see now was because it was used in instance methods

@robotboy655
Copy link
Collaborator

@Kefta, PRs can now be automatically Squashed when merging

@Kefta
Copy link
Contributor

Kefta commented Apr 17, 2017

Ah, didn't know

@DirkyJerky
Copy link
Contributor Author

DirkyJerky commented Apr 18, 2017

I believe the best but messy option is as follows:

  • Replace sboard_panel with self:GetParent():GetParent():GetParent (nesting dolls are fun)

Goal is the top TTTScoreboard panel, which defines its self.sort_table in its INIT() [----]

Child #1 is TTTPlayerFrame [----]

Child #2 is just a Panel used as a canvas, returned by "TTTPlayerFrame"::GetCanvas() [----]
[----]

(Target) Child #3 is one of the TTTScoreGroups, each of which has the previous Panel as its parent [----]

Everything seems to be working with the fix.

Sorry for disappointing you @svdm ;-;

@svdm
Copy link
Collaborator

svdm commented Apr 18, 2017

Honestly it's cleaner to just move the sort_table stuff into a global sboard_sort. It's basically constant anyway. Then you can use that sboard_sort wherever you need it in the scoreboard panels without the nesting mess.

@DirkyJerky
Copy link
Contributor Author

DirkyJerky commented Apr 18, 2017

Will test at home this afternoon.

Seems to still be working as intended.

@svdm svdm merged commit a71f363 into Facepunch:master Apr 19, 2017
@MinIsMin
Copy link
Contributor

MinIsMin commented Jul 27, 2017

The "Sort by" string is clipping into "Name" in some languages (tested with German and Spanish) and doesn't look well.
German Scoreboard Image

Maybe GetPos + space for next position?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
TTT The pull request is for TTT and will be handled by svdm.
Projects
None yet
10 participants