mirror of
https://github.com/nzp-team/quakespasm.git
synced 2024-11-21 11:21:07 +00:00
NX/VITA: Fix networking progs with multiple clients
This commit is contained in:
parent
01993b3e0d
commit
2108d718d4
16 changed files with 167 additions and 44 deletions
|
@ -8,7 +8,7 @@
|
|||
DO_USERDIRS=0
|
||||
|
||||
### Enable/Disable SDL2
|
||||
USE_SDL2=0
|
||||
USE_SDL2=1
|
||||
|
||||
### Enable/Disable codecs for streaming music support
|
||||
USE_CODEC_WAVE=1
|
||||
|
@ -222,7 +222,9 @@ SYSOBJ_RES :=
|
|||
GLOBJS = \
|
||||
gl_refrag.o \
|
||||
gl_rlight.o \
|
||||
gl_rpart.o \
|
||||
gl_rmain.o \
|
||||
gl_hud.o \
|
||||
gl_fog.o \
|
||||
gl_rmisc.o \
|
||||
r_part.o \
|
||||
|
@ -240,8 +242,8 @@ GLOBJS = \
|
|||
r_brush.o \
|
||||
gl_model.o
|
||||
|
||||
OBJS := strlcat.o \
|
||||
strlcpy.o \
|
||||
OBJS := bsd_strlcat.o \
|
||||
bsd_strlcpy.o \
|
||||
$(GLOBJS) \
|
||||
$(SYSOBJ_INPUT) \
|
||||
$(COMOBJ_SND) \
|
||||
|
@ -270,6 +272,7 @@ OBJS := strlcat.o \
|
|||
cfgfile.o \
|
||||
host.o \
|
||||
host_cmd.o \
|
||||
matrixlib.o \
|
||||
mathlib.o \
|
||||
pr_cmds.o \
|
||||
pr_edict.o \
|
||||
|
|
|
@ -28,7 +28,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#ifdef VITA
|
||||
#include <vitasdk.h>
|
||||
#else
|
||||
#endif
|
||||
#ifdef __SWITCH__
|
||||
#include <switch.h>
|
||||
#include <switch/runtime/pad.h>
|
||||
#endif
|
||||
|
@ -44,7 +45,8 @@ cvar_t gyrosensy = {"gyrosensy", "1.0", CVAR_ARCHIVE};
|
|||
|
||||
#ifdef VITA
|
||||
SceMotionState motionstate;
|
||||
#else
|
||||
#endif
|
||||
#ifdef __SWITCH__
|
||||
PadState gyropad;
|
||||
HidSixAxisSensorHandle handles[4];
|
||||
#endif
|
||||
|
@ -329,7 +331,8 @@ void CL_AdjustAngles (void)
|
|||
// and the PITCH or the vertical y axis is controlled by angularVelocity.x but its what seems to work
|
||||
float x_gyro_cam = motionstate.angularVelocity.y * gyrosensx.value;
|
||||
float y_gyro_cam = motionstate.angularVelocity.x * gyrosensy.value;
|
||||
#else
|
||||
#endif
|
||||
#ifdef __SWITCH__
|
||||
padUpdate(&gyropad);
|
||||
// Read from the correct sixaxis handle depending on the current input style
|
||||
HidSixAxisSensorState sixaxis = {0};
|
||||
|
@ -351,6 +354,13 @@ void CL_AdjustAngles (void)
|
|||
float y_gyro_cam = sixaxis.angular_velocity.x * (gyrosensy.value*4);
|
||||
#endif // VITA
|
||||
|
||||
#ifndef __SWITCH__
|
||||
#ifndef VITA
|
||||
float x_gyro_cam = 0;
|
||||
float y_gyro_cam = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
cl.viewangles[YAW] += x_gyro_cam;
|
||||
|
||||
V_StopPitchDrift();
|
||||
|
@ -387,7 +397,7 @@ void CL_BaseMove (usercmd_t *cmd)
|
|||
Q_memset (cmd, 0, sizeof(*cmd));
|
||||
|
||||
// cypress - we handle movespeed in QC now.
|
||||
cl_backspeed = cl_forwardspeed = cl_sidespeed = sv_player->v.maxspeed*0.71;
|
||||
cl_backspeed = cl_forwardspeed = cl_sidespeed = cl.maxspeed*0.71;
|
||||
|
||||
// Throttle side and back speeds
|
||||
cl_sidespeed *= 0.8;
|
||||
|
@ -399,14 +409,14 @@ void CL_BaseMove (usercmd_t *cmd)
|
|||
|
||||
|
||||
// Limit max
|
||||
if (cl_backspeed > sv_player->v.maxspeed) {
|
||||
cl_backspeed = sv_player->v.maxspeed;
|
||||
if (cl_backspeed > cl.maxspeed) {
|
||||
cl_backspeed = cl.maxspeed;
|
||||
}
|
||||
if (cl_sidespeed > sv_player->v.maxspeed) {
|
||||
cl_sidespeed = sv_player->v.maxspeed;
|
||||
if (cl_sidespeed > cl.maxspeed) {
|
||||
cl_sidespeed = cl.maxspeed;
|
||||
}
|
||||
if (cl_forwardspeed > sv_player->v.maxspeed) {
|
||||
cl_forwardspeed = sv_player->v.maxspeed;
|
||||
if (cl_forwardspeed > cl.maxspeed) {
|
||||
cl_forwardspeed = cl.maxspeed;
|
||||
}
|
||||
|
||||
|
||||
|
@ -761,7 +771,8 @@ void CL_InitInput (void)
|
|||
#ifdef VITA
|
||||
sceMotionReset();
|
||||
sceMotionStartSampling();
|
||||
#else
|
||||
#endif
|
||||
#ifdef __SWITCH__
|
||||
padConfigureInput(1, HidNpadStyleSet_NpadStandard);
|
||||
padInitializeDefault(&gyropad);
|
||||
|
||||
|
|
|
@ -544,9 +544,9 @@ void CL_RelinkEntities (void)
|
|||
smokeorg[2] += cl.viewheight;
|
||||
VectorCopy(smokeorg,start);
|
||||
|
||||
right_offset = sv_player->v.Flash_Offset[0];
|
||||
up_offset = sv_player->v.Flash_Offset[1];
|
||||
forward_offset = sv_player->v.Flash_Offset[2];
|
||||
right_offset = cl.flash_offset[0];
|
||||
up_offset = cl.flash_offset[1];
|
||||
forward_offset = cl.flash_offset[2];
|
||||
|
||||
right_offset = right_offset/1000;
|
||||
up_offset = up_offset/1000;
|
||||
|
|
|
@ -779,6 +779,13 @@ void CL_ParseClientdata (void)
|
|||
}
|
||||
//johnfitz
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
cl.ads_offset[i] = MSG_ReadFloat();
|
||||
for(i = 0; i < 3; i++)
|
||||
cl.flash_offset[i] = MSG_ReadFloat();
|
||||
|
||||
cl.flash_size = MSG_ReadByte();
|
||||
|
||||
if (bits & SU_PERKS)
|
||||
i = MSG_ReadLong ();
|
||||
else
|
||||
|
@ -964,6 +971,40 @@ void CL_ParseClientdata (void)
|
|||
cl.perks = i;
|
||||
}
|
||||
|
||||
if (bits & SU_MAXSPEED)
|
||||
cl.maxspeed = MSG_ReadFloat();
|
||||
else
|
||||
cl.maxspeed = 0;
|
||||
|
||||
if (bits & SU_FACINGENEMY)
|
||||
cl.facingenemy = MSG_ReadByte();
|
||||
else
|
||||
cl.facingenemy = 0;
|
||||
|
||||
if (bits & SU_WEAPONNAME) {
|
||||
size_t len = MSG_ReadByte();
|
||||
|
||||
for(i = 0; i < 32; i++) {
|
||||
cl.weaponname[i] = 0;
|
||||
}
|
||||
|
||||
for(i = 0; i < len; i++) {
|
||||
cl.weaponname[i] = MSG_ReadChar();
|
||||
}
|
||||
}
|
||||
|
||||
if (bits & SU_TOUCHNAME) {
|
||||
size_t len = MSG_ReadByte();
|
||||
|
||||
for(i = 0; i < 32; i++) {
|
||||
cl.touchname[i] = 0;
|
||||
}
|
||||
|
||||
for(i = 0; i < len; i++) {
|
||||
cl.touchname[i] = MSG_ReadChar();
|
||||
}
|
||||
}
|
||||
|
||||
cl.onground = (bits & SU_ONGROUND) != 0;
|
||||
cl.inwater = (bits & SU_INWATER) != 0;
|
||||
|
||||
|
|
|
@ -161,6 +161,8 @@ typedef struct
|
|||
int perks; // Perk icons.
|
||||
int progress_bar; // Perk icons.
|
||||
int items; // inventory bit flags
|
||||
float maxspeed; // Player's maximum allowed speed.
|
||||
int facingenemy; // Returns 1 if the player is facing an enemy
|
||||
float item_gettime[32]; // cl.time of aquiring item, for blinking
|
||||
float faceanimtime; // use anim frame if cl.time < this
|
||||
|
||||
|
@ -181,6 +183,10 @@ typedef struct
|
|||
|
||||
vec3_t punchangle; // temporary offset
|
||||
vec3_t gun_kick;
|
||||
vec3_t ads_offset; // Value to position a weapon for ADS
|
||||
vec3_t flash_offset; // Value to position the muzzleflash for a weapon
|
||||
|
||||
int flash_size; // Size of muzzleflash
|
||||
|
||||
// pitch drifting vars
|
||||
float idealpitch;
|
||||
|
@ -215,6 +221,8 @@ typedef struct
|
|||
struct qmodel_s *model_precache[MAX_MODELS];
|
||||
struct sfx_s *sound_precache[MAX_SOUNDS];
|
||||
|
||||
char weaponname[32]; // name of the currently held weapon
|
||||
char touchname[32]; // name of the weapon/other string we're touching.
|
||||
char mapname[128];
|
||||
char levelname[128]; // for display on solo scoreboard //johnfitz -- was 40.
|
||||
int viewentity; // cl_entitites[cl.viewentity] = player
|
||||
|
|
|
@ -415,6 +415,7 @@ void HUD_Points (void)
|
|||
{
|
||||
int i, k, l;
|
||||
int x, y, f, xplus;
|
||||
float r, g, b;
|
||||
scoreboard_t *s;
|
||||
char str[12];
|
||||
|
||||
|
@ -434,6 +435,14 @@ void HUD_Points (void)
|
|||
if (!s->name[0])
|
||||
continue;
|
||||
|
||||
switch(i) {
|
||||
case 0: r = g = b = 1; break;
|
||||
case 1: r = 0; g = 0.46; b = 0.7; break;
|
||||
case 2: r = 0.92; g = 0.74; b = 0; break;
|
||||
case 3: r = 0; g = 0.90; b = 0.13; break;
|
||||
default: r = g = b = 1; break;
|
||||
}
|
||||
|
||||
// draw background
|
||||
|
||||
// draw number
|
||||
|
@ -467,17 +476,17 @@ void HUD_Points (void)
|
|||
}
|
||||
}
|
||||
#ifdef VITA
|
||||
Draw_StretchPic(12, 407, sb_moneyback, 128, 32);
|
||||
Draw_StretchPic(12, 407 - (35 * i), sb_moneyback, 128, 32);
|
||||
#else
|
||||
Draw_StretchPic(8, 629, sb_moneyback, 86, 21);
|
||||
Draw_StretchPic(8, 629 - (24 * i), sb_moneyback, 86, 21);
|
||||
#endif // VITA
|
||||
|
||||
#ifdef VITA
|
||||
xplus = HUD_itoa (f, str)*16;
|
||||
Draw_ColoredStringScale (((160 - xplus)/2)-5, 413, va("%i", current_points), 1, 1, 1, 1, 2.0f); //2x Scale/White
|
||||
Draw_ColoredStringScale (((160 - xplus)/2)-5, 413 - (35 * i), va("%i", current_points), r, g, b, 1, 2.0f); //2x Scale/White
|
||||
#else
|
||||
xplus = HUD_itoa (f, str)*12;
|
||||
Draw_ColoredStringScale (((111 - xplus)/2)-5, 633, va("%i", current_points), 1, 1, 1, 1, 1.5f);
|
||||
Draw_ColoredStringScale (((111 - xplus)/2)-5, 633 - (24 * i), va("%i", current_points), r, g, b, 1, 1.5f);
|
||||
#endif // VITA
|
||||
|
||||
if (old_points != f)
|
||||
|
@ -485,17 +494,17 @@ void HUD_Points (void)
|
|||
if (f > old_points)
|
||||
{
|
||||
#ifdef VITA
|
||||
HUD_Parse_Point_Change(f - old_points, 0, 80 - (xplus), 415);
|
||||
HUD_Parse_Point_Change(f - old_points, 0, 80 - (xplus), 415 - (35 * i));
|
||||
#else
|
||||
HUD_Parse_Point_Change(f - old_points, 0, 140 - (xplus), y);
|
||||
HUD_Parse_Point_Change(f - old_points, 0, 140 - (xplus), y - (24 * i));
|
||||
#endif // VITA
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef VITA
|
||||
HUD_Parse_Point_Change(old_points - f, 1, 80 - (xplus), 415);
|
||||
HUD_Parse_Point_Change(old_points - f, 1, 80 - (xplus), 415 - (35 * i));
|
||||
#else
|
||||
HUD_Parse_Point_Change(old_points - f, 1, 140 - (xplus), y);
|
||||
HUD_Parse_Point_Change(old_points - f, 1, 140 - (xplus), y - (24 * i));
|
||||
#endif // VITA
|
||||
}
|
||||
old_points = f;
|
||||
|
@ -1942,7 +1951,7 @@ void HUD_Weapon (void)
|
|||
#else
|
||||
y_value = vid.height - 16 - fragpic->height;
|
||||
#endif
|
||||
strcpy(str, pr_strings+sv_player->v.Weapon_Name);
|
||||
strcpy(str, cl.weaponname);
|
||||
//strcpy(str, GetWeaponName(cl.stats[STAT_ACTIVEWEAPON]));
|
||||
l = strlen(str);
|
||||
#ifdef VITA
|
||||
|
|
|
@ -2400,7 +2400,7 @@ void QMB_MuzzleFlash(vec3_t org)
|
|||
|
||||
if(!(ISUNDERWATER(TruePointContents(org))))
|
||||
{
|
||||
size = sv_player->v.Flash_Size;
|
||||
size = cl.flash_size;
|
||||
|
||||
if(size == 0 || cl.stats[STAT_ZOOM] == 2)
|
||||
return;
|
||||
|
|
|
@ -339,13 +339,13 @@ void SCR_UsePrint (int type, int cost, int weapon)
|
|||
button_pic_x = 5;
|
||||
break;
|
||||
case 3://ammo
|
||||
strcpy(w, PR_GetString(sv_player->v.Weapon_Name_Touch));
|
||||
strcpy(w, cl.touchname);
|
||||
strcpy(s, va("Hold %s to buy Ammo for %s\n", GetUseButtonL(), w, cost));
|
||||
strcpy(c, va("[Cost: %i]\n", cost));
|
||||
button_pic_x = 5;
|
||||
break;
|
||||
case 4://weapon
|
||||
strcpy(w, PR_GetString(sv_player->v.Weapon_Name_Touch));
|
||||
strcpy(w, cl.touchname);
|
||||
strcpy(s, va("Hold %s to buy %s\n", GetUseButtonL(), w, cost));
|
||||
strcpy(c, va("[Cost: %i]\n", cost));
|
||||
button_pic_x = 5;
|
||||
|
@ -361,7 +361,7 @@ void SCR_UsePrint (int type, int cost, int weapon)
|
|||
button_pic_x = 5;
|
||||
break;
|
||||
case 7://box take
|
||||
strcpy(w, PR_GetString(sv_player->v.Weapon_Name_Touch));
|
||||
strcpy(w, cl.touchname);
|
||||
strcpy(s, va("Hold %s for %s\n", GetUseButtonL(), w));
|
||||
strcpy(c, "");
|
||||
button_pic_x = 5;
|
||||
|
@ -1601,7 +1601,7 @@ void SCR_DrawCrosshair (void)
|
|||
|
||||
float col;
|
||||
|
||||
if (sv_player->v.facingenemy == 1) {
|
||||
if (cl.facingenemy == 1) {
|
||||
col = 0;
|
||||
} else {
|
||||
col = 255;
|
||||
|
|
|
@ -82,11 +82,7 @@ static int nummodes;
|
|||
static qboolean vid_initialized = false;
|
||||
|
||||
#if defined(USE_SDL2)
|
||||
#ifdef VITA
|
||||
static SDL_Window *draw_context;
|
||||
#else
|
||||
extern SDL_Window *draw_context;
|
||||
#endif
|
||||
static SDL_GLContext gl_context;
|
||||
#else
|
||||
static SDL_Surface *draw_context;
|
||||
|
|
|
@ -568,6 +568,7 @@ void Host_ClearMemory (void)
|
|||
perk_order[6] = 0;
|
||||
perk_order[7] = 0;
|
||||
cl.perks = 0;
|
||||
cl.maxspeed = 0;
|
||||
current_perk_order = 0;
|
||||
crosshair_spread_time = 0;
|
||||
crosshair_offset_step = 0;
|
||||
|
|
|
@ -761,7 +761,7 @@ void IN_JoyMove (usercmd_t *cmd)
|
|||
// Naievil -- share speed for the viewangle
|
||||
speed = 1;
|
||||
//shpuld begin
|
||||
if ((in_aimassist.value == 1) && (sv_player->v.facingenemy == 1) && cl.stats[STAT_CURRENTMAG] > 0) {
|
||||
if ((in_aimassist.value == 1) && (cl.facingenemy == 1) && cl.stats[STAT_CURRENTMAG] > 0) {
|
||||
speed *= 0.5;
|
||||
}
|
||||
// additionally, slice look speed when ADS/scopes
|
||||
|
|
|
@ -86,7 +86,7 @@ static void Sys_InitSDL (void)
|
|||
#include <vitasdk.h>
|
||||
#define DEFAULT_MEMORY (128 * 1024 * 1024) // ericw -- was 72MB (64-bit) / 64MB (32-bit)
|
||||
#else
|
||||
#define DEFAULT_MEMORY (256 * 1024 * 1024) // ericw -- was 72MB (64-bit) / 64MB (32-bit)
|
||||
#define DEFAULT_MEMORY (512 * 1024 * 1024) // ericw -- was 72MB (64-bit) / 64MB (32-bit)
|
||||
#endif
|
||||
|
||||
static quakeparms_t parms;
|
||||
|
|
|
@ -49,6 +49,11 @@ sys_socket_t UDP_Init (void)
|
|||
char *tst;
|
||||
char buff[MAXHOSTNAMELEN];
|
||||
struct qsockaddr addr;
|
||||
#ifndef VITA
|
||||
#ifndef __SWITCH__
|
||||
struct hostent *local;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (COM_CheckParm ("-noudp"))
|
||||
return INVALID_SOCKET;
|
||||
|
|
|
@ -103,10 +103,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define SU_EXTEND2 (1<<23) // another byte to follow
|
||||
#define SU_WEAPONFRAME2 (1<<24) // 1 byte, this is .weaponframe & 0xFF00 (second byte)
|
||||
#define SU_WEAPONALPHA (1<<25) // 1 byte, this is alpha for weaponmodel, uses ENTALPHA_ENCODE, not sent if ENTALPHA_DEFAULT
|
||||
#define SU_UNUSED26 (1<<26)
|
||||
#define SU_UNUSED27 (1<<27)
|
||||
#define SU_UNUSED28 (1<<28)
|
||||
#define SU_UNUSED29 (1<<29)
|
||||
#define SU_MAXSPEED (1<<26)
|
||||
#define SU_FACINGENEMY (1<<27)
|
||||
#define SU_WEAPONNAME (1<<28)
|
||||
#define SU_TOUCHNAME (1<<29)
|
||||
#define SU_UNUSED30 (1<<30)
|
||||
#define SU_EXTEND3 (1<<31) // another byte to follow, future expansion
|
||||
//johnfitz
|
||||
|
|
|
@ -781,6 +781,7 @@ SV_WriteClientdataToMessage
|
|||
|
||||
==================
|
||||
*/
|
||||
extern char* pr_strings;
|
||||
void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
|
||||
{
|
||||
int bits;
|
||||
|
@ -831,6 +832,18 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
|
|||
if (ent->v.perks)
|
||||
bits |= SU_PERKS;
|
||||
|
||||
if (ent->v.maxspeed)
|
||||
bits |= SU_MAXSPEED;
|
||||
|
||||
if (ent->v.facingenemy)
|
||||
bits |= SU_FACINGENEMY;
|
||||
|
||||
if (ent->v.Weapon_Name)
|
||||
bits |= SU_WEAPONNAME;
|
||||
|
||||
//if (ent->v.ADS_Offset[0])
|
||||
// bits |= SU_ADSOFS;
|
||||
|
||||
if ( (int)ent->v.flags & FL_ONGROUND)
|
||||
bits |= SU_ONGROUND;
|
||||
|
||||
|
@ -893,9 +906,45 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
|
|||
MSG_WriteChar (msg, ent->v.velocity[i]/16);
|
||||
}
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
MSG_WriteFloat(msg, ent->v.ADS_Offset[i]);
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
MSG_WriteFloat(msg, ent->v.Flash_Offset[i]);
|
||||
|
||||
MSG_WriteByte(msg, ent->v.Flash_Size);
|
||||
|
||||
if (bits & SU_PERKS)
|
||||
MSG_WriteLong (msg, ent->v.perks);
|
||||
|
||||
if (bits & SU_MAXSPEED)
|
||||
MSG_WriteFloat (msg, ent->v.maxspeed);
|
||||
|
||||
if (bits & SU_FACINGENEMY)
|
||||
MSG_WriteByte (msg, ent->v.facingenemy);
|
||||
|
||||
if (bits & SU_WEAPONNAME) {
|
||||
size_t len = 32;
|
||||
if (strlen(pr_strings+ent->v.Weapon_Name) < 32)
|
||||
len = strlen(pr_strings+ent->v.Weapon_Name);
|
||||
|
||||
MSG_WriteByte(msg, len);
|
||||
for(i = 0; i < len; i++) {
|
||||
MSG_WriteChar(msg, (pr_strings+ent->v.Weapon_Name)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (bits & SU_TOUCHNAME) {
|
||||
size_t len = 32;
|
||||
if (strlen(pr_strings+ent->v.Weapon_Name_Touch) < 32)
|
||||
len = strlen(pr_strings+ent->v.Weapon_Name_Touch);
|
||||
|
||||
MSG_WriteByte(msg, len);
|
||||
for(i = 0; i < len; i++) {
|
||||
MSG_WriteChar(msg, (pr_strings+ent->v.Weapon_Name_Touch)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (bits & SU_WEAPONFRAME)
|
||||
MSG_WriteByte (msg, ent->v.weaponframe);
|
||||
if (bits & SU_WEAPONSKIN)
|
||||
|
|
|
@ -1043,9 +1043,9 @@ void V_CalcRefdef (void)
|
|||
vec3_t ADSOffset;
|
||||
if(cl.stats[STAT_ZOOM] == 1 || cl.stats[STAT_ZOOM] == 2)
|
||||
{
|
||||
ADSOffset[0] = sv_player->v.ADS_Offset[0];
|
||||
ADSOffset[1] = sv_player->v.ADS_Offset[1];
|
||||
ADSOffset[2] = sv_player->v.ADS_Offset[2];
|
||||
ADSOffset[0] = cl.ads_offset[0];
|
||||
ADSOffset[1] = cl.ads_offset[1];
|
||||
ADSOffset[2] = cl.ads_offset[2];
|
||||
|
||||
ADSOffset[0] = ADSOffset[0]/1000;
|
||||
ADSOffset[1] = ADSOffset[1]/1000;
|
||||
|
|
Loading…
Reference in a new issue