mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-18 15:32:33 +00:00
Continue screen! With aaaaaall the new assets to go with it.
* https://cdn.discordapp.com/attachments/428262628893261828/621129794045870108/srb20077.gif * https://cdn.discordapp.com/attachments/428262628893261828/621129785124585502/srb20078.gif * I will be accepting no further questions at this time.
This commit is contained in:
parent
25e975e781
commit
ed5e8c486c
7 changed files with 238 additions and 37 deletions
246
src/f_finale.c
246
src/f_finale.c
|
@ -2465,6 +2465,11 @@ void F_TitleDemoTicker(void)
|
||||||
// ==========
|
// ==========
|
||||||
// CONTINUE
|
// CONTINUE
|
||||||
// ==========
|
// ==========
|
||||||
|
|
||||||
|
static skin_t *contskins[2];
|
||||||
|
static UINT8 cont_spr2[2][6];
|
||||||
|
static UINT8 *contcolormaps[2];
|
||||||
|
|
||||||
void F_StartContinue(void)
|
void F_StartContinue(void)
|
||||||
{
|
{
|
||||||
I_Assert(!netgame && !multiplayer);
|
I_Assert(!netgame && !multiplayer);
|
||||||
|
@ -2488,7 +2493,44 @@ void F_StartContinue(void)
|
||||||
S_ChangeMusicInternal("_conti", false);
|
S_ChangeMusicInternal("_conti", false);
|
||||||
S_StopSounds();
|
S_StopSounds();
|
||||||
|
|
||||||
timetonext = TICRATE*11;
|
contskins[0] = &skins[players[consoleplayer].skin];
|
||||||
|
cont_spr2[0][0] = P_GetSkinSprite2(contskins[0], SPR2_CNT1, NULL);
|
||||||
|
cont_spr2[0][2] = contskins[0]->contangle & 7;
|
||||||
|
contcolormaps[0] = R_GetTranslationColormap(players[consoleplayer].skin, players[consoleplayer].skincolor, GTC_CACHE);
|
||||||
|
cont_spr2[0][4] = contskins[0]->sprites[cont_spr2[0][0]].numframes;
|
||||||
|
cont_spr2[0][5] = max(1, contskins[0]->contspeed);
|
||||||
|
|
||||||
|
if (botskin)
|
||||||
|
{
|
||||||
|
INT32 secondplaya;
|
||||||
|
|
||||||
|
if (secondarydisplayplayer != consoleplayer)
|
||||||
|
secondplaya = secondarydisplayplayer;
|
||||||
|
else // HACK
|
||||||
|
secondplaya = 1;
|
||||||
|
|
||||||
|
contskins[1] = &skins[players[secondplaya].skin];
|
||||||
|
cont_spr2[1][0] = P_GetSkinSprite2(contskins[1], SPR2_CNT4, NULL);
|
||||||
|
cont_spr2[1][2] = (contskins[1]->contangle >> 3) & 7;
|
||||||
|
contcolormaps[1] = R_GetTranslationColormap(players[secondplaya].skin, players[secondplaya].skincolor, GTC_CACHE);
|
||||||
|
cont_spr2[1][4] = contskins[1]->sprites[cont_spr2[1][0]].numframes;
|
||||||
|
if (cont_spr2[1][0] == SPR2_CNT4)
|
||||||
|
cont_spr2[1][5] = 4; // sorry, this one is hardcoded
|
||||||
|
else
|
||||||
|
cont_spr2[1][5] = max(1, contskins[1]->contspeed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
contskins[1] = NULL;
|
||||||
|
contcolormaps[1] = NULL;
|
||||||
|
cont_spr2[1][0] = cont_spr2[1][2] = cont_spr2[1][4] = cont_spr2[1][5] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cont_spr2[0][1] = cont_spr2[0][3] =\
|
||||||
|
cont_spr2[1][1] = cont_spr2[1][3] = 0;
|
||||||
|
|
||||||
|
timetonext = (11*TICRATE)+11;
|
||||||
|
continuetime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -2497,47 +2539,198 @@ void F_StartContinue(void)
|
||||||
//
|
//
|
||||||
void F_ContinueDrawer(void)
|
void F_ContinueDrawer(void)
|
||||||
{
|
{
|
||||||
patch_t *contsonic;
|
spritedef_t *sprdef;
|
||||||
INT32 i, x = (BASEVIDWIDTH/2) + 4, ncontinues = players[consoleplayer].continues;
|
spriteframe_t *sprframe;
|
||||||
if (ncontinues > 20)
|
patch_t *patch;
|
||||||
ncontinues = 20;
|
INT32 i, x = (BASEVIDWIDTH>>1), ncontinues = players[consoleplayer].continues;
|
||||||
|
char numbuf[9] = "CONTNUM*";
|
||||||
|
tic_t timeleft = (timetonext/TICRATE);
|
||||||
|
INT32 offsx = 0, offsy = 0, lift[2] = {0, 0};
|
||||||
|
|
||||||
if (imcontinuing)
|
if (continuetime >= 3*TICRATE)
|
||||||
contsonic = W_CachePatchName("CONT2", PU_CACHE);
|
{
|
||||||
else
|
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0);
|
||||||
contsonic = W_CachePatchName("CONT1", PU_CACHE);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||||
V_DrawCenteredString(BASEVIDWIDTH/2, 100, 0, "CONTINUE?");
|
|
||||||
|
|
||||||
// Draw a Sonic!
|
if (timetonext >= (11*TICRATE)+10)
|
||||||
V_DrawScaledPatch((BASEVIDWIDTH - SHORT(contsonic->width))/2, 32, 0, contsonic);
|
return;
|
||||||
|
|
||||||
// Draw the continue markers! Show continues minus one.
|
V_DrawLevelTitle(x - (V_LevelNameWidth("CONTINUE")>>1), 16, 0, "CONTINUE");
|
||||||
x -= ncontinues * 6;
|
|
||||||
|
// Two stars...
|
||||||
|
patch = W_CachePatchName("CONTSTAR", PU_CACHE);
|
||||||
|
V_DrawScaledPatch(x-32, 160, 0, patch);
|
||||||
|
V_DrawScaledPatch(x+32, 160, 0, patch);
|
||||||
|
|
||||||
|
// Time left!
|
||||||
|
if (timeleft > 9)
|
||||||
|
{
|
||||||
|
numbuf[7] = '1';
|
||||||
|
V_DrawScaledPatch(x - 10, 160, 0, W_CachePatchName(numbuf, PU_CACHE));
|
||||||
|
numbuf[7] = '0';
|
||||||
|
V_DrawScaledPatch(x + 10, 160, 0, W_CachePatchName(numbuf, PU_CACHE));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
numbuf[7] = '0'+timeleft;
|
||||||
|
V_DrawScaledPatch(x, 160, 0, W_CachePatchName(numbuf, PU_CACHE));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the continue markers! Show continues.
|
||||||
|
if (ncontinues > 10)
|
||||||
|
{
|
||||||
|
if (!(continuetime & 1) || continuetime > 17)
|
||||||
|
V_DrawContinueIcon(x, 68, 0, players[consoleplayer].skin, players[consoleplayer].skincolor);
|
||||||
|
V_DrawScaledPatch(x+12, 68-2, 0, stlivex);
|
||||||
|
V_DrawRightAlignedString(x+36, 69-5, 0,
|
||||||
|
va("%d",(imcontinuing ? ncontinues-1 : ncontinues)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
x += (ncontinues/2) * 30;
|
||||||
|
if (!(ncontinues & 1))
|
||||||
|
x -= 15;
|
||||||
for (i = 0; i < ncontinues; ++i)
|
for (i = 0; i < ncontinues; ++i)
|
||||||
V_DrawContinueIcon(x + (i*12), 140, 0, players[consoleplayer].skin, players[consoleplayer].skincolor);
|
{
|
||||||
|
if (i == (ncontinues/2) && ((continuetime & 1) || continuetime > 17))
|
||||||
|
continue;
|
||||||
|
V_DrawContinueIcon(x - (i*30), 68, 0, players[consoleplayer].skin, players[consoleplayer].skincolor);
|
||||||
|
}
|
||||||
|
x = BASEVIDWIDTH>>1;
|
||||||
|
}
|
||||||
|
|
||||||
V_DrawCenteredString(BASEVIDWIDTH/2, 168, 0, va("\x82*\x80" " %02d " "\x82*\x80", timetonext/TICRATE));
|
// Spotlight
|
||||||
|
V_DrawScaledPatch(x, 140, 0, W_CachePatchName("CONTSPOT", PU_CACHE));
|
||||||
|
|
||||||
|
// warping laser
|
||||||
|
if (continuetime)
|
||||||
|
{
|
||||||
|
INT32 w = min(continuetime, 28), brightness = (continuetime>>1) & 7;
|
||||||
|
if (brightness > 3)
|
||||||
|
brightness = 8-brightness;
|
||||||
|
V_DrawFadeFill(x-w, 0, w<<1, 140, 0, 0, (3+brightness));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contskins[1])
|
||||||
|
{
|
||||||
|
if (continuetime > 15)
|
||||||
|
{
|
||||||
|
angle_t work = FixedAngle((10*(continuetime-15))<<FRACBITS)>>ANGLETOFINESHIFT;
|
||||||
|
offsy = FINESINE(work)<<1;
|
||||||
|
offsx = (27*FINECOSINE(work))>>1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
offsx = 27<<(FRACBITS-1);
|
||||||
|
lift[1] = continuetime-10;
|
||||||
|
if (lift[1] < 0)
|
||||||
|
lift[1] = 0;
|
||||||
|
else if (lift[1] > TICRATE+5)
|
||||||
|
lift[1] = TICRATE+5;
|
||||||
|
}
|
||||||
|
|
||||||
|
lift[0] = continuetime-5;
|
||||||
|
if (lift[0] < 0)
|
||||||
|
lift[0] = 0;
|
||||||
|
else if (lift[0] > TICRATE+5)
|
||||||
|
lift[0] = TICRATE+5;
|
||||||
|
|
||||||
|
#define drawchar(dx, dy, n) {\
|
||||||
|
sprdef = &contskins[n]->sprites[cont_spr2[n][0]];\
|
||||||
|
sprframe = &sprdef->spriteframes[cont_spr2[n][1]];\
|
||||||
|
patch = W_CachePatchNum(sprframe->lumppat[cont_spr2[n][2]], PU_CACHE);\
|
||||||
|
V_DrawFixedPatch((dx), (dy), FRACUNIT, (sprframe->flip & (1<<cont_spr2[n][2])) ? V_FLIP : 0, patch, contcolormaps[n]);\
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offsy < 0)
|
||||||
|
drawchar((BASEVIDWIDTH<<(FRACBITS-1))-offsx, ((140-lift[0])<<FRACBITS)-offsy, 0);
|
||||||
|
if (contskins[1])
|
||||||
|
drawchar((BASEVIDWIDTH<<(FRACBITS-1))+offsx, ((140-lift[1])<<FRACBITS)+offsy, 1);
|
||||||
|
if (offsy >= 0)
|
||||||
|
drawchar((BASEVIDWIDTH<<(FRACBITS-1))-offsx, ((140-lift[0])<<FRACBITS)-offsy, 0);
|
||||||
|
|
||||||
|
#undef drawchar
|
||||||
|
|
||||||
|
if (timetonext > (11*TICRATE))
|
||||||
|
V_DrawFadeScreen(31, timetonext-(11*TICRATE));
|
||||||
|
if (continuetime > ((3*TICRATE) - 10))
|
||||||
|
V_DrawFadeScreen(0, (continuetime - ((3*TICRATE) - 10)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void F_ContinueTicker(void)
|
void F_ContinueTicker(void)
|
||||||
{
|
{
|
||||||
if (!imcontinuing)
|
if (!imcontinuing)
|
||||||
{
|
{
|
||||||
// note the setup to prevent 2x reloading
|
if (timetonext > 0)
|
||||||
if (timetonext >= 0)
|
{
|
||||||
timetonext--;
|
if (!(--timetonext))
|
||||||
if (timetonext == 0)
|
{
|
||||||
Command_ExitGame_f();
|
Command_ExitGame_f();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// note the setup to prevent 2x reloading
|
if (++continuetime == 3*TICRATE)
|
||||||
if (continuetime >= 0)
|
{
|
||||||
continuetime--;
|
|
||||||
if (continuetime == 0)
|
|
||||||
G_Continue();
|
G_Continue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (continuetime > 5 && ((continuetime & 1) || continuetime > TICRATE) && (++cont_spr2[0][2]) >= 8)
|
||||||
|
cont_spr2[0][2] = 0;
|
||||||
|
|
||||||
|
if (continuetime > 10 && (!(continuetime & 1) || continuetime > TICRATE+5) && (++cont_spr2[1][2]) >= 8)
|
||||||
|
cont_spr2[1][2] = 0;
|
||||||
|
|
||||||
|
if (continuetime == (3*TICRATE)-10)
|
||||||
|
S_StartSound(NULL, sfx_cdfm56); // or 31
|
||||||
|
else if (continuetime == 5)
|
||||||
|
{
|
||||||
|
cont_spr2[0][0] = P_GetSkinSprite2(contskins[0], SPR2_CNT2, NULL);
|
||||||
|
cont_spr2[0][4] = contskins[0]->sprites[cont_spr2[0][0]].numframes;
|
||||||
|
cont_spr2[0][1] = cont_spr2[0][3] = 0;
|
||||||
|
cont_spr2[0][5] = 2;
|
||||||
|
}
|
||||||
|
else if (continuetime == TICRATE)
|
||||||
|
{
|
||||||
|
cont_spr2[0][0] = P_GetSkinSprite2(contskins[0], SPR2_CNT3, NULL);
|
||||||
|
cont_spr2[0][4] = contskins[0]->sprites[cont_spr2[0][0]].numframes;
|
||||||
|
cont_spr2[0][1] = cont_spr2[0][3] = 0;
|
||||||
|
}
|
||||||
|
else if (contskins[1])
|
||||||
|
{
|
||||||
|
if (continuetime == 10)
|
||||||
|
{
|
||||||
|
cont_spr2[1][0] = P_GetSkinSprite2(contskins[1], SPR2_CNT2, NULL);
|
||||||
|
cont_spr2[1][4] = contskins[1]->sprites[cont_spr2[1][0]].numframes;
|
||||||
|
cont_spr2[1][1] = cont_spr2[1][3] = 0;
|
||||||
|
cont_spr2[1][5] = 2;
|
||||||
|
}
|
||||||
|
else if (continuetime == TICRATE+5)
|
||||||
|
{
|
||||||
|
cont_spr2[1][0] = P_GetSkinSprite2(contskins[1], SPR2_CNT3, NULL);
|
||||||
|
cont_spr2[1][4] = contskins[1]->sprites[cont_spr2[1][0]].numframes;
|
||||||
|
cont_spr2[1][1] = cont_spr2[1][3] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((++cont_spr2[0][3]) >= cont_spr2[0][5])
|
||||||
|
{
|
||||||
|
cont_spr2[0][3] = 0;
|
||||||
|
if (++cont_spr2[0][1] >= cont_spr2[0][4])
|
||||||
|
cont_spr2[0][1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contskins[1] && (++cont_spr2[1][3]) >= cont_spr2[1][5])
|
||||||
|
{
|
||||||
|
cont_spr2[1][3] = 0;
|
||||||
|
if (++cont_spr2[1][1] >= cont_spr2[1][4])
|
||||||
|
cont_spr2[1][1] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2568,8 +2761,9 @@ boolean F_ContinueResponder(event_t *event)
|
||||||
|
|
||||||
keypressed = true;
|
keypressed = true;
|
||||||
imcontinuing = true;
|
imcontinuing = true;
|
||||||
continuetime = TICRATE;
|
S_StartSound(NULL, sfx_kc6b);
|
||||||
S_StartSound(NULL, sfx_itemup);
|
I_FadeSong(0, MUSICRATE, &S_StopMusic);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2603,6 +2603,8 @@ static void Sk_SetDefaultValue(skin_t *skin)
|
||||||
skin->followitem = 0;
|
skin->followitem = 0;
|
||||||
|
|
||||||
skin->highresscale = FRACUNIT;
|
skin->highresscale = FRACUNIT;
|
||||||
|
skin->contspeed = 17;
|
||||||
|
skin->contangle = 0;
|
||||||
|
|
||||||
skin->availability = 0;
|
skin->availability = 0;
|
||||||
|
|
||||||
|
@ -2907,6 +2909,8 @@ static boolean R_ProcessPatchableFields(skin_t *skin, char *stoken, char *value)
|
||||||
GETINT(thrustfactor)
|
GETINT(thrustfactor)
|
||||||
GETINT(accelstart)
|
GETINT(accelstart)
|
||||||
GETINT(acceleration)
|
GETINT(acceleration)
|
||||||
|
GETINT(contspeed)
|
||||||
|
GETINT(contangle)
|
||||||
#undef GETINT
|
#undef GETINT
|
||||||
|
|
||||||
#define GETSKINCOLOR(field) else if (!stricmp(stoken, #field)) skin->field = R_GetColorByName(value);
|
#define GETSKINCOLOR(field) else if (!stricmp(stoken, #field)) skin->field = R_GetColorByName(value);
|
||||||
|
|
|
@ -122,6 +122,8 @@ typedef struct
|
||||||
UINT8 prefoppositecolor; // if 0 use tables instead
|
UINT8 prefoppositecolor; // if 0 use tables instead
|
||||||
|
|
||||||
fixed_t highresscale; // scale of highres, default is 0.5
|
fixed_t highresscale; // scale of highres, default is 0.5
|
||||||
|
UINT8 contspeed; // continue screen animation speed
|
||||||
|
UINT8 contangle; // initial angle on continue screen
|
||||||
|
|
||||||
// specific sounds per skin
|
// specific sounds per skin
|
||||||
sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table
|
sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table
|
||||||
|
|
|
@ -64,12 +64,12 @@ patch_t *sbotime; // Time logo
|
||||||
patch_t *sbocolon; // Colon for time
|
patch_t *sbocolon; // Colon for time
|
||||||
patch_t *sboperiod; // Period for time centiseconds
|
patch_t *sboperiod; // Period for time centiseconds
|
||||||
patch_t *livesback; // Lives icon background
|
patch_t *livesback; // Lives icon background
|
||||||
|
patch_t *stlivex;
|
||||||
static patch_t *nrec_timer; // Timer for NiGHTS records
|
static patch_t *nrec_timer; // Timer for NiGHTS records
|
||||||
static patch_t *sborings;
|
static patch_t *sborings;
|
||||||
static patch_t *slidgame;
|
static patch_t *slidgame;
|
||||||
static patch_t *slidtime;
|
static patch_t *slidtime;
|
||||||
static patch_t *slidover;
|
static patch_t *slidover;
|
||||||
static patch_t *stlivex;
|
|
||||||
static patch_t *sboredrings;
|
static patch_t *sboredrings;
|
||||||
static patch_t *sboredtime;
|
static patch_t *sboredtime;
|
||||||
static patch_t *getall; // Special Stage HUD
|
static patch_t *getall; // Special Stage HUD
|
||||||
|
|
|
@ -70,6 +70,7 @@ extern patch_t *sboperiod;
|
||||||
extern patch_t *faceprefix[MAXSKINS]; // face status patches
|
extern patch_t *faceprefix[MAXSKINS]; // face status patches
|
||||||
extern patch_t *superprefix[MAXSKINS]; // super face status patches
|
extern patch_t *superprefix[MAXSKINS]; // super face status patches
|
||||||
extern patch_t *livesback;
|
extern patch_t *livesback;
|
||||||
|
extern patch_t *stlivex;
|
||||||
extern patch_t *ngradeletters[7];
|
extern patch_t *ngradeletters[7];
|
||||||
|
|
||||||
/** HUD location information (don't move this comment)
|
/** HUD location information (don't move this comment)
|
||||||
|
|
|
@ -1064,17 +1064,17 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
|
||||||
//
|
//
|
||||||
void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor)
|
void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor)
|
||||||
{
|
{
|
||||||
if (skinnum < 0 || skinnum >= numskins || (skins[skinnum].flags & SF_HIRES))
|
if (skinnum >= 0 && skinnum < numskins && skins[skinnum].sprites[SPR2_XTRA].numframes >= 4)
|
||||||
V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE));
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
spriteframe_t *sprframe = &skins[skinnum].sprites[SPR2_WAIT].spriteframes[0];
|
spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA];
|
||||||
patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
|
spriteframe_t *sprframe = &sprdef->spriteframes[3];
|
||||||
|
patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL);
|
||||||
const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE);
|
const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE);
|
||||||
|
|
||||||
// No variant for translucency
|
V_DrawMappedPatch(x, y, flags, patch, colormap);
|
||||||
V_DrawTinyMappedPatch(x, y, flags, patch, colormap);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -429,7 +429,7 @@ void Y_IntermissionDrawer(void)
|
||||||
{
|
{
|
||||||
if ((data.spec.continues & 0x80) && i == continues-1 && (endtic < 0 || intertic%20 < 10))
|
if ((data.spec.continues & 0x80) && i == continues-1 && (endtic < 0 || intertic%20 < 10))
|
||||||
break;
|
break;
|
||||||
V_DrawContinueIcon(246 + xoffset5 - (i*12), 162+yoffset, 0, *data.spec.playerchar, *data.spec.playercolor);
|
V_DrawContinueIcon(246 + xoffset5 - (i*20), 162+yoffset, 0, *data.spec.playerchar, *data.spec.playercolor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue