mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 11:10:47 +00:00
m32script conveniece
git-svn-id: https://svn.eduke32.com/eduke32@1528 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
20c028b2e9
commit
4bde7fddac
5 changed files with 273 additions and 204 deletions
|
@ -32,7 +32,7 @@ definequote 7 door sector not an island sector!
|
|||
definequote 8 door sector has no SE sprite!
|
||||
|
||||
//light sector x y z range r g b radi fade angle horiz mins maxs prio tile
|
||||
definequote 9 light %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d 0
|
||||
definequote 9 light %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d
|
||||
definequote 10 --PRLIGHTS--
|
||||
definequote 11 --ENDPRLIGHTS--
|
||||
|
||||
|
@ -42,6 +42,7 @@ definequote 14 BLUE:
|
|||
|
||||
definequote 15 x/yoffset: %d %d
|
||||
definequote 16 (r/g/b)color: %d %d %d
|
||||
definequote 17 PICNUM:
|
||||
|
||||
gamearray ar 128
|
||||
gamearray parm 8
|
||||
|
@ -62,26 +63,41 @@ defstate tests
|
|||
sub parm[3] parm[2]
|
||||
qsprintf TQUOTE 6 parm[3]
|
||||
quote TQUOTE
|
||||
|
||||
// iteration and break test
|
||||
for i range 10
|
||||
{
|
||||
addlogvar i
|
||||
ife i 5 break
|
||||
}
|
||||
ife i 5 quote 0 else quote 1
|
||||
ends
|
||||
|
||||
// prints out maphack light definitions based on SE lights in map
|
||||
defstate printlights
|
||||
print 10
|
||||
for i allsprites ifactor SECTOREFFECTOR ifge sprite[i].lotag 49 ifle sprite[i].lotag 50
|
||||
for i allsprites, ifactor SECTOREFFECTOR, ifge .lotag 49, ifle .lotag 50
|
||||
{
|
||||
set j 128, sub j sprite[i].shade, shiftl j 1
|
||||
ife .lotag 50
|
||||
{
|
||||
set j 128, sub j .shade, shiftl j 1
|
||||
set k j, mul k 3, div k 4
|
||||
set l 0
|
||||
ifand sprite[i].cstat 2
|
||||
}
|
||||
else
|
||||
{
|
||||
ifand sprite[i].cstat 512
|
||||
set j 0, set k 0
|
||||
}
|
||||
|
||||
set l 0
|
||||
ifand .cstat 2
|
||||
{
|
||||
ifand .cstat 512
|
||||
set l 4
|
||||
else
|
||||
set l 2
|
||||
}
|
||||
qsprintf TQUOTE 9 sprite[i].sectnum sprite[i].x sprite[i].y sprite[i].z
|
||||
sprite[i].hitag sprite[i].xvel sprite[i].yvel sprite[i].zvel
|
||||
j k sprite[i].ang sprite[i].extra sprite[i].xoffset sprite[i].yoffset l
|
||||
qsprintf TQUOTE 9 .sectnum .x .y .z .hitag .xvel .yvel .zvel
|
||||
j k .ang .extra .xoffset .yoffset l .owner
|
||||
print TQUOTE
|
||||
}
|
||||
print 11
|
||||
|
@ -91,36 +107,36 @@ defstate fiddlewithlights
|
|||
ife searchstat 3 ife sprite[searchwall].picnum SECTOREFFECTOR
|
||||
ifge sprite[searchwall].lotag 49 ifle sprite[searchwall].lotag 50
|
||||
{
|
||||
set i searchwall
|
||||
set i searchwall, seti i
|
||||
|
||||
// horiz
|
||||
ifeithershift set j 1 else set j 10
|
||||
ifhitkey KEY_gUP add sprite[i].extra j
|
||||
else ifhitkey KEY_gKP5 sub sprite[i].extra j
|
||||
clamp sprite[i].extra -500 500
|
||||
ifhitkey KEY_gUP add .extra j
|
||||
else ifhitkey KEY_gKP5 sub .extra j
|
||||
clamp .extra -500 500
|
||||
|
||||
// angle
|
||||
set j 128
|
||||
ifeitherctrl set j 4
|
||||
ifeithershift { ifeitherctrl set j 1 else set j 32 }
|
||||
ifhitkey KEY_gLEFT sub sprite[i].ang j
|
||||
else ifhitkey KEY_gRIGHT add sprite[i].ang j
|
||||
ifhitkey KEY_gLEFT sub .ang j
|
||||
else ifhitkey KEY_gRIGHT add .ang j
|
||||
|
||||
// range
|
||||
ifeithershift set j 10
|
||||
else ifeitherctrl set j 1000
|
||||
else set j 100
|
||||
ifhitkey KEY_gPGUP add sprite[i].hitag j
|
||||
else ifhitkey KEY_gHOME sub sprite[i].hitag j
|
||||
clamp sprite[i].hitag 0 16000
|
||||
ifhitkey KEY_gPGUP add .hitag j
|
||||
else ifhitkey KEY_gHOME sub .hitag j
|
||||
clamp .hitag 0 16000
|
||||
|
||||
// radius
|
||||
ifeitherctrl
|
||||
{
|
||||
ifholdkey KEY_gMINUS add sprite[i].shade 9
|
||||
else ifholdkey KEY_gPLUS sub sprite[i].shade 9
|
||||
ifholdkey KEY_gMINUS add .shade 9
|
||||
else ifholdkey KEY_gPLUS sub .shade 9
|
||||
|
||||
clamp sprite[i].shade -118 117
|
||||
clamp .shade -118 117
|
||||
}
|
||||
|
||||
// min/max shade
|
||||
|
@ -129,29 +145,36 @@ defstate fiddlewithlights
|
|||
{
|
||||
ifhitkey KEY_gSLASH
|
||||
{
|
||||
set sprite[i].xoffset 0
|
||||
set sprite[i].yoffset 0
|
||||
set .xoffset 0
|
||||
set .yoffset 0
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
set k 0
|
||||
ifhitkey KEY_gSLASH { add sprite[i].xoffset j, set k 1 }
|
||||
else ifhitkey KEY_gSTAR { add sprite[i].yoffset j, set k 1 }
|
||||
ifhitkey KEY_gSLASH { add .xoffset j, set k 1 }
|
||||
else ifhitkey KEY_gSTAR { add .yoffset j, set k 1 }
|
||||
|
||||
ife k 1
|
||||
{
|
||||
qsprintf TQUOTE 15 sprite[i].xoffset sprite[i].yoffset
|
||||
qsprintf TQUOTE 15 .xoffset .yoffset
|
||||
quote TQUOTE
|
||||
}
|
||||
}
|
||||
|
||||
// color
|
||||
ifeitheralt ifhitkey KEY_gEND
|
||||
// color/picnum
|
||||
ifeitheralt
|
||||
{
|
||||
getnumber256 sprite[i].xvel 12 255
|
||||
getnumber256 sprite[i].yvel 13 255
|
||||
getnumber256 sprite[i].zvel 14 255
|
||||
ifhitkey KEY_gEND
|
||||
{
|
||||
getnumber256 .xvel 12 255
|
||||
getnumber256 .yvel 13 255
|
||||
getnumber256 .zvel 14 255
|
||||
}
|
||||
else ifhitkey KEY_gDOWN
|
||||
{
|
||||
getnumber256 .owner 17 -MAXTILES
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -159,17 +182,17 @@ defstate fiddlewithlights
|
|||
ifeithershift inv j
|
||||
|
||||
set k 0
|
||||
ifhitkey KEY_gEND { add sprite[i].xvel j, set k 1 }
|
||||
ifhitkey KEY_gDOWN { add sprite[i].yvel j, set k 1 }
|
||||
ifhitkey KEY_gPGDN { add sprite[i].zvel j, set k 1 }
|
||||
ifhitkey KEY_gEND { add .xvel j, set k 1 }
|
||||
ifhitkey KEY_gDOWN { add .yvel j, set k 1 }
|
||||
ifhitkey KEY_gPGDN { add .zvel j, set k 1 }
|
||||
|
||||
ife k 1
|
||||
{
|
||||
clamp sprite[i].xvel 1 255
|
||||
clamp sprite[i].yvel 1 255
|
||||
clamp sprite[i].zvel 1 255
|
||||
clamp .xvel 1 255
|
||||
clamp .yvel 1 255
|
||||
clamp .zvel 1 255
|
||||
|
||||
qsprintf TQUOTE 16 sprite[i].xvel sprite[i].yvel sprite[i].zvel
|
||||
qsprintf TQUOTE 16 .xvel .yvel .zvel
|
||||
quote TQUOTE
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +217,8 @@ endevent
|
|||
onevent EVENT_ANALYZESPRITES
|
||||
for i drawnsprites
|
||||
{
|
||||
switch tsprite[i].picnum
|
||||
set j tsprite[i].owner
|
||||
switch sprite[j].picnum
|
||||
case LIZTROOP spritepal 1 break
|
||||
case PIGCOP spritepal 2 break
|
||||
case BOSS1 spritepal 6 break
|
||||
|
@ -239,20 +263,25 @@ onevent EVENT_DRAW2DSCREEN
|
|||
ifactor LIZTROOP
|
||||
drawcircle16b sprite[i].x sprite[i].y 256 9
|
||||
*/
|
||||
|
||||
/*
|
||||
set i totalclock
|
||||
shiftr i 6
|
||||
drawcircle16b posx posy 256 i
|
||||
set j i
|
||||
add j 8
|
||||
drawcircle16 halfxdim16 midydim16 12 j
|
||||
qsprintf 3 2 i j
|
||||
printmessage16 3
|
||||
*/
|
||||
endevent
|
||||
|
||||
onevent EVENT_OVERHEADEDITOR
|
||||
// LOCATORS auto-incrementer
|
||||
onevent EVENT_INSERTSPRITE2D
|
||||
set k I
|
||||
set j -1
|
||||
for i spritesofsector .sectnum
|
||||
{
|
||||
ifn i k, ifactor LOCATORS, ifg .lotag j
|
||||
set j .lotag
|
||||
}
|
||||
ifg j -1
|
||||
{
|
||||
add j 1
|
||||
set .lotag j
|
||||
}
|
||||
endevent
|
||||
|
||||
onevent EVENT_PREKEYS2D // formerly EVENT_OVERHEADEDITOR
|
||||
for i range 27
|
||||
{
|
||||
ifholdkey alphakeys[i]
|
||||
|
@ -273,16 +302,6 @@ onevent EVENT_OVERHEADEDITOR
|
|||
endevent
|
||||
|
||||
onevent EVENT_KEYS3D
|
||||
for i range 10
|
||||
// ife 0 1
|
||||
{
|
||||
ifholdkey numberkeys[i]
|
||||
{
|
||||
qsprintf TQUOTE 5 i
|
||||
quote TQUOTE
|
||||
}
|
||||
}
|
||||
|
||||
// swinging doors tester -- hit space on a door wall
|
||||
ife searchstat 0
|
||||
ifhitkey KEY_SPACE // SE11 ST23 up:ccw
|
||||
|
|
|
@ -876,7 +876,7 @@ static void C_GetNextVarType(int32_t type)
|
|||
|
||||
return;
|
||||
}
|
||||
else if (*textptr == '-' /* && !isdigit(*(textptr+1))*/)
|
||||
else if (*textptr == '-' && *(textptr+1)!='.' /* && !isdigit(*(textptr+1))*/)
|
||||
{
|
||||
if (type==0)
|
||||
{
|
||||
|
@ -892,6 +892,32 @@ static void C_GetNextVarType(int32_t type)
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (type!=GAMEVAR_SPECIAL && (*textptr == '.' || (*textptr == '-' && *(textptr+1)=='.')))
|
||||
{
|
||||
int32_t lLabelID = -1, aridx=g_iThisActorID;
|
||||
|
||||
flags |= (MAXGAMEVARS<<3);
|
||||
if (*textptr=='-')
|
||||
{
|
||||
flags |= (MAXGAMEVARS<<1);
|
||||
textptr++;
|
||||
}
|
||||
textptr++;
|
||||
/// now pointing at 'xxx'
|
||||
C_GetNextLabelName();
|
||||
lLabelID = C_GetLabelNameID(SpriteLabels, &spriteH, strtolower(tlabel,Bstrlen(tlabel)));
|
||||
|
||||
if (lLabelID == -1)
|
||||
{
|
||||
g_numCompilerErrors++;
|
||||
C_ReportError(ERROR_SYMBOLNOTRECOGNIZED);
|
||||
return;
|
||||
}
|
||||
|
||||
id = g_iSpriteVarID;
|
||||
*g_scriptPtr++ = (aridx<<16 | id | (lLabelID<<2) | flags);
|
||||
return;
|
||||
}
|
||||
|
||||
C_GetNextLabelName();
|
||||
if (hash_find(&keywH, tlabel)>=0)
|
||||
|
@ -3088,7 +3114,7 @@ static void C_AddDefaultDefinitions(void)
|
|||
C_AddDefinition("EVENT_DRAW2DSCREEN", EVENT_DRAW2DSCREEN, LABEL_EVENT);
|
||||
C_AddDefinition("EVENT_KEYS2D", EVENT_KEYS2D, LABEL_EVENT);
|
||||
C_AddDefinition("EVENT_KEYS3D", EVENT_KEYS3D, LABEL_EVENT);
|
||||
C_AddDefinition("EVENT_OVERHEADEDITOR", EVENT_OVERHEADEDITOR, LABEL_EVENT);
|
||||
C_AddDefinition("EVENT_PREKEYS2D", EVENT_OVERHEADEDITOR, LABEL_EVENT);
|
||||
C_AddDefinition("EVENT_PREKEYS3D", EVENT_PREKEYS3D, LABEL_EVENT);
|
||||
|
||||
C_AddDefinition("CLIPMASK0", CLIPMASK0, LABEL_DEFINE);
|
||||
|
@ -3164,6 +3190,19 @@ static void C_AddDefaultDefinitions(void)
|
|||
C_AddDefinition("KEY_RCTRL", KEYSC_RCTRL, LABEL_DEFINE);
|
||||
C_AddDefinition("KEY_RSHIFT", KEYSC_RSHIFT, LABEL_DEFINE);
|
||||
|
||||
// some aliases...
|
||||
C_AddDefinition("KEY_KP7", KEYSC_gHOME, LABEL_DEFINE);
|
||||
C_AddDefinition("KEY_KP8", KEYSC_gUP, LABEL_DEFINE);
|
||||
C_AddDefinition("KEY_KP9", KEYSC_gPGUP, LABEL_DEFINE);
|
||||
C_AddDefinition("KEY_KP4", KEYSC_gLEFT, LABEL_DEFINE);
|
||||
C_AddDefinition("KEY_KP5", KEYSC_gKP5, LABEL_DEFINE);
|
||||
C_AddDefinition("KEY_KP6", KEYSC_gRIGHT, LABEL_DEFINE);
|
||||
C_AddDefinition("KEY_KP1", KEYSC_gEND, LABEL_DEFINE);
|
||||
C_AddDefinition("KEY_KP2", KEYSC_gDOWN, LABEL_DEFINE);
|
||||
C_AddDefinition("KEY_KP3", KEYSC_gPGDN, LABEL_DEFINE);
|
||||
C_AddDefinition("KEY_KP0", KEYSC_gINS, LABEL_DEFINE);
|
||||
C_AddDefinition("KEY_KPCOMMA", KEYSC_gDEL, LABEL_DEFINE);
|
||||
|
||||
C_AddDefinition("KEY_gDEL", KEYSC_gDEL, LABEL_DEFINE);
|
||||
C_AddDefinition("KEY_gDOWN", KEYSC_gDOWN, LABEL_DEFINE);
|
||||
C_AddDefinition("KEY_gEND", KEYSC_gEND, LABEL_DEFINE);
|
||||
|
|
|
@ -87,9 +87,13 @@ typedef struct {
|
|||
// or >= MAXEVENTS+1 and < MAXEVENTS+1+g_stateCount (state)
|
||||
int32_t g_st;
|
||||
spritetype *g_sp;
|
||||
int32_t g_errorFlag, g_returnFlag;
|
||||
uint32_t flags; //g_errorFlag, g_returnFlag;
|
||||
} vmstate_t;
|
||||
|
||||
#define VMFLAG_RETURN 1
|
||||
#define VMFLAG_BREAK 2
|
||||
#define VMFLAG_ERROR 4
|
||||
|
||||
extern vmstate_t vm;
|
||||
extern vmstate_t vm_default;
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@ vmstate_t vm_default =
|
|||
-1,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -159,12 +158,12 @@ void X_OnEvent(register int32_t iEventID, register int32_t iActor)
|
|||
|
||||
vm.g_st = 1+iEventID;
|
||||
|
||||
vm.g_returnFlag = vm.g_errorFlag = 0;
|
||||
vm.flags = 0;
|
||||
|
||||
insptr = script + aEventOffsets[iEventID];
|
||||
X_DoExecute(0);
|
||||
|
||||
if (vm.g_errorFlag)
|
||||
if (vm.flags&VMFLAG_ERROR)
|
||||
{
|
||||
aEventEnabled[iEventID] = 0;
|
||||
message("ERROR executing %s. Event disabled.", label+(iEventID*MAXLABELLEN));
|
||||
|
@ -236,7 +235,7 @@ static int32_t X_DoSort(const int32_t *lv, const int32_t *rv)
|
|||
(vm.g_st!=0 || searchstat!=3 || (vm.g_i=searchwall, vm.g_sp=&sprite[vm.g_i], 0))) \
|
||||
{ \
|
||||
OSD_Printf(CON_ERROR "Current sprite index invalid!\n", g_errorLineNum, keyw[g_tw]); \
|
||||
vm.g_errorFlag = 1; \
|
||||
vm.flags |= VMFLAG_ERROR; \
|
||||
continue; \
|
||||
}
|
||||
|
||||
|
@ -244,7 +243,7 @@ static int32_t X_DoSort(const int32_t *lv, const int32_t *rv)
|
|||
if (dasprite < 0 || dasprite>=MAXSPRITES) \
|
||||
{ \
|
||||
OSD_Printf(CON_ERROR "Invalid sprite index %d!\n", g_errorLineNum, keyw[g_tw], dasprite); \
|
||||
vm.g_errorFlag = 1; \
|
||||
vm.flags |= VMFLAG_ERROR; \
|
||||
continue; \
|
||||
}
|
||||
|
||||
|
@ -252,7 +251,7 @@ static int32_t X_DoSort(const int32_t *lv, const int32_t *rv)
|
|||
if (dasect < 0 || dasect>=numsectors) \
|
||||
{ \
|
||||
OSD_Printf(CON_ERROR "Invalid sector index %d!\n", g_errorLineNum, keyw[g_tw], dasect); \
|
||||
vm.g_errorFlag = 1; \
|
||||
vm.flags |= VMFLAG_ERROR; \
|
||||
continue; \
|
||||
}
|
||||
|
||||
|
@ -260,7 +259,7 @@ static int32_t X_DoSort(const int32_t *lv, const int32_t *rv)
|
|||
if (!vm.g_sp && (vm.g_st!=0 || searchstat!=3 || (vm.g_sp=&sprite[searchwall], 0))) \
|
||||
{ \
|
||||
OSD_Printf(CON_ERROR "Current sprite invalid!\n", g_errorLineNum, keyw[g_tw]); \
|
||||
vm.g_errorFlag = 1; \
|
||||
vm.flags |= VMFLAG_ERROR; \
|
||||
continue; \
|
||||
}
|
||||
|
||||
|
@ -268,13 +267,13 @@ static int32_t X_DoSort(const int32_t *lv, const int32_t *rv)
|
|||
if (q<0 || q>=MAXQUOTES) \
|
||||
{ \
|
||||
OSD_Printf(CON_ERROR "Invalid quote number %d!\n", g_errorLineNum, keyw[g_tw], q); \
|
||||
vm.g_errorFlag = 1; \
|
||||
vm.flags |= VMFLAG_ERROR; \
|
||||
continue; \
|
||||
} \
|
||||
else if (array[q] == NULL) \
|
||||
{ \
|
||||
OSD_Printf(CON_ERROR "Null quote %d!\n", g_errorLineNum, keyw[g_tw], q); \
|
||||
vm.g_errorFlag = 1; \
|
||||
vm.flags |= VMFLAG_ERROR; \
|
||||
continue; \
|
||||
} \
|
||||
|
||||
|
@ -287,7 +286,7 @@ int32_t X_DoExecute(int32_t once)
|
|||
|
||||
while (!once)
|
||||
{
|
||||
if (vm.g_errorFlag + vm.g_returnFlag)
|
||||
if (vm.flags)
|
||||
return 1;
|
||||
|
||||
tw = *insptr;
|
||||
|
@ -309,20 +308,23 @@ skip_check:
|
|||
case CON_STATE:
|
||||
{
|
||||
instype *tempscrptr = insptr+2;
|
||||
int32_t stateidx = *(insptr+1), o_g_st = vm.g_st, oret=vm.g_returnFlag;
|
||||
int32_t stateidx = *(insptr+1), o_g_st = vm.g_st, oret=vm.flags&VMFLAG_RETURN;
|
||||
|
||||
insptr = script + statesinfo[stateidx].ofs;
|
||||
vm.g_st = 1+MAXEVENTS+stateidx;
|
||||
X_DoExecute(0);
|
||||
vm.g_st = o_g_st;
|
||||
vm.g_returnFlag = oret;
|
||||
vm.flags &= ~VMFLAG_RETURN;
|
||||
vm.flags |= oret;
|
||||
insptr = tempscrptr;
|
||||
}
|
||||
continue;
|
||||
|
||||
case CON_RETURN:
|
||||
vm.g_returnFlag = 1;
|
||||
vm.flags |= VMFLAG_RETURN;
|
||||
return 1;
|
||||
case CON_BREAK:
|
||||
vm.flags |= VMFLAG_BREAK;
|
||||
case CON_ENDS:
|
||||
return 1;
|
||||
|
||||
|
@ -332,6 +334,7 @@ skip_check:
|
|||
continue;
|
||||
|
||||
case CON_ENDSWITCH:
|
||||
vm.flags &= ~VMFLAG_BREAK;
|
||||
case CON_ENDEVENT:
|
||||
insptr++;
|
||||
return 1;
|
||||
|
@ -414,7 +417,7 @@ skip_check:
|
|||
if (j<0 || j>=(g_scriptPtr-script))
|
||||
{
|
||||
OSD_Printf(CON_ERROR "script index out of bounds (%d)\n", g_errorLineNum, keyw[g_tw], j);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
continue;
|
||||
}
|
||||
insptr = (instype *)(j+script);
|
||||
|
@ -505,19 +508,19 @@ skip_check:
|
|||
if (j<0 || j >= g_gameArrayCount)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Tried to set invalid array ID (%d)\n", g_errorLineNum, keyw[g_tw], j);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
}
|
||||
if (aGameArrays[j].dwFlags & GAMEARRAY_READONLY)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Tried to set on read-only array `%s'\n", g_errorLineNum, keyw[g_tw], aGameArrays[j].szLabel);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
}
|
||||
if (index >= aGameArrays[j].size || index < 0)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Array index %d out of bounds\n", g_errorLineNum, keyw[g_tw], index);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
}
|
||||
if (vm.g_errorFlag) continue;
|
||||
if (vm.flags&VMFLAG_ERROR) continue;
|
||||
((int32_t *)aGameArrays[j].vals)[index]=value; // REM: other array types not implemented, since they're read-only
|
||||
continue;
|
||||
}
|
||||
|
@ -540,8 +543,8 @@ skip_check:
|
|||
if (asize<=0 || asize>65536)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Invalid array size %d (max: 65536)\n",g_errorLineNum,keyw[g_tw]);
|
||||
vm.g_errorFlag = 1;
|
||||
continue;;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
continue;
|
||||
}
|
||||
|
||||
// OSD_Printf(OSDTEXT_GREEN "CON_RESIZEARRAY: resizing array %s from %d to %d\n", aGameArrays[j].szLabel, aGameArrays[j].size, asize);
|
||||
|
@ -550,7 +553,7 @@ skip_check:
|
|||
{
|
||||
aGameArrays[j].size = 0;
|
||||
OSD_Printf(CON_ERROR "Out of memory!\n",g_errorLineNum,keyw[g_tw]);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
return 1;
|
||||
}
|
||||
aGameArrays[j].size = asize;
|
||||
|
@ -570,19 +573,19 @@ skip_check:
|
|||
if (si<0 || si>=g_gameArrayCount)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Invalid array %d!\n",g_errorLineNum,keyw[g_tw],si);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
}
|
||||
if (di<0 || di>=g_gameArrayCount)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Invalid array %d!\n",g_errorLineNum,keyw[g_tw],di);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
}
|
||||
if (aGameArrays[di].dwFlags & GAMEARRAY_READONLY)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Array %d is read-only!\n",g_errorLineNum,keyw[g_tw],di);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
}
|
||||
if (vm.g_errorFlag) continue;
|
||||
if (vm.flags&VMFLAG_ERROR) continue;
|
||||
|
||||
ssiz = (aGameArrays[si].dwFlags&GAMEARRAY_VARSIZE) ?
|
||||
Gv_GetVarN(aGameArrays[si].size) : aGameArrays[si].size;
|
||||
|
@ -858,14 +861,14 @@ skip_check:
|
|||
if (xvar < 0 || xvar >= MAXSPRITES || sprite[xvar].statnum==MAXSTATUS)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "invalid sprite %d\n",g_errorLineNum,keyw[g_tw],xvar);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
}
|
||||
if (yvar < 0 || yvar >= MAXSPRITES || sprite[yvar].statnum==MAXSTATUS)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "invalid sprite %d\n",g_errorLineNum,keyw[g_tw],yvar);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
}
|
||||
if (vm.g_errorFlag) continue;
|
||||
if (vm.flags&VMFLAG_ERROR) continue;
|
||||
|
||||
if (tw==CON_DIST)
|
||||
Gv_SetVarX(distvar, dist(&sprite[xvar],&sprite[yvar]));
|
||||
|
@ -1043,7 +1046,8 @@ skip_check:
|
|||
j = (Gv_GetVarX(*(insptr-1)) != *insptr);
|
||||
X_DoConditional(j);
|
||||
}
|
||||
while (j);
|
||||
while (j && !vm.flags);
|
||||
vm.flags &= ~VMFLAG_BREAK;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1057,7 +1061,8 @@ skip_check:
|
|||
j = (Gv_GetVarX(*(insptr-1)) < *insptr);
|
||||
X_DoConditional(j);
|
||||
}
|
||||
while (j);
|
||||
while (j && !vm.flags);
|
||||
vm.flags &= ~VMFLAG_BREAK;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1073,7 +1078,8 @@ skip_check:
|
|||
insptr--;
|
||||
X_DoConditional(j);
|
||||
}
|
||||
while (j);
|
||||
while (j && !vm.flags);
|
||||
vm.flags &= ~VMFLAG_BREAK;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1089,7 +1095,8 @@ skip_check:
|
|||
insptr--;
|
||||
X_DoConditional(j);
|
||||
}
|
||||
while (j);
|
||||
while (j && !vm.flags);
|
||||
vm.flags &= ~VMFLAG_BREAK;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1104,7 +1111,7 @@ skip_check:
|
|||
if (count > aGameArrays[aridx].size)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Count of elements to sort (%d) exceeds array size (%d)!\n",g_errorLineNum,keyw[g_tw],count,aGameArrays[aridx].size);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1133,12 +1140,12 @@ skip_check:
|
|||
spritetype *vm_sp_bak = vm.g_sp;
|
||||
int16_t endwall;
|
||||
|
||||
if (vm.g_errorFlag) continue;
|
||||
if (vm.flags&VMFLAG_ERROR) continue;
|
||||
|
||||
switch (how)
|
||||
{
|
||||
case ITER_ALLSPRITES:
|
||||
for (jj=0; jj<MAXSPRITES; jj++)
|
||||
for (jj=0; jj<MAXSPRITES && !vm.flags; jj++)
|
||||
{
|
||||
if (sprite[jj].statnum == MAXSTATUS)
|
||||
continue;
|
||||
|
@ -1150,7 +1157,7 @@ skip_check:
|
|||
}
|
||||
break;
|
||||
case ITER_ALLSECTORS:
|
||||
for (jj=0; jj<numsectors; jj++)
|
||||
for (jj=0; jj<numsectors && !vm.flags; jj++)
|
||||
{
|
||||
Gv_SetVarX(var, jj);
|
||||
insptr = beg;
|
||||
|
@ -1158,7 +1165,7 @@ skip_check:
|
|||
}
|
||||
break;
|
||||
case ITER_ALLWALLS:
|
||||
for (jj=0; jj<numwalls; jj++)
|
||||
for (jj=0; jj<numwalls && !vm.flags; jj++)
|
||||
{
|
||||
Gv_SetVarX(var, jj);
|
||||
insptr = beg;
|
||||
|
@ -1166,7 +1173,7 @@ skip_check:
|
|||
}
|
||||
break;
|
||||
case ITER_SELSPRITES:
|
||||
for (ii=0; ii<highlightcnt; ii++)
|
||||
for (ii=0; ii<highlightcnt && !vm.flags; ii++)
|
||||
{
|
||||
jj = highlight[ii];
|
||||
if (jj&0xc000)
|
||||
|
@ -1181,7 +1188,7 @@ skip_check:
|
|||
}
|
||||
break;
|
||||
case ITER_SELSECTORS:
|
||||
for (ii=0; ii<highlightsectorcnt; ii++)
|
||||
for (ii=0; ii<highlightsectorcnt && !vm.flags; ii++)
|
||||
{
|
||||
jj=highlightsector[ii];
|
||||
Gv_SetVarX(var, jj);
|
||||
|
@ -1190,7 +1197,7 @@ skip_check:
|
|||
}
|
||||
break;
|
||||
case ITER_SELWALLS:
|
||||
for (ii=0; ii<highlightcnt; ii++)
|
||||
for (ii=0; ii<highlightcnt && !vm.flags; ii++)
|
||||
{
|
||||
jj=highlight[ii];
|
||||
if (jj&0xc000)
|
||||
|
@ -1201,7 +1208,7 @@ skip_check:
|
|||
}
|
||||
break;
|
||||
case ITER_DRAWNSPRITES:
|
||||
for (ii=0; ii<spritesortcnt; ii++)
|
||||
for (ii=0; ii<spritesortcnt && !vm.flags; ii++)
|
||||
{
|
||||
vm.g_sp = &tsprite[ii];
|
||||
Gv_SetVarX(var, ii);
|
||||
|
@ -1212,7 +1219,7 @@ skip_check:
|
|||
case ITER_SPRITESOFSECTOR:
|
||||
if (parm2 < 0 || parm2 >= MAXSECTORS)
|
||||
goto badindex;
|
||||
for (jj=headspritesect[parm2]; jj>=0; jj=nextspritesect[jj])
|
||||
for (jj=headspritesect[parm2]; jj>=0 && !vm.flags; jj=nextspritesect[jj])
|
||||
{
|
||||
Gv_SetVarX(var, jj);
|
||||
vm.g_i = jj;
|
||||
|
@ -1224,7 +1231,8 @@ skip_check:
|
|||
case ITER_WALLSOFSECTOR:
|
||||
if (parm2 < 0 || parm2 >= MAXSECTORS)
|
||||
goto badindex;
|
||||
for(jj=sector[parm2].wallptr, endwall=jj+sector[parm2].wallnum-1; jj<=endwall; jj++)
|
||||
for(jj=sector[parm2].wallptr, endwall=jj+sector[parm2].wallnum-1;
|
||||
jj<=endwall && !vm.flags; jj++)
|
||||
{
|
||||
Gv_SetVarX(var, jj);
|
||||
insptr = beg;
|
||||
|
@ -1241,10 +1249,10 @@ skip_check:
|
|||
insptr = beg;
|
||||
X_DoExecute(1);
|
||||
jj = wall[jj].point2;
|
||||
} while (jj != parm2);
|
||||
} while (jj != parm2 && !vm.flags);
|
||||
break;
|
||||
case ITER_RANGE:
|
||||
for (jj=0; jj<parm2; jj++)
|
||||
for (jj=0; jj<parm2 && !vm.flags; jj++)
|
||||
{
|
||||
Gv_SetVarX(var, jj);
|
||||
insptr = beg;
|
||||
|
@ -1253,16 +1261,17 @@ skip_check:
|
|||
break;
|
||||
default:
|
||||
OSD_Printf(CON_ERROR "Unknown iteration type %d!\n",g_errorLineNum,keyw[g_tw],how);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
continue;
|
||||
badindex:
|
||||
OSD_Printf(OSD_ERROR "Line %d, %s %s: index %d out of range!\n",g_errorLineNum,keyw[g_tw],
|
||||
iter_tokens[how], parm2);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
continue;
|
||||
}
|
||||
vm.g_i = vm_i_bak;
|
||||
vm.g_sp = vm_sp_bak;
|
||||
vm.flags &= ~VMFLAG_BREAK;
|
||||
insptr = end;
|
||||
}
|
||||
continue;
|
||||
|
@ -1352,7 +1361,7 @@ badindex:
|
|||
if (key<0 || key >= (int32_t)(sizeof(keystatus)/sizeof(keystatus[0])))
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Invalid key %d!\n",g_errorLineNum,keyw[g_tw],key);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1463,7 +1472,7 @@ badindex:
|
|||
{
|
||||
OSD_Printf(CON_ERROR "Sector index %d out of range!\n",g_errorLineNum,keyw[g_tw],
|
||||
sectnum);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
continue;
|
||||
}
|
||||
insptr--;
|
||||
|
@ -1503,7 +1512,7 @@ badindex:
|
|||
if (numsprites >= MAXSPRITES)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Maximum number of sprites reached.\n",g_errorLineNum,keyw[g_tw]);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1522,21 +1531,21 @@ badindex:
|
|||
if (ospritenum<0 || ospritenum>=MAXSPRITES || sprite[ospritenum].statnum==MAXSTATUS)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Tried to duplicate nonexistent sprite %d\n",g_errorLineNum,keyw[g_tw],ospritenum);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
}
|
||||
if (numsprites >= MAXSPRITES)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Maximum number of sprites reached.\n",g_errorLineNum,keyw[g_tw]);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
}
|
||||
if (vm.g_errorFlag) continue;
|
||||
if (vm.flags&VMFLAG_ERROR) continue;
|
||||
|
||||
nspritenum = insertsprite(sprite[ospritenum].sectnum, sprite[ospritenum].statnum);
|
||||
|
||||
if (nspritenum < 0)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Internal error.\n",g_errorLineNum,keyw[g_tw]);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1568,7 +1577,7 @@ badindex:
|
|||
if (dapoint<0 || dapoint>=numwalls)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Invalid wall %d\n",g_errorLineNum,keyw[g_tw],dapoint);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1775,7 +1784,7 @@ badindex:
|
|||
if (j < 0 || j > MAXSTATUS)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "invalid status list %d\n",g_errorLineNum,keyw[g_tw],j);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
continue;
|
||||
}
|
||||
Gv_SetVarX(i,headspritestat[j]);
|
||||
|
@ -1845,15 +1854,15 @@ badindex:
|
|||
if (lVar1<0 || lVar1>=MAXSPRITES || sprite[lVar1].statnum==MAXSTATUS)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Invalid sprite %d\n",g_errorLineNum,keyw[g_tw],lVar1);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
}
|
||||
if (lVar2<0 || lVar2>=MAXSPRITES || sprite[lVar2].statnum==MAXSTATUS)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Invalid sprite %d\n",g_errorLineNum,keyw[g_tw],lVar2);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
}
|
||||
|
||||
if (vm.g_errorFlag) res=0;
|
||||
if (vm.flags&VMFLAG_ERROR) res=0;
|
||||
else res=cansee(sprite[lVar1].x,sprite[lVar1].y,sprite[lVar1].z,sprite[lVar1].sectnum,
|
||||
sprite[lVar2].x,sprite[lVar2].y,sprite[lVar2].z,sprite[lVar2].sectnum);
|
||||
|
||||
|
@ -1873,7 +1882,7 @@ badindex:
|
|||
{
|
||||
OSD_Printf(CON_ERROR "Invalid %s: %d\n", tw==CON_CHANGESPRITESTAT?"statnum":"sector",
|
||||
g_errorLineNum,keyw[g_tw],j);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1898,7 +1907,7 @@ badindex:
|
|||
if (wallnum<0 || wallnum>=numwalls)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Invalid wall %d\n",g_errorLineNum,keyw[g_tw],wallnum);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
continue;
|
||||
}
|
||||
dragpoint(wallnum,newx,newy);
|
||||
|
@ -2059,7 +2068,7 @@ badindex:
|
|||
int32_t backcol=(tw>=CON_PRINTEXT256)?Gv_GetVarX(*insptr++):0;
|
||||
int32_t fontsize=(tw>=CON_PRINTEXT256)?Gv_GetVarX(*insptr++):0;
|
||||
|
||||
if (tw==CON_ERRORINS) vm.g_errorFlag = 1;
|
||||
if (tw==CON_ERRORINS) vm.flags |= VMFLAG_ERROR;
|
||||
|
||||
X_ERROR_INVALIDQUOTE(i, ScriptQuotes);
|
||||
|
||||
|
@ -2545,7 +2554,7 @@ dodefault:
|
|||
"you're using and instructions how to reproduce this error to\n"
|
||||
"helixhorned@gmail.com.\n\n"
|
||||
"Thank you!");
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -225,7 +225,7 @@ int32_t __fastcall Gv_GetVarN(register int32_t id) // 'N' for "no side-effects"
|
|||
if (id & (0xFFFFFFFF-(MAXGAMEVARS-1)))
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Gv_GetVarN(): invalid var index %d\n",g_errorLineNum,keyw[g_tw],id);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -246,7 +246,7 @@ int32_t __fastcall Gv_GetVarN(register int32_t id) // 'N' for "no side-effects"
|
|||
return *((uint8_t*)aGameVars[id].val.lValue);
|
||||
default:
|
||||
OSD_Printf(CON_ERROR "Gv_GetVarN(): WTF??\n",g_errorLineNum,keyw[g_tw]);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ int32_t __fastcall Gv_GetVarX(register int32_t id)
|
|||
return labelval[(id>>16)&0xffff];
|
||||
default:
|
||||
OSD_Printf(CON_ERROR "Gv_GetVarX() (constant): WTF??\n",g_errorLineNum,keyw[g_tw]);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -311,7 +311,7 @@ int32_t __fastcall Gv_GetVarX(register int32_t id)
|
|||
return ((((uint8_t *)aGameArrays[id].vals)[index] ^ -negateResult) + negateResult);
|
||||
default:
|
||||
OSD_Printf(CON_ERROR "Gv_GetVarX() (array): WTF??\n",g_errorLineNum,keyw[g_tw]);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -348,7 +348,7 @@ int32_t __fastcall Gv_GetVarX(register int32_t id)
|
|||
if (!negateResult)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Gv_GetVarX(): invalid gamevar ID (%d)\n",g_errorLineNum,keyw[g_tw],id);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ int32_t __fastcall Gv_GetVarX(register int32_t id)
|
|||
return ((*((uint8_t*)aGameVars[id].val.lValue) ^ -negateResult) + negateResult);
|
||||
default:
|
||||
OSD_Printf(CON_ERROR "Gv_GetVarX(): WTF??\n",g_errorLineNum,keyw[g_tw]);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -396,7 +396,7 @@ void __fastcall Gv_SetVarX(register int32_t id, register int32_t lValue)
|
|||
if (index < 0 || index >= siz)
|
||||
{
|
||||
OSD_Printf(CON_ERROR "Gv_SetVarX(): invalid array index (%s[%d])\n",g_errorLineNum,keyw[g_tw],aGameArrays[id].szLabel,index);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -414,7 +414,7 @@ void __fastcall Gv_SetVarX(register int32_t id, register int32_t lValue)
|
|||
return;
|
||||
default:
|
||||
OSD_Printf(CON_ERROR "Gv_SetVarX() (array): WTF??\n",g_errorLineNum,keyw[g_tw]);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
@ -452,7 +452,7 @@ void __fastcall Gv_SetVarX(register int32_t id, register int32_t lValue)
|
|||
}
|
||||
|
||||
OSD_Printf(CON_ERROR "Gv_SetVarX(): invalid gamevar ID (%d)\n",g_errorLineNum,keyw[g_tw],id);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -476,7 +476,7 @@ void __fastcall Gv_SetVarX(register int32_t id, register int32_t lValue)
|
|||
return;
|
||||
default:
|
||||
OSD_Printf(CON_ERROR "Gv_SetVarX(): WTF??\n",g_errorLineNum,keyw[g_tw]);
|
||||
vm.g_errorFlag = 1;
|
||||
vm.flags |= VMFLAG_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -611,8 +611,6 @@ static void Gv_AddSystemVars(void)
|
|||
GAMEARRAY_READONLY|GAMEARRAY_OFSHORT|GAMEARRAY_VARSIZE);
|
||||
Gv_NewArray("highlightsector", (void *)highlightsector, hlscnt_id,
|
||||
GAMEARRAY_READONLY|GAMEARRAY_OFSHORT|GAMEARRAY_VARSIZE);
|
||||
Gv_NewArray("sintable", (void *)sintable, 2048,
|
||||
GAMEARRAY_READONLY|GAMEARRAY_OFSHORT);
|
||||
|
||||
Gv_NewArray("hsect", (void *)headspritesect, MAXSECTORS+1, GAMEARRAY_READONLY|GAMEARRAY_OFSHORT);
|
||||
Gv_NewArray("nsect", (void *)prevspritesect, MAXSPRITES, GAMEARRAY_READONLY|GAMEARRAY_OFSHORT);
|
||||
|
|
Loading…
Reference in a new issue