mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-02-23 22:11:01 +00:00
Merge branch 'acs-get-set' into 'master'
ACS: Property get/set functions See merge request KartKrew/Kart!1203
This commit is contained in:
commit
2cba1b7820
12 changed files with 2410 additions and 9 deletions
|
|
@ -144,6 +144,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
|
|||
k_vote.c
|
||||
k_serverstats.c
|
||||
k_zvote.c
|
||||
k_mapuser.c
|
||||
)
|
||||
|
||||
if(SRB2_CONFIG_ENABLE_WEBM_MOVIES)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -83,4 +83,18 @@ bool CallFunc_PodiumFinish(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM
|
|||
|
||||
bool CallFunc_SetLineRenderStyle(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
|
||||
bool CallFunc_GetLineProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_SetLineProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_GetSideProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_SetSideProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_GetSectorProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_SetSectorProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_GetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_SetThingProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
|
||||
bool CallFunc_GetLineUserProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_GetSideUserProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_GetSectorUserProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_GetThingUserProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
|
||||
#endif // __SRB2_ACS_CALL_FUNCS_HPP__
|
||||
|
|
|
|||
|
|
@ -128,14 +128,22 @@ Environment::Environment()
|
|||
// This style is preferred for added functions
|
||||
// that aren't mimicing one from Hexen's or ZDoom's
|
||||
// ACS implementations.
|
||||
//addFuncDataACS0( 1, addCallFunc(CallFunc_GetLineUDMFInt));
|
||||
//addFuncDataACS0( 2, addCallFunc(CallFunc_GetLineUDMFFixed));
|
||||
//addFuncDataACS0( 3, addCallFunc(CallFunc_GetThingUDMFInt));
|
||||
//addFuncDataACS0( 4, addCallFunc(CallFunc_GetThingUDMFFixed));
|
||||
//addFuncDataACS0( 5, addCallFunc(CallFunc_GetSectorUDMFInt));
|
||||
//addFuncDataACS0( 6, addCallFunc(CallFunc_GetSectorUDMFFixed));
|
||||
//addFuncDataACS0( 7, addCallFunc(CallFunc_GetSideUDMFInt));
|
||||
//addFuncDataACS0( 8, addCallFunc(CallFunc_GetSideUDMFFixed));
|
||||
addFuncDataACS0( 1, addCallFunc(CallFunc_GetLineProperty));
|
||||
addFuncDataACS0( 2, addCallFunc(CallFunc_SetLineProperty));
|
||||
addFuncDataACS0( 3, addCallFunc(CallFunc_GetLineUserProperty));
|
||||
addFuncDataACS0( 4, addCallFunc(CallFunc_GetSectorProperty));
|
||||
addFuncDataACS0( 5, addCallFunc(CallFunc_SetSectorProperty));
|
||||
addFuncDataACS0( 6, addCallFunc(CallFunc_GetSectorUserProperty));
|
||||
addFuncDataACS0( 7, addCallFunc(CallFunc_GetSideProperty));
|
||||
addFuncDataACS0( 8, addCallFunc(CallFunc_SetSideProperty));
|
||||
addFuncDataACS0( 9, addCallFunc(CallFunc_GetSideUserProperty));
|
||||
addFuncDataACS0( 10, addCallFunc(CallFunc_GetThingProperty));
|
||||
addFuncDataACS0( 11, addCallFunc(CallFunc_SetThingProperty));
|
||||
addFuncDataACS0( 12, addCallFunc(CallFunc_GetThingUserProperty));
|
||||
//addFuncDataACS0( 13, addCallFunc(CallFunc_GetPlayerProperty));
|
||||
//addFuncDataACS0( 14, addCallFunc(CallFunc_SetPlayerProperty));
|
||||
//addFuncDataACS0( 15, addCallFunc(CallFunc_GetPolyobjProperty));
|
||||
//addFuncDataACS0( 16, addCallFunc(CallFunc_SetPolyobjProperty));
|
||||
|
||||
addFuncDataACS0( 100, addCallFunc(CallFunc_strcmp));
|
||||
addFuncDataACS0( 101, addCallFunc(CallFunc_strcasecmp));
|
||||
|
|
|
|||
|
|
@ -233,6 +233,21 @@ struct mapnode_t
|
|||
#pragma pack()
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
USER_PROP_BOOL,
|
||||
USER_PROP_INT,
|
||||
USER_PROP_FIXED,
|
||||
USER_PROP_STR
|
||||
} mapUserPropertyType_e;
|
||||
|
||||
struct mapUserProperties_t
|
||||
{
|
||||
mapUserProperty_t *properties;
|
||||
size_t length;
|
||||
size_t capacity;
|
||||
};
|
||||
|
||||
#define NUMMAPTHINGARGS 10
|
||||
#define NUMMAPTHINGSTRINGARGS 2
|
||||
|
||||
|
|
@ -252,6 +267,7 @@ struct mapthing_t
|
|||
INT32 args[NUMMAPTHINGARGS];
|
||||
char *stringargs[NUMMAPTHINGSTRINGARGS];
|
||||
UINT8 layer; // FOF layer to spawn on, see P_GetMobjSpawnHeight
|
||||
mapUserProperties_t user; // UDMF user-defined custom properties.
|
||||
mobj_t *mobj;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -540,6 +540,7 @@ void M_TokenizerClose(void);
|
|||
const char *M_TokenizerRead(UINT32 i);
|
||||
UINT32 M_TokenizerGetEndPos(void);
|
||||
void M_TokenizerSetEndPos(UINT32 newPos);
|
||||
boolean M_TokenizerJustReadString(void);
|
||||
|
||||
char *sizeu1(size_t num);
|
||||
char *sizeu2(size_t num);
|
||||
|
|
|
|||
180
src/k_mapuser.c
Normal file
180
src/k_mapuser.c
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file k_mapuser.c
|
||||
/// \brief UDMF: Custom user properties
|
||||
|
||||
#include "k_mapuser.h"
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "doomdata.h"
|
||||
#include "doomtype.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_misc.h"
|
||||
#include "m_fixed.h"
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_UserPropertyPush(mapUserProperties_t *user, const char *key, mapUserPropertyType_e type, void *value)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
void K_UserPropertyPush(mapUserProperties_t *user, const char *key, mapUserPropertyType_e type, void *value)
|
||||
{
|
||||
const size_t keyLength = strlen(key);
|
||||
mapUserProperty_t *prop = NULL;
|
||||
|
||||
I_Assert(keyLength > 0);
|
||||
|
||||
if (user->length >= user->capacity)
|
||||
{
|
||||
if (user->capacity == 0)
|
||||
{
|
||||
user->capacity = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
user->capacity *= 2;
|
||||
}
|
||||
|
||||
user->properties = (mapUserProperty_t *)Z_ReallocAlign(
|
||||
user->properties,
|
||||
sizeof(mapUserProperty_t) * user->capacity,
|
||||
PU_LEVEL,
|
||||
NULL,
|
||||
sizeof(mapUserProperty_t) * 8
|
||||
);
|
||||
}
|
||||
|
||||
prop = &user->properties[ user->length ];
|
||||
|
||||
prop->key = Z_Malloc(keyLength + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(prop->key, key, keyLength + 1);
|
||||
prop->key[keyLength] = '\0';
|
||||
|
||||
prop->hash = quickncasehash(prop->key, keyLength);
|
||||
|
||||
prop->type = type;
|
||||
switch (type)
|
||||
{
|
||||
case USER_PROP_BOOL:
|
||||
{
|
||||
prop->valueBool = *(boolean *)value;
|
||||
break;
|
||||
}
|
||||
case USER_PROP_INT:
|
||||
{
|
||||
prop->valueInt = *(INT32 *)value;
|
||||
break;
|
||||
}
|
||||
case USER_PROP_FIXED:
|
||||
{
|
||||
prop->valueFixed = *(fixed_t *)value;
|
||||
break;
|
||||
}
|
||||
case USER_PROP_STR:
|
||||
{
|
||||
const char *string = *(const char **)value;
|
||||
const size_t stringLength = strlen(string);
|
||||
|
||||
prop->valueStr = Z_Malloc(stringLength + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(prop->valueStr, string, stringLength + 1);
|
||||
prop->valueStr[stringLength] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
user->length++;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
mapUserProperty_t *K_UserPropertyFind(mapUserProperties_t *user, const char *key)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
mapUserProperty_t *K_UserPropertyFind(mapUserProperties_t *user, const char *key)
|
||||
{
|
||||
const size_t keyLength = strlen(key);
|
||||
const UINT32 hash = quickncasehash(key, keyLength);
|
||||
size_t i;
|
||||
|
||||
if (user->length == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < user->length; i++)
|
||||
{
|
||||
mapUserProperty_t *const prop = &user->properties[ i ];
|
||||
|
||||
if (hash != prop->hash)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcasecmp(key, prop->key))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void K_UserPropertyFree(mapUserProperty_t *prop)
|
||||
|
||||
Frees the memory of a single user property.
|
||||
|
||||
Input Arguments:-
|
||||
prop - User property memory structure to free.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
static void K_UserPropertyFree(mapUserProperty_t *prop)
|
||||
{
|
||||
if (prop->key != NULL)
|
||||
{
|
||||
Z_Free(prop->key);
|
||||
prop->key = NULL;
|
||||
}
|
||||
|
||||
if (prop->valueStr != NULL)
|
||||
{
|
||||
Z_Free(prop->valueStr);
|
||||
prop->valueStr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_UserPropertiesClear(mapUserProperties_t *user)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
void K_UserPropertiesClear(mapUserProperties_t *user)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (user->properties == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < user->length; i++)
|
||||
{
|
||||
K_UserPropertyFree(&user->properties[i]);
|
||||
}
|
||||
|
||||
Z_Free(user->properties);
|
||||
user->properties = NULL;
|
||||
user->length = user->capacity = 0;
|
||||
}
|
||||
94
src/k_mapuser.h
Normal file
94
src/k_mapuser.h
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file k_mapuser.h
|
||||
/// \brief UDMF: Custom user properties
|
||||
|
||||
#ifndef __K_MAPUSER__
|
||||
#define __K_MAPUSER__
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
#include "doomdata.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct mapUserProperty_t
|
||||
{
|
||||
UINT32 hash;
|
||||
char *key;
|
||||
|
||||
mapUserPropertyType_e type;
|
||||
|
||||
boolean valueBool;
|
||||
INT32 valueInt;
|
||||
fixed_t valueFixed;
|
||||
char *valueStr;
|
||||
};
|
||||
|
||||
// mapUserProperties_t has to be defined in doomdata.h instead
|
||||
// because of circular dependency issues
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_UserPropertyPush(mapUserProperties_t *user, const char *key, mapUserPropertyType_e type, void *value);
|
||||
|
||||
Adds a new key value to the user properties struct.
|
||||
|
||||
Input Arguments:-
|
||||
user - User properties memory structure.
|
||||
key - The key to add.
|
||||
type - Enum representing the type of the value to add.
|
||||
value - The value to add, as a void pointer.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_UserPropertyPush(mapUserProperties_t *user, const char *key, mapUserPropertyType_e type, void *value);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
mapUserProperty_t *K_UserPropertyFind(mapUserProperties_t *user, const char *key);
|
||||
|
||||
Tries to find if the key value already exists in this
|
||||
user properties struct.
|
||||
|
||||
Input Arguments:-
|
||||
user - User properties memory structure.
|
||||
key - The key to find.
|
||||
|
||||
Return:-
|
||||
The struct of the property we just got, or NULL if the key didn't exist already.
|
||||
--------------------------------------------------*/
|
||||
|
||||
mapUserProperty_t *K_UserPropertyFind(mapUserProperties_t *user, const char *key);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_UserPropertiesClear(mapUserProperties_t *user);
|
||||
|
||||
Frees an entire user properties struct.
|
||||
|
||||
Input Arguments:-
|
||||
user - User properties memory structure to free.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_UserPropertiesClear(mapUserProperties_t *user);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // __K_MAPUSER__
|
||||
|
|
@ -2295,6 +2295,7 @@ static UINT32 tokenizerStartPos = 0;
|
|||
static UINT32 tokenizerEndPos = 0;
|
||||
static UINT32 tokenizerInputLength = 0;
|
||||
static UINT8 tokenizerInComment = 0; // 0 = not in comment, 1 = // Single-line, 2 = /* Multi-line */
|
||||
static boolean tokenizerIsString = false; // did we strip quotes from this token?
|
||||
|
||||
void M_TokenizerOpen(const char *inputString)
|
||||
{
|
||||
|
|
@ -2319,6 +2320,7 @@ void M_TokenizerClose(void)
|
|||
tokenizerStartPos = 0;
|
||||
tokenizerEndPos = 0;
|
||||
tokenizerInComment = 0;
|
||||
tokenizerIsString = false;
|
||||
}
|
||||
|
||||
static void M_DetectComment(UINT32 *pos)
|
||||
|
|
@ -2349,8 +2351,10 @@ static void M_ReadTokenString(UINT32 i)
|
|||
// Assign the memory. Don't forget an extra byte for the end of the string!
|
||||
tokenizerToken[i] = (char *)Z_Malloc(tokenCapacity[i] * sizeof(char), PU_STATIC, NULL);
|
||||
}
|
||||
|
||||
// Copy the string.
|
||||
M_Memcpy(tokenizerToken[i], tokenizerInput + tokenizerStartPos, (size_t)tokenLength);
|
||||
|
||||
// Make the final character NUL.
|
||||
tokenizerToken[i][tokenLength] = '\0';
|
||||
}
|
||||
|
|
@ -2362,6 +2366,9 @@ const char *M_TokenizerRead(UINT32 i)
|
|||
|
||||
tokenizerStartPos = tokenizerEndPos;
|
||||
|
||||
// Reset string flag
|
||||
tokenizerIsString = false;
|
||||
|
||||
// Try to detect comments now, in case we're pointing right at one
|
||||
M_DetectComment(&tokenizerStartPos);
|
||||
|
||||
|
|
@ -2416,6 +2423,10 @@ const char *M_TokenizerRead(UINT32 i)
|
|||
|
||||
M_ReadTokenString(i);
|
||||
tokenizerEndPos++;
|
||||
|
||||
// Tell us the the token was a string.
|
||||
tokenizerIsString = true;
|
||||
|
||||
return tokenizerToken[i];
|
||||
}
|
||||
|
||||
|
|
@ -2451,6 +2462,11 @@ void M_TokenizerSetEndPos(UINT32 newPos)
|
|||
tokenizerEndPos = newPos;
|
||||
}
|
||||
|
||||
boolean M_TokenizerJustReadString(void)
|
||||
{
|
||||
return tokenizerIsString;
|
||||
}
|
||||
|
||||
/** Count bits in a number.
|
||||
*/
|
||||
UINT8 M_CountBits(UINT32 num, UINT8 size)
|
||||
|
|
|
|||
244
src/p_setup.c
244
src/p_setup.c
|
|
@ -103,6 +103,7 @@
|
|||
#include "doomstat.h" // MAXMUSNAMES
|
||||
#include "k_podium.h"
|
||||
#include "k_rank.h"
|
||||
#include "k_mapuser.h"
|
||||
|
||||
// Replay names have time
|
||||
#if !defined (UNDER_CE)
|
||||
|
|
@ -1388,6 +1389,82 @@ static boolean TextmapCount(size_t size)
|
|||
return true;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_NUM_TYPE_NA,
|
||||
PROP_NUM_TYPE_INT,
|
||||
PROP_NUM_TYPE_FLOAT
|
||||
};
|
||||
|
||||
static void ParseUserProperty(mapUserProperties_t *user, const char *param, const char *val)
|
||||
{
|
||||
if (fastncmp(param, "user_", 5) && strlen(param) > 5)
|
||||
{
|
||||
const boolean valIsString = M_TokenizerJustReadString();
|
||||
const char *key = param + 5;
|
||||
const size_t valLen = strlen(val);
|
||||
UINT8 numberType = PROP_NUM_TYPE_INT;
|
||||
size_t i = 0;
|
||||
|
||||
if (valIsString == true)
|
||||
{
|
||||
// Value is a string. Upload directly!
|
||||
K_UserPropertyPush(user, key, USER_PROP_STR, &val);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < valLen; i++)
|
||||
{
|
||||
if (val[i] == '.')
|
||||
{
|
||||
numberType = PROP_NUM_TYPE_FLOAT;
|
||||
}
|
||||
else if (val[i] < '0' || val[i] > '9')
|
||||
{
|
||||
numberType = PROP_NUM_TYPE_NA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (numberType)
|
||||
{
|
||||
case PROP_NUM_TYPE_INT:
|
||||
{
|
||||
// Value is an integer.
|
||||
INT32 vInt = atol(val);
|
||||
K_UserPropertyPush(user, key, USER_PROP_INT, &vInt);
|
||||
break;
|
||||
}
|
||||
case PROP_NUM_TYPE_FLOAT:
|
||||
{
|
||||
// Value is a float. Convert to fixed.
|
||||
fixed_t vFixed = FLOAT_TO_FIXED(atof(val));
|
||||
K_UserPropertyPush(user, key, USER_PROP_FIXED, &vFixed);
|
||||
break;
|
||||
}
|
||||
case PROP_NUM_TYPE_NA:
|
||||
default:
|
||||
{
|
||||
// Value is some other kind of type.
|
||||
// Currently we just support bool.
|
||||
|
||||
boolean vBool = fastcmp("true", val);
|
||||
if (vBool == true || fastcmp("false", val))
|
||||
{
|
||||
// Value is a boolean.
|
||||
K_UserPropertyPush(user, key, USER_PROP_BOOL, &vBool);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Value is invalid.
|
||||
CONS_Alert(CONS_WARNING, "Could not interpret user property \"%s\" value (%s)\n", param, val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ParseTextmapVertexParameter(UINT32 i, const char *param, const char *val)
|
||||
{
|
||||
if (fastcmp(param, "x"))
|
||||
|
|
@ -1657,6 +1734,8 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char
|
|||
sectors[i].activation |= SECSPAC_FLOORMISSILE;
|
||||
else if (fastcmp(param, "missileceiling") && fastcmp("true", val))
|
||||
sectors[i].activation |= SECSPAC_CEILINGMISSILE;
|
||||
else
|
||||
ParseUserProperty(§ors[i].user, param, val);
|
||||
}
|
||||
|
||||
static void ParseTextmapSidedefParameter(UINT32 i, const char *param, const char *val)
|
||||
|
|
@ -1675,6 +1754,8 @@ static void ParseTextmapSidedefParameter(UINT32 i, const char *param, const char
|
|||
P_SetSidedefSector(i, atol(val));
|
||||
else if (fastcmp(param, "repeatcnt"))
|
||||
sides[i].repeatcnt = atol(val);
|
||||
else
|
||||
ParseUserProperty(&sides[i].user, param, val);
|
||||
}
|
||||
|
||||
static void ParseTextmapLinedefParameter(UINT32 i, const char *param, const char *val)
|
||||
|
|
@ -1782,6 +1863,8 @@ static void ParseTextmapLinedefParameter(UINT32 i, const char *param, const char
|
|||
lines[i].activation |= SPAC_PUSHMONSTER;
|
||||
else if (fastcmp(param, "impact") && fastcmp("true", val))
|
||||
lines[i].activation |= SPAC_IMPACT;
|
||||
else
|
||||
ParseUserProperty(&lines[i].user, param, val);
|
||||
}
|
||||
|
||||
static void ParseTextmapThingParameter(UINT32 i, const char *param, const char *val)
|
||||
|
|
@ -1839,6 +1922,8 @@ static void ParseTextmapThingParameter(UINT32 i, const char *param, const char *
|
|||
return;
|
||||
mapthings[i].args[argnum] = atol(val);
|
||||
}
|
||||
else
|
||||
ParseUserProperty(&mapthings[i].user, param, val);
|
||||
}
|
||||
|
||||
/** From a given position table, run a specified parser function through a {}-encapsuled text.
|
||||
|
|
@ -1977,13 +2062,35 @@ static void P_WriteTextmap(void)
|
|||
memcpy(wsides, sides, numsides * sizeof(*sides));
|
||||
|
||||
for (i = 0; i < nummapthings; i++)
|
||||
{
|
||||
if (mapthings[i].tags.count)
|
||||
wmapthings[i].tags.tags = memcpy(Z_Malloc(mapthings[i].tags.count * sizeof(mtag_t), PU_LEVEL, NULL), mapthings[i].tags.tags, mapthings[i].tags.count * sizeof(mtag_t));
|
||||
|
||||
if (mapthings[i].user.length)
|
||||
{
|
||||
wmapthings[i].user.properties = memcpy(
|
||||
Z_Malloc(mapthings[i].user.length * sizeof(mapUserProperty_t), PU_LEVEL, NULL),
|
||||
mapthings[i].user.properties,
|
||||
mapthings[i].user.length * sizeof(mapUserProperty_t)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < numsectors; i++)
|
||||
{
|
||||
if (sectors[i].tags.count)
|
||||
wsectors[i].tags.tags = memcpy(Z_Malloc(sectors[i].tags.count*sizeof(mtag_t), PU_LEVEL, NULL), sectors[i].tags.tags, sectors[i].tags.count*sizeof(mtag_t));
|
||||
|
||||
if (sectors[i].user.length)
|
||||
{
|
||||
wsectors[i].user.properties = memcpy(
|
||||
Z_Malloc(sectors[i].user.length * sizeof(mapUserProperty_t), PU_LEVEL, NULL),
|
||||
sectors[i].user.properties,
|
||||
sectors[i].user.length * sizeof(mapUserProperty_t)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < numlines; i++)
|
||||
{
|
||||
size_t v;
|
||||
|
|
@ -1991,6 +2098,15 @@ static void P_WriteTextmap(void)
|
|||
if (lines[i].tags.count)
|
||||
wlines[i].tags.tags = memcpy(Z_Malloc(lines[i].tags.count * sizeof(mtag_t), PU_LEVEL, NULL), lines[i].tags.tags, lines[i].tags.count * sizeof(mtag_t));
|
||||
|
||||
if (lines[i].user.length)
|
||||
{
|
||||
wlines[i].user.properties = memcpy(
|
||||
Z_Malloc(lines[i].user.length * sizeof(mapUserProperty_t), PU_LEVEL, NULL),
|
||||
lines[i].user.properties,
|
||||
lines[i].user.length * sizeof(mapUserProperty_t)
|
||||
);
|
||||
}
|
||||
|
||||
v = lines[i].v1 - vertexes;
|
||||
wusedvertexes[v] = true;
|
||||
|
||||
|
|
@ -1998,6 +2114,18 @@ static void P_WriteTextmap(void)
|
|||
wusedvertexes[v] = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < numsides; i++)
|
||||
{
|
||||
if (sides[i].user.length)
|
||||
{
|
||||
wsides[i].user.properties = memcpy(
|
||||
Z_Malloc(sides[i].user.length * sizeof(mapUserProperty_t), PU_LEVEL, NULL),
|
||||
sides[i].user.properties,
|
||||
sides[i].user.length * sizeof(mapUserProperty_t)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
freetag = Tag_NextUnused(0);
|
||||
|
||||
for (i = 0; i < nummapthings; i++)
|
||||
|
|
@ -2279,6 +2407,28 @@ static void P_WriteTextmap(void)
|
|||
for (j = 0; j < NUMMAPTHINGSTRINGARGS; j++)
|
||||
if (mapthings[i].stringargs[j])
|
||||
fprintf(f, "stringarg%s = \"%s\";\n", sizeu1(j), mapthings[i].stringargs[j]);
|
||||
if (wmapthings[i].user.length > 0)
|
||||
{
|
||||
for (j = 0; j < wmapthings[i].user.length; j++)
|
||||
{
|
||||
mapUserProperty_t *const prop = &wmapthings[i].user.properties[j];
|
||||
switch (prop->type)
|
||||
{
|
||||
case USER_PROP_BOOL:
|
||||
fprintf(f, "user_%s = %s;\n", prop->key, (prop->valueBool == true) ? "true" : "false");
|
||||
break;
|
||||
case USER_PROP_INT:
|
||||
fprintf(f, "user_%s = %d;\n", prop->key, prop->valueInt);
|
||||
break;
|
||||
case USER_PROP_FIXED:
|
||||
fprintf(f, "user_%s = %f;\n", prop->key, FIXED_TO_FLOAT(prop->valueFixed));
|
||||
break;
|
||||
case USER_PROP_STR:
|
||||
fprintf(f, "user_%s = \"%s\";\n", prop->key, prop->valueStr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(f, "}\n");
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
|
@ -2405,6 +2555,28 @@ static void P_WriteTextmap(void)
|
|||
fprintf(f, "monsterpush = true;\n");
|
||||
if (wlines[i].activation & SPAC_IMPACT)
|
||||
fprintf(f, "impact = true;\n");
|
||||
if (wlines[i].user.length > 0)
|
||||
{
|
||||
for (j = 0; j < wlines[i].user.length; j++)
|
||||
{
|
||||
mapUserProperty_t *const prop = &wlines[i].user.properties[j];
|
||||
switch (prop->type)
|
||||
{
|
||||
case USER_PROP_BOOL:
|
||||
fprintf(f, "user_%s = %s;\n", prop->key, (prop->valueBool == true) ? "true" : "false");
|
||||
break;
|
||||
case USER_PROP_INT:
|
||||
fprintf(f, "user_%s = %d;\n", prop->key, prop->valueInt);
|
||||
break;
|
||||
case USER_PROP_FIXED:
|
||||
fprintf(f, "user_%s = %f;\n", prop->key, FIXED_TO_FLOAT(prop->valueFixed));
|
||||
break;
|
||||
case USER_PROP_STR:
|
||||
fprintf(f, "user_%s = \"%s\";\n", prop->key, prop->valueStr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(f, "}\n");
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
|
@ -2426,6 +2598,28 @@ static void P_WriteTextmap(void)
|
|||
fprintf(f, "texturemiddle = \"%.*s\";\n", 8, textures[wsides[i].midtexture]->name);
|
||||
if (wsides[i].repeatcnt != 0)
|
||||
fprintf(f, "repeatcnt = %d;\n", wsides[i].repeatcnt);
|
||||
if (wsides[i].user.length > 0)
|
||||
{
|
||||
for (j = 0; j < wsides[i].user.length; j++)
|
||||
{
|
||||
mapUserProperty_t *const prop = &wsides[i].user.properties[j];
|
||||
switch (prop->type)
|
||||
{
|
||||
case USER_PROP_BOOL:
|
||||
fprintf(f, "user_%s = %s;\n", prop->key, (prop->valueBool == true) ? "true" : "false");
|
||||
break;
|
||||
case USER_PROP_INT:
|
||||
fprintf(f, "user_%s = %d;\n", prop->key, prop->valueInt);
|
||||
break;
|
||||
case USER_PROP_FIXED:
|
||||
fprintf(f, "user_%s = %f;\n", prop->key, FIXED_TO_FLOAT(prop->valueFixed));
|
||||
break;
|
||||
case USER_PROP_STR:
|
||||
fprintf(f, "user_%s = \"%s\";\n", prop->key, prop->valueStr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(f, "}\n");
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
|
@ -2609,6 +2803,28 @@ static void P_WriteTextmap(void)
|
|||
fprintf(f, "missilefloor = true;\n");
|
||||
if (wsectors[i].activation & SECSPAC_CEILINGMISSILE)
|
||||
fprintf(f, "missileceiling = true;\n");
|
||||
if (wsectors[i].user.length > 0)
|
||||
{
|
||||
for (j = 0; j < wsectors[i].user.length; j++)
|
||||
{
|
||||
mapUserProperty_t *const prop = &wsectors[i].user.properties[j];
|
||||
switch (prop->type)
|
||||
{
|
||||
case USER_PROP_BOOL:
|
||||
fprintf(f, "user_%s = %s;\n", prop->key, (prop->valueBool == true) ? "true" : "false");
|
||||
break;
|
||||
case USER_PROP_INT:
|
||||
fprintf(f, "user_%s = %d;\n", prop->key, prop->valueInt);
|
||||
break;
|
||||
case USER_PROP_FIXED:
|
||||
fprintf(f, "user_%s = %f;\n", prop->key, FIXED_TO_FLOAT(prop->valueFixed));
|
||||
break;
|
||||
case USER_PROP_STR:
|
||||
fprintf(f, "user_%s = \"%s\";\n", prop->key, prop->valueStr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(f, "}\n");
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
|
@ -2616,17 +2832,38 @@ static void P_WriteTextmap(void)
|
|||
fclose(f);
|
||||
|
||||
for (i = 0; i < nummapthings; i++)
|
||||
{
|
||||
if (wmapthings[i].tags.count)
|
||||
Z_Free(wmapthings[i].tags.tags);
|
||||
|
||||
if (wmapthings[i].user.length)
|
||||
Z_Free(wmapthings[i].user.properties);
|
||||
}
|
||||
|
||||
for (i = 0; i < numsectors; i++)
|
||||
{
|
||||
if (wsectors[i].tags.count)
|
||||
Z_Free(wsectors[i].tags.tags);
|
||||
|
||||
if (wsectors[i].user.length)
|
||||
Z_Free(wsectors[i].user.properties);
|
||||
}
|
||||
|
||||
for (i = 0; i < numlines; i++)
|
||||
{
|
||||
if (wlines[i].tags.count)
|
||||
Z_Free(wlines[i].tags.tags);
|
||||
|
||||
if (wlines[i].user.length)
|
||||
Z_Free(wlines[i].user.properties);
|
||||
}
|
||||
|
||||
for (i = 0; i < numsides; i++)
|
||||
{
|
||||
if (wsides[i].user.length)
|
||||
Z_Free(wsides[i].user.properties);
|
||||
}
|
||||
|
||||
Z_Free(wmapthings);
|
||||
Z_Free(wvertexes);
|
||||
Z_Free(wsectors);
|
||||
|
|
@ -2709,6 +2946,8 @@ static void P_LoadTextmap(void)
|
|||
memset(sc->stringargs, 0x00, NUMSECTORSTRINGARGS*sizeof(*sc->stringargs));
|
||||
sc->activation = 0;
|
||||
|
||||
K_UserPropertiesClear(&sc->user);
|
||||
|
||||
textmap_colormap.used = false;
|
||||
textmap_colormap.lightcolor = 0;
|
||||
textmap_colormap.lightalpha = 25;
|
||||
|
|
@ -2762,6 +3001,7 @@ static void P_LoadTextmap(void)
|
|||
ld->sidenum[1] = 0xffff;
|
||||
|
||||
ld->activation = 0;
|
||||
K_UserPropertiesClear(&ld->user);
|
||||
|
||||
TextmapParse(linesPos[i], i, ParseTextmapLinedefParameter);
|
||||
|
||||
|
|
@ -2786,6 +3026,8 @@ static void P_LoadTextmap(void)
|
|||
sd->sector = NULL;
|
||||
sd->repeatcnt = 0;
|
||||
|
||||
K_UserPropertiesClear(&sd->user);
|
||||
|
||||
TextmapParse(sidesPos[i], i, ParseTextmapSidedefParameter);
|
||||
|
||||
if (!sd->sector)
|
||||
|
|
@ -2811,6 +3053,8 @@ static void P_LoadTextmap(void)
|
|||
mt->layer = 0;
|
||||
mt->mobj = NULL;
|
||||
|
||||
K_UserPropertiesClear(&mt->user);
|
||||
|
||||
TextmapParse(mapthingsPos[i], i, ParseTextmapThingParameter);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
11
src/r_defs.h
11
src/r_defs.h
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#include "taglist.h"
|
||||
|
||||
#include "k_mapuser.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
@ -551,6 +553,9 @@ struct sector_t
|
|||
INT32 args[NUMSECTORARGS];
|
||||
char *stringargs[NUMSECTORSTRINGARGS];
|
||||
sectoractionflags_t activation;
|
||||
|
||||
// UDMF user-defined custom properties.
|
||||
mapUserProperties_t user;
|
||||
};
|
||||
|
||||
//
|
||||
|
|
@ -609,6 +614,9 @@ struct line_t
|
|||
|
||||
char *text; // a concatenation of all front and back texture names, for linedef specials that require a string.
|
||||
INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0
|
||||
|
||||
// UDMF user-defined custom properties.
|
||||
mapUserProperties_t user;
|
||||
};
|
||||
|
||||
struct side_t
|
||||
|
|
@ -635,6 +643,9 @@ struct side_t
|
|||
char *text; // a concatenation of all top, bottom, and mid texture names, for linedef specials that require a string.
|
||||
|
||||
extracolormap_t *colormap_data; // storage for colormaps; not applied to sectors.
|
||||
|
||||
// UDMF user-defined custom properties.
|
||||
mapUserProperties_t user;
|
||||
};
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -217,6 +217,10 @@ TYPEDEF (gpRank_t);
|
|||
TYPEDEF (midVote_t);
|
||||
TYPEDEF (midVoteGUI_t);
|
||||
|
||||
// k_mapuser.h
|
||||
TYPEDEF (mapUserProperty_t);
|
||||
TYPEDEF (mapUserProperties_t);
|
||||
|
||||
// lua_hudlib_drawlist.h
|
||||
typedef struct huddrawlist_s *huddrawlist_h;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue