Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3fd07bc
New ui branch
VeryEvilHumna Oct 29, 2023
8d33c6d
Color codes in Player settings
VeryEvilHumna Oct 29, 2023
d01f969
Experimental UI v0: templates usage in the options
VeryEvilHumna Oct 30, 2023
75987ab
Merge branch 'TeamForbiddenLLC:master' into new-ui
VeryEvilHumna Oct 31, 2023
1ba4f06
Experemental UI v0.1: troubleshooting tab in options
VeryEvilHumna Oct 31, 2023
e15b49d
Experimental UI v0.1.1: Better UX in the header nav
VeryEvilHumna Oct 31, 2023
37fd106
Merge branch 'TeamForbiddenLLC:master' into new-ui
VeryEvilHumna Mar 29, 2026
da3b893
Merge remote-tracking branch 'upstream_pork/master'
VeryEvilHumna Mar 29, 2026
0e90fbc
fix: restore files omitted in merge
VeryEvilHumna Mar 29, 2026
bd05352
feat+refactor
VeryEvilHumna Mar 29, 2026
be6d8ae
feat: make librocket debugger work
VeryEvilHumna Mar 29, 2026
adbe7ce
fix: dp -> px for librocket debugger
VeryEvilHumna Mar 29, 2026
c6a6b22
feat: add reload warfork ui button to librocket debugger
VeryEvilHumna Mar 30, 2026
71f9e41
fix: make librocket's debugger window text bigger
VeryEvilHumna Mar 30, 2026
1528483
wip: search bars everywhere possible
VeryEvilHumna Mar 30, 2026
1bc345a
feat: poor man's hot reload
VeryEvilHumna Mar 30, 2026
e027073
/ui/porkui -> /ui/testui for assets
VeryEvilHumna Mar 30, 2026
466ac5e
feat: replace www icon from `home` to `prime:globe`
VeryEvilHumna Mar 30, 2026
e000c69
feat: add github icon to footer + standardize all icons to being roun…
VeryEvilHumna Mar 30, 2026
513d905
fix: background for main menu not displaying in the testui.
VeryEvilHumna Mar 30, 2026
52b5296
feat: add static noise to the main menu
VeryEvilHumna Mar 31, 2026
0496a4c
refactor+feat: refactor out the sidebar in all `game_*` pages to it's…
VeryEvilHumna Mar 31, 2026
1281c54
fix: increase line height in the connect by ip modal to make it accou…
VeryEvilHumna Mar 31, 2026
3c8e8d7
feat: allow copying and pasting into every librocket input field
VeryEvilHumna Mar 31, 2026
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
60 changes: 60 additions & 0 deletions assets/data0_21pure/scripts/ui_testui.shader
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
ui/testui/gfx/background
{
nopicmip
nomipmaps
nocompress
nofiltering
cull none

{
map ui/testui/gfx/back2.png
blendFunc blend
alphaGen const .1
}

{
map textures/billboard/scanlinenoise.png
blendFunc blend
tcMod scale 2 2
tcMod scroll 0 0.02
alphaGen const 0.05
}

{
map textures/billboard/scanlinenoise.png
blendFunc blend
tcMod scale 2 2
tcMod transform 1 1 0 0 0.32 0.32
tcMod scroll 0 0.05
alphaGen const 0.05
}
}

ui/testui/gfx/background2
{
nopicmip
nomipmaps
nocompress
cull none

{
map ui/testui/gfx/bandes2.png
blendFunc blend
alphagen wave sin 0.05 0.1 0 0.05
tcmod scroll 0 -.08
}
}

ui/testui/gfx/loader_simple
{
noPicmip
noMipmaps
nocompress
cull none

{
clampmap ui/testui/gfx/loader_simple.png
blendfunc blend
tcmod rotate 500
}
}
21 changes: 20 additions & 1 deletion assets/data0_21pure/ui/porkui/options_player.rml
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,21 @@
break;
}
}

void newUiModal(void)
{
window.modal('modal_basic.rml?text=Warning%3A%20Experemental%20UI%20is%20still%20under%20development%20and%20may%20contain%20bugs%20or%20incomplete%20features.%20You%20will%20have%20an%20option%20to%20switch%20back%20to%20legacy%20(this)%20version.%20Please%20use%20it%20at%20your%20own%20risk%20and%20report%20any%20issues%20you%20encounter%20on%20our%20GitHub%20or%20in%20Discord.%20Thank%20you%20for%20your%20understanding%20and%20support&ypos=0.25');
if(window.getModalValue() == 0)
{
switchToNewUi();
}
}


void switchToNewUi(void)
{
game.execAppend( "ui_basepath ui/testui; ui_reload\n" );
}


</script>
Expand Down Expand Up @@ -493,7 +508,11 @@
<option value="12">Light Blue</option>
</select>
<br/>

<br/>
<br/>

<button onclick="newUiModal();">Switch to new experemental UI</button>

</optionsform>
</panel>

Expand Down
162 changes: 162 additions & 0 deletions assets/data0_21pure/ui/testui/as/animations.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/*
Copyright (C) 2012 Jannik Kolodziej ("drahtmaul")

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

*/

funcdef void callback();

const int EASE_NONE = 0;
const int EASE_IN = 1;
const int EASE_OUT = 2;
const int EASE_INOUT = 3;

Vec3 ANIM_LEFT( -120, 0, 0 );
Vec3 ANIM_BOTTOM( 0, 100, 0 );
Vec3 ANIM_RIGHT( 100, 0, 0 );
Vec3 ANIM_TOP( 0, -100, 0 );
Vec3 ANIM_ORIGIN( 0, 0, 0 );

const int ANIMATION_DURATION_FAST = 150; // how long will animations last?

const int ANIMATION_TICK = 10;

// This class will move your element from a certain point to another point. cVec3s need to be percantage values!
// Be aware that the elements position-property will be set to 'relative'!
// Will call the callback as soon as it is done with animation.
class MoveAnimation
{
int animTime;
int animStartTime;
int animLastTime;
int animMoveTime;
Vec3 animStart;
Vec3 animDest;
Element @animElement;
int animEase;
bool ceased;

callback @animDoneCallback;

MoveAnimation( Element @elem, int time, Vec3 start, Vec3 dest, int ease, callback @animDoneCallback = null )
{
@this.animElement = @elem;
this.animTime = time;
this.animStart = start;
this.animDest = dest;
this.animEase = ease;
this.ceased = false;
@this.animDoneCallback = @animDoneCallback;
if( time <= 0 ) {
animate();
}
else {
this.startAnimation();
}
}

~MoveAnimation( )
{
@this.animDoneCallback = null;
@this.animElement = null;
}

private void startAnimation()
{
if( @animElement == null || animTime <= 0 )
return;
animMoveTime = 0;
animStartTime = animLastTime = window.time;
animElement.css( 'position', 'relative' )
.css( 'left', animStart.x + "%" )
.css( 'top', animStart.y + "%" );
window.setInterval( __MoveAnimationCallback, ANIMATION_TICK, any(@this) );
}

bool animate() // do not call this one, it's just for the scheduler
{
if( @this.animElement == null )
return false; // something went wrong

if( this.ceased )
{
if( @this.animDoneCallback is null ) // check whether we need to inform someone that we are done
return false; // doesn't look like it
else
this.animDoneCallback();
return false;
}

float frac;

if( this.animTime > 0 )
{
int moveTime = window.time - this.animLastTime;
if( moveTime > ANIMATION_TICK )
moveTime = ANIMATION_TICK;

animMoveTime += moveTime;
frac = float(animMoveTime) / this.animTime;
frac = applyEase( frac, this.animEase );
if( frac > 1 )
frac = 1;
}
else
{
frac = 1;
}

this.animLastTime = window.time;
this.setElementPosition( 'left', animStart.x, animDest.x, frac );
this.setElementPosition( 'top', animStart.y, animDest.y, frac );

if( frac == 1 ) // we are done
this.ceased = true;
return true; // continue to call this function
}

private void setElementPosition( String prop, float start, float dest, float frac )
{
float tmp = dest - start;
tmp = start + tmp * frac;
this.animElement.css( prop, int( tmp ) + "%" );
}
}

float applyEase( float x, int ease ) // x needs to be between 0 and 1
{
if( ease == EASE_NONE ) // FIXME: switch()?
return x;
else if( ease == EASE_IN )
return x*x*x*x; // f(x)=x^4
else if( ease == EASE_OUT )
return pow( x, 0.25 ); // f(x)=x^0.25
else if( ease == EASE_INOUT )
return x * x * ( -2.0f * x + 3.0f ); // f(x)=-2x^3+3x^2 -- That math was fucking hard if you're not used to to that kind of stuff...
return 0;
}

bool __MoveAnimationCallback( any & obj ) // this one will serve as a relay, handing scheduler-call over to the class
{
MoveAnimation @anim;
obj.retrieve(@anim);

if( @anim == null )
return false; // something went wrong, just disable that scheduler

return anim.animate();
}
83 changes: 83 additions & 0 deletions assets/data0_21pure/ui/testui/as/base.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
Copyright (C) 2012 Chasseur de bots

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

*/

const String S_COLOR_BLACK = "^0";
const String S_COLOR_RED = "^1";
const String S_COLOR_GREEN = "^2";
const String S_COLOR_YELLOW = "^3";
const String S_COLOR_BLUE = "^4";
const String S_COLOR_CYAN = "^5";
const String S_COLOR_MAGENTA = "^6";
const String S_COLOR_WHITE = "^7";
const String S_COLOR_ORANGE = "^8";
const String S_COLOR_GREY = "^9";

/*
* Converts "R G B" decimal representation to #hhhhhh representation
*/
String @RGB2Hex( const String &in rgb )
{
array<String @> @components = StringUtils::Split( rgb, " " );

String hex = "#";

uint count = 0;
uint components_size = components.size();
for( uint i = 0; i < components_size; i++ ) {
String @component = components[i];
if( component.empty() ) {
continue;
}

hex += StringUtils::FormatInt( component.toInt(), '0h', 2 );

count++;
if( count == 3 ) {
// parsed all 3 components
break;
}
}

return hex;
}

/*
* Converts #hhhhhh representation to "R G B" decimal representation
*/
const String @Hex2RGB( const String &in hex )
{
if( hex.length() < 7 || hex.substr( 0, 1 ) != '#' ) {
// wrong format
return '0 0 0';
}

uint r = StringUtils::Strtol( hex.substr( 1, 2 ), 16 ) & 0xff;
uint g = StringUtils::Strtol( hex.substr( 3, 2 ), 16 ) & 0xff;
uint b = StringUtils::Strtol( hex.substr( 5, 2 ), 16 ) & 0xff;

return '' + r + ' ' + g + ' ' + b;
}

void OpenQuitDialog( void )
{
window.modal('modal_basic.rml?text=Are%20you%20sure%20you%20want%20to%20quit%3F&ypos=0.25');
if (window.getModalValue() == 0)
game.execAppend('quit\n');
}
43 changes: 43 additions & 0 deletions assets/data0_21pure/ui/testui/as/callvotes.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
Copyright (C) 2013 Chasseur de bots

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

*/

namespace Callvotes
{
bool playerHasVoted( int playerNum )
{
String votes = ::game.cs( ::CS_ACTIVE_CALLVOTE_VOTES );

if (votes.empty()) {
return false;
}

array<String @>vectors = StringUtils::Split( votes, ' ' );
int vectorid = playerNum / 31;

if( playerNum < 0 || vectorid >= int(vectors.length()) ) {
return false;
}

String hex = '0x' + vectors[vectorid];
int bits = hex.toInt();
bool voted = bits & (1<<(playerNum&31)) != 0;
return voted;
}
}
Loading
Loading