mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'custom-weather' into 'master'
Allow freesloting & editing precipprops See merge request KartKrew/Kart!612
This commit is contained in:
commit
6bc1d65442
18 changed files with 560 additions and 107 deletions
|
|
@ -186,6 +186,27 @@ static inline int lib_freeslot(lua_State *L)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (fastcmp(type, "PRECIP"))
|
||||
{
|
||||
// Search if we already have a PRECIP by that name...
|
||||
preciptype_t i;
|
||||
for (i = PRECIP_FIRSTFREESLOT; i < precip_freeslot; i++)
|
||||
if (fastcmp(word, precipprops[i].name))
|
||||
break;
|
||||
|
||||
// We don't, so allocate a new one.
|
||||
if (i >= precip_freeslot) {
|
||||
if (precip_freeslot < MAXPRECIP)
|
||||
{
|
||||
CONS_Printf("Weather PRECIP_%s allocated.\n",word);
|
||||
precipprops[i].name = Z_StrDup(word);
|
||||
lua_pushinteger(L, precip_freeslot);
|
||||
r++;
|
||||
precip_freeslot++;
|
||||
} else
|
||||
CONS_Alert(CONS_WARNING, "Ran out of free PRECIP slots!\n");
|
||||
}
|
||||
}
|
||||
Z_Free(s);
|
||||
lua_remove(L, 1);
|
||||
continue;
|
||||
|
|
@ -475,6 +496,21 @@ static inline int lib_getenum(lua_State *L)
|
|||
if (mathlib) return luaL_error(L, "menutype '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("PRECIP_",word,7)) {
|
||||
p = word+7;
|
||||
for (i = 0; i < MAXPRECIP; i++)
|
||||
{
|
||||
if (precipprops[i].name == NULL)
|
||||
break;
|
||||
|
||||
if (fastcmp(p, precipprops[i].name))
|
||||
{
|
||||
lua_pushinteger(L, PRECIP_NONE + i);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return luaL_error(L, "weather type '%s' does not exist.\n", word);
|
||||
}
|
||||
else if (!mathlib && fastncmp("A_",word,2)) {
|
||||
char *caps;
|
||||
// Try to get a Lua action first.
|
||||
|
|
|
|||
|
|
@ -481,6 +481,25 @@ void readfreeslots(MYFILE *f)
|
|||
lastcustomtol <<= 1;
|
||||
}
|
||||
}
|
||||
else if (fastcmp(type, "PRECIP"))
|
||||
{
|
||||
// Search if we already have a PRECIP by that name...
|
||||
for (i = PRECIP_FIRSTFREESLOT; i < (int)precip_freeslot; i++)
|
||||
if (fastcmp(word, precipprops[i].name))
|
||||
break;
|
||||
|
||||
// We found it? Then don't allocate another one.
|
||||
if (i < (int)precip_freeslot)
|
||||
continue;
|
||||
|
||||
// We don't, so allocate a new one.
|
||||
if (precip_freeslot < MAXPRECIP)
|
||||
{
|
||||
precipprops[i].name = Z_StrDup(word);
|
||||
precip_freeslot++;
|
||||
} else
|
||||
deh_warning("Ran out of free PRECIP slots!\n");
|
||||
}
|
||||
else
|
||||
deh_warning("Freeslots: unknown enum class '%s' for '%s_%s'", type, type, word);
|
||||
}
|
||||
|
|
@ -1528,7 +1547,7 @@ void readlevelheader(MYFILE *f, INT32 num)
|
|||
strlwr(mapheaderinfo[num-1]->forcecharacter); // skin names are lowercase
|
||||
}
|
||||
else if (fastcmp(word, "WEATHER"))
|
||||
mapheaderinfo[num-1]->weather = (UINT8)get_number(word2);
|
||||
mapheaderinfo[num-1]->weather = get_precip(word2);
|
||||
else if (fastcmp(word, "SKYTEXTURE"))
|
||||
deh_strlcpy(mapheaderinfo[num-1]->skytexture, word2,
|
||||
sizeof(mapheaderinfo[num-1]->skytexture), va("Level header %d: sky texture", num));
|
||||
|
|
@ -4086,6 +4105,61 @@ if (!followers[numfollowers].field) \
|
|||
Z_Free(s);
|
||||
}
|
||||
|
||||
void readweather(MYFILE *f, INT32 num)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
char *word;
|
||||
char *word2;
|
||||
char *tmp;
|
||||
|
||||
do
|
||||
{
|
||||
if (myfgets(s, MAXLINELEN, f))
|
||||
{
|
||||
if (s[0] == '\n')
|
||||
break;
|
||||
|
||||
// First remove trailing newline, if there is one
|
||||
tmp = strchr(s, '\n');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
|
||||
tmp = strchr(s, '#');
|
||||
if (tmp)
|
||||
*tmp = '\0';
|
||||
if (s == tmp)
|
||||
continue; // Skip comment lines, but don't break.
|
||||
|
||||
// Set / reset word
|
||||
word = s;
|
||||
|
||||
// Get the part before the " = "
|
||||
tmp = strchr(s, '=');
|
||||
if (tmp)
|
||||
*(tmp-1) = '\0';
|
||||
else
|
||||
break;
|
||||
strupr(word);
|
||||
|
||||
// Now get the part after
|
||||
word2 = tmp += 2;
|
||||
|
||||
if (fastcmp(word, "TYPE"))
|
||||
{
|
||||
precipprops[num].type = get_mobjtype(word2);
|
||||
}
|
||||
else if (fastcmp(word, "EFFECTS"))
|
||||
{
|
||||
precipprops[num].effects = get_number(word2);
|
||||
}
|
||||
else
|
||||
deh_warning("Weather %d : unknown word '%s'", num, word);
|
||||
}
|
||||
} while (!myfeof(f));
|
||||
|
||||
Z_Free(s);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
|
@ -4222,6 +4296,24 @@ menutype_t get_menutype(const char *word)
|
|||
return GT_COOP;
|
||||
}*/
|
||||
|
||||
preciptype_t get_precip(const char *word)
|
||||
{ // Returns the value of PRECIP_ enumerations
|
||||
preciptype_t i;
|
||||
if (*word >= '0' && *word <= '9')
|
||||
return atoi(word);
|
||||
if (fastncmp("PRECIP_",word,4))
|
||||
word += 7; // take off the PRECIP_
|
||||
for (i = 0; i < MAXPRECIP; i++)
|
||||
{
|
||||
if (precipprops[i].name == NULL)
|
||||
break;
|
||||
if (fasticmp(word, precipprops[i].name))
|
||||
return i;
|
||||
}
|
||||
deh_warning("Couldn't find weather type named 'PRECIP_%s'",word);
|
||||
return PRECIP_RAIN;
|
||||
}
|
||||
|
||||
/// \todo Make ANY of this completely over-the-top math craziness obey the order of operations.
|
||||
static fixed_t op_mul(fixed_t a, fixed_t b) { return a*b; }
|
||||
static fixed_t op_div(fixed_t a, fixed_t b) { return a/b; }
|
||||
|
|
|
|||
|
|
@ -85,5 +85,7 @@ void clear_conditionsets(void);
|
|||
|
||||
void readcupheader(MYFILE *f, cupheader_t *cup);
|
||||
void readfollower(MYFILE *f);
|
||||
preciptype_t get_precip(const char *word);
|
||||
void readweather(MYFILE *f, INT32 num);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -6741,6 +6741,11 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"SPOT_WEAK",SPOT_WEAK},
|
||||
{"SPOT_BUMP",SPOT_BUMP},
|
||||
|
||||
// precipeffect_t
|
||||
{"PRECIPFX_THUNDER",PRECIPFX_THUNDER},
|
||||
{"PRECIPFX_LIGHTNING",PRECIPFX_LIGHTNING},
|
||||
{"PRECIPFX_WATERPARTICLES",PRECIPFX_WATERPARTICLES},
|
||||
|
||||
{NULL,0}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -576,6 +576,18 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
|
|||
|
||||
readcupheader(f, cup);
|
||||
}
|
||||
else if (fastcmp(word, "WEATHER") || fastcmp(word, "PRECIP") || fastcmp(word, "PRECIPITATION"))
|
||||
{
|
||||
if (i == 0 && word2[0] != '0') // If word2 isn't a number
|
||||
i = get_precip(word2); // find a weather type by name
|
||||
if (i < MAXPRECIP && i > 0)
|
||||
readweather(f, i);
|
||||
else
|
||||
{
|
||||
deh_warning("Weather number %d out of range (1 - %d)", i, MAXPRECIP-1);
|
||||
ignorelines(f);
|
||||
}
|
||||
}
|
||||
else if (fastcmp(word, "RINGRACERS"))
|
||||
{
|
||||
if (isdigit(word2[0]))
|
||||
|
|
|
|||
|
|
@ -41,8 +41,7 @@ extern UINT32 mapmusresume;
|
|||
// Use other bits if necessary.
|
||||
|
||||
extern UINT32 maptol;
|
||||
extern UINT8 globalweather;
|
||||
extern UINT8 curWeather;
|
||||
|
||||
extern INT32 cursaveslot;
|
||||
//extern INT16 lastmapsaved;
|
||||
extern INT16 lastmaploaded;
|
||||
|
|
@ -64,31 +63,44 @@ extern tic_t marathontime;
|
|||
extern UINT8 numgameovers;
|
||||
extern SINT8 startinglivesbalance[maxgameovers+1];
|
||||
|
||||
#define NUMPRECIPFREESLOTS 64
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PRECIP_NONE = 0,
|
||||
|
||||
PRECIP_RAIN,
|
||||
PRECIP_SNOW,
|
||||
PRECIP_BLIZZARD,
|
||||
PRECIP_STORM,
|
||||
PRECIP_STORM_NORAIN,
|
||||
PRECIP_STORM_NOSTRIKES,
|
||||
|
||||
PRECIP_FIRSTFREESLOT,
|
||||
PRECIP_LASTFREESLOT = PRECIP_FIRSTFREESLOT + NUMPRECIPFREESLOTS - 1,
|
||||
|
||||
MAXPRECIP
|
||||
} preciptype_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PRECIPFX_THUNDER = 1,
|
||||
PRECIPFX_LIGHTNING = 1<<1
|
||||
PRECIPFX_LIGHTNING = 1<<1,
|
||||
PRECIPFX_WATERPARTICLES = 1<<2
|
||||
} precipeffect_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
mobjtype_t type;
|
||||
precipeffect_t effects;
|
||||
} precipprops_t;
|
||||
|
||||
extern precipprops_t precipprops[MAXPRECIP];
|
||||
extern preciptype_t precip_freeslot;
|
||||
|
||||
extern preciptype_t globalweather;
|
||||
extern preciptype_t curWeather;
|
||||
|
||||
// Set if homebrew PWAD stuff has been added.
|
||||
extern boolean modifiedgame;
|
||||
|
|
|
|||
20
src/g_game.c
20
src/g_game.c
|
|
@ -93,20 +93,22 @@ UINT32 mapmusresume;
|
|||
INT16 gamemap = 1;
|
||||
UINT32 maptol;
|
||||
|
||||
UINT8 globalweather = PRECIP_NONE;
|
||||
UINT8 curWeather = PRECIP_NONE;
|
||||
preciptype_t globalweather = PRECIP_NONE;
|
||||
preciptype_t curWeather = PRECIP_NONE;
|
||||
|
||||
precipprops_t precipprops[MAXPRECIP] =
|
||||
{
|
||||
{MT_NULL, 0}, // PRECIP_NONE
|
||||
{MT_RAIN, 0}, // PRECIP_RAIN
|
||||
{MT_SNOWFLAKE, 0}, // PRECIP_SNOW
|
||||
{MT_BLIZZARDSNOW, 0}, // PRECIP_BLIZZARD
|
||||
{MT_RAIN, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING}, // PRECIP_STORM
|
||||
{MT_NULL, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING}, // PRECIP_STORM_NORAIN
|
||||
{MT_RAIN, PRECIPFX_THUNDER} // PRECIP_STORM_NOSTRIKES
|
||||
{"NONE", MT_NULL, 0}, // PRECIP_NONE
|
||||
{"RAIN", MT_RAIN, 0}, // PRECIP_RAIN
|
||||
{"SNOW", MT_SNOWFLAKE, 0}, // PRECIP_SNOW
|
||||
{"BLIZZARD", MT_BLIZZARDSNOW, 0}, // PRECIP_BLIZZARD
|
||||
{"STORM", MT_RAIN, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING}, // PRECIP_STORM
|
||||
{"STORM_NORAIN", MT_NULL, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING}, // PRECIP_STORM_NORAIN
|
||||
{"STORM_NOSTRIKES", MT_RAIN, PRECIPFX_THUNDER} // PRECIP_STORM_NOSTRIKES
|
||||
};
|
||||
|
||||
preciptype_t precip_freeslot = PRECIP_FIRSTFREESLOT;
|
||||
|
||||
INT32 cursaveslot = 0; // Auto-save 1p savegame slot
|
||||
//INT16 lastmapsaved = 0; // Last map we auto-saved at
|
||||
INT16 lastmaploaded = 0; // Last map the game loaded
|
||||
|
|
|
|||
|
|
@ -18246,7 +18246,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_SPLASH1, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
-72*FRACUNIT, // speed
|
||||
72*FRACUNIT, // speed
|
||||
1*FRACUNIT, // radius
|
||||
8*FRACUNIT, // height
|
||||
0, // display offset
|
||||
|
|
@ -18273,7 +18273,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
-2*FRACUNIT, // speed
|
||||
2*FRACUNIT, // speed
|
||||
4*FRACUNIT, // radius
|
||||
4*FRACUNIT, // height
|
||||
0, // display offset
|
||||
|
|
@ -18300,7 +18300,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
S_NULL, // deathstate
|
||||
S_NULL, // xdeathstate
|
||||
sfx_None, // deathsound
|
||||
-24*FRACUNIT, // speed
|
||||
24*FRACUNIT, // speed
|
||||
4*FRACUNIT, // radius
|
||||
4*FRACUNIT, // height
|
||||
0, // display offset
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ static const struct {
|
|||
{META_SPRITEINFO, "spriteinfo_t"},
|
||||
{META_PIVOTLIST, "spriteframepivot_t[]"},
|
||||
{META_FRAMEPIVOT, "spriteframepivot_t"},
|
||||
{META_PRECIPPROPS, "precipprops_t"},
|
||||
|
||||
{META_TAGLIST, "taglist"},
|
||||
|
||||
|
|
|
|||
|
|
@ -1758,6 +1758,151 @@ static int colorramp_len(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// PRECIP PROPS //
|
||||
//////////////////
|
||||
|
||||
// Arbitrary precipprops[] table index -> precipprops_t *
|
||||
static int lib_getPrecipProps(lua_State *L)
|
||||
{
|
||||
INT32 i;
|
||||
lua_remove(L, 1);
|
||||
|
||||
i = luaL_checkinteger(L, 1);
|
||||
if (i <= 0 || i >= MAXPRECIP)
|
||||
return luaL_error(L, "precipprops[] index %d out of range (1 - %d)", i, MAXPRECIP-1);
|
||||
LUA_PushUserdata(L, &precipprops[i], META_PRECIPPROPS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Lua table full of data -> precipprops[]
|
||||
static int lib_setPrecipProps(lua_State *L)
|
||||
{
|
||||
precipprops_t *props;
|
||||
lua_remove(L, 1); // don't care about precipprops[] userdata.
|
||||
{
|
||||
INT32 i = luaL_checkinteger(L, 1);
|
||||
if (i <= 0 || i >= MAXPRECIP)
|
||||
return luaL_error(L, "precipprops[] index %d out of range (1 - %d)", i, MAXPRECIP-1);
|
||||
props = &precipprops[i]; // get the precipprops to assign to.
|
||||
}
|
||||
|
||||
luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table.
|
||||
lua_remove(L, 1); // pop preciptype num, don't need it any more.
|
||||
lua_settop(L, 1); // cut the stack here. the only thing left now is the table of data we're assigning to the precipprops.
|
||||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter precipprops in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter precipprops in CMD building code!");
|
||||
|
||||
// clear the precipprops to start with, in case of missing table elements
|
||||
// make sure we do not clear the name
|
||||
memset(props + sizeof(props->name), 0, sizeof(precipprops_t) - sizeof(props->name));
|
||||
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 1)) {
|
||||
lua_Integer i = 0;
|
||||
const char *str = NULL;
|
||||
lua_Integer value;
|
||||
|
||||
if (lua_isnumber(L, 2))
|
||||
i = lua_tointeger(L, 2);
|
||||
else
|
||||
str = luaL_checkstring(L, 2);
|
||||
|
||||
if (i == 1 || (str && fastcmp(str, "type")))
|
||||
{
|
||||
value = luaL_checkinteger(L, 3);
|
||||
if (value < MT_NULL || value >= NUMMOBJTYPES)
|
||||
return luaL_error(L, "type number %d is invalid.", value);
|
||||
props->type = luaL_checkinteger(L, 3);
|
||||
}
|
||||
else if (i == 2 || (str && fastcmp(str, "effects")))
|
||||
{
|
||||
props->effects = luaL_checkinteger(L, 3);
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// #precipprops -> MAXPRECIP
|
||||
static int lib_precippropslen(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, MAXPRECIP);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// precipprops_t *, field -> number
|
||||
static int precipprops_get(lua_State *L)
|
||||
{
|
||||
precipprops_t *props = *((precipprops_t **)luaL_checkudata(L, 1, META_PRECIPPROPS));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
|
||||
I_Assert(props != NULL);
|
||||
I_Assert(props >= precipprops);
|
||||
|
||||
if (fastcmp(field, "type"))
|
||||
{
|
||||
lua_pushinteger(L, props->type);
|
||||
}
|
||||
else if (fastcmp(field,"effects"))
|
||||
{
|
||||
lua_pushinteger(L, props->effects);
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "precipprops_t", field);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// precipprops_t *, field, number -> precipprops[]
|
||||
static int precipprops_set(lua_State *L)
|
||||
{
|
||||
precipprops_t *props = *((precipprops_t **)luaL_checkudata(L, 1, META_PRECIPPROPS));
|
||||
const char *field = luaL_checkstring(L, 2);
|
||||
|
||||
if (hud_running)
|
||||
return luaL_error(L, "Do not alter precipprops in HUD rendering code!");
|
||||
if (hook_cmd_running)
|
||||
return luaL_error(L, "Do not alter precipprops in CMD building code!");
|
||||
|
||||
I_Assert(props != NULL);
|
||||
I_Assert(props >= precipprops);
|
||||
|
||||
if (fastcmp(field, "type"))
|
||||
{
|
||||
props->type = luaL_checkinteger(L, 3);
|
||||
}
|
||||
else if (fastcmp(field, "effects"))
|
||||
{
|
||||
props->effects = luaL_checkinteger(L, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
return luaL_error(L, LUA_QL("precipprops_t") " has no field named " LUA_QS, field);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// precipprops_t * -> PRECIP_*
|
||||
static int precipprops_num(lua_State *L)
|
||||
{
|
||||
precipprops_t *props = *((precipprops_t **)luaL_checkudata(L, 1, META_PRECIPPROPS));
|
||||
|
||||
I_Assert(props != NULL);
|
||||
I_Assert(props >= precipprops);
|
||||
|
||||
lua_pushinteger(L, props - precipprops);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
//
|
||||
// Now push all these functions into the Lua state!
|
||||
|
|
@ -1861,6 +2006,17 @@ int LUA_InfoLib(lua_State *L)
|
|||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_PRECIPPROPS);
|
||||
lua_pushcfunction(L, precipprops_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, precipprops_set);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
|
||||
lua_pushcfunction(L, precipprops_num);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getSprname);
|
||||
|
|
@ -1961,6 +2117,19 @@ int LUA_InfoLib(lua_State *L)
|
|||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "spriteinfo");
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getPrecipProps);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, lib_setPrecipProps);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
|
||||
lua_pushcfunction(L, lib_precippropslen);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "precipprops");
|
||||
|
||||
luaL_newmetatable(L, META_LUABANKS);
|
||||
lua_pushcfunction(L, lib_getluabanks);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ extern lua_State *gL;
|
|||
#define META_SPRITEINFO "SPRITEINFO_T*"
|
||||
#define META_PIVOTLIST "SPRITEFRAMEPIVOT_T[]"
|
||||
#define META_FRAMEPIVOT "SPRITEFRAMEPIVOT_T*"
|
||||
#define META_PRECIPPROPS "PRECIPPROPS_T*"
|
||||
|
||||
#define META_TAGLIST "TAGLIST"
|
||||
|
||||
|
|
|
|||
|
|
@ -277,6 +277,7 @@ void P_RespawnSpecials(void);
|
|||
|
||||
mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type);
|
||||
|
||||
void P_CalculatePrecipFloor(precipmobj_t *mobj);
|
||||
void P_RecalcPrecipInSector(sector_t *sector);
|
||||
void P_PrecipitationEffects(void);
|
||||
|
||||
|
|
|
|||
152
src/p_mobj.c
152
src/p_mobj.c
|
|
@ -3760,19 +3760,25 @@ animonly:
|
|||
P_CyclePlayerMobjState(mobj);
|
||||
}
|
||||
|
||||
static void CalculatePrecipFloor(precipmobj_t *mobj)
|
||||
void P_CalculatePrecipFloor(precipmobj_t *mobj)
|
||||
{
|
||||
// recalculate floorz each time
|
||||
const sector_t *mobjsecsubsec;
|
||||
boolean setWater = false;
|
||||
|
||||
if (mobj && mobj->subsector && mobj->subsector->sector)
|
||||
mobjsecsubsec = mobj->subsector->sector;
|
||||
else
|
||||
return;
|
||||
|
||||
mobj->precipflags &= ~PCF_INVISIBLE;
|
||||
mobj->floorz = P_GetSectorFloorZAt(mobjsecsubsec, mobj->x, mobj->y);
|
||||
mobj->ceilingz = P_GetSectorCeilingZAt(mobjsecsubsec, mobj->x, mobj->y);
|
||||
|
||||
if (mobjsecsubsec->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
fixed_t topheight;
|
||||
fixed_t height;
|
||||
|
||||
for (rover = mobjsecsubsec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
|
|
@ -3780,16 +3786,46 @@ static void CalculatePrecipFloor(precipmobj_t *mobj)
|
|||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
|
||||
if (precipprops[curWeather].effects & PRECIPFX_WATERPARTICLES)
|
||||
{
|
||||
if (!(rover->flags & FF_SWIMMABLE))
|
||||
continue;
|
||||
|
||||
if (setWater == false)
|
||||
{
|
||||
mobj->ceilingz = P_GetFFloorTopZAt(rover, mobj->x, mobj->y);
|
||||
mobj->floorz = P_GetFFloorBottomZAt(rover, mobj->x, mobj->y);
|
||||
setWater = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
height = P_GetFFloorTopZAt(rover, mobj->x, mobj->y);
|
||||
if (height > mobj->ceilingz)
|
||||
mobj->ceilingz = height;
|
||||
|
||||
height = P_GetFFloorBottomZAt(rover, mobj->x, mobj->y);
|
||||
if (height < mobj->floorz)
|
||||
mobj->floorz = height;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(rover->flags & FF_BLOCKOTHERS) && !(rover->flags & FF_SWIMMABLE))
|
||||
continue;
|
||||
|
||||
topheight = P_GetFFloorTopZAt(rover, mobj->x, mobj->y);
|
||||
if (topheight > mobj->floorz)
|
||||
mobj->floorz = topheight;
|
||||
height = P_GetFFloorTopZAt(rover, mobj->x, mobj->y);
|
||||
if (height > mobj->floorz)
|
||||
mobj->floorz = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((precipprops[curWeather].effects & PRECIPFX_WATERPARTICLES) && setWater == false)
|
||||
{
|
||||
mobj->precipflags |= PCF_INVISIBLE;
|
||||
}
|
||||
}
|
||||
|
||||
void P_RecalcPrecipInSector(sector_t *sector)
|
||||
{
|
||||
mprecipsecnode_t *psecnode;
|
||||
|
|
@ -3800,7 +3836,7 @@ void P_RecalcPrecipInSector(sector_t *sector)
|
|||
sector->moved = true; // Recalc lighting and things too, maybe
|
||||
|
||||
for (psecnode = sector->touching_preciplist; psecnode; psecnode = psecnode->m_thinglist_next)
|
||||
CalculatePrecipFloor(psecnode->m_thing);
|
||||
P_CalculatePrecipFloor(psecnode->m_thing);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -3812,11 +3848,12 @@ void P_NullPrecipThinker(precipmobj_t *mobj)
|
|||
{
|
||||
//(void)mobj;
|
||||
mobj->precipflags &= ~PCF_THUNK;
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
}
|
||||
|
||||
void P_PrecipThinker(precipmobj_t *mobj)
|
||||
{
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
boolean flip = (mobj->precipflags & PCF_FLIP);
|
||||
|
||||
P_CycleStateAnimation((mobj_t *)mobj);
|
||||
|
||||
|
|
@ -3824,9 +3861,10 @@ void P_PrecipThinker(precipmobj_t *mobj)
|
|||
{
|
||||
// Reset to ceiling!
|
||||
P_SetPrecipMobjState(mobj, mobj->info->spawnstate);
|
||||
mobj->z = mobj->ceilingz;
|
||||
mobj->momz = mobj->info->speed;
|
||||
mobj->z = (flip) ? (mobj->floorz) : (mobj->ceilingz);
|
||||
mobj->momz = -mobj->info->speed;
|
||||
mobj->precipflags &= ~PCF_SPLASH;
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
}
|
||||
|
||||
if (mobj->tics != -1)
|
||||
|
|
@ -3858,18 +3896,20 @@ void P_PrecipThinker(precipmobj_t *mobj)
|
|||
if (mobj->precipflags & PCF_SPLASH)
|
||||
return;
|
||||
|
||||
mobj->z += mobj->momz;
|
||||
|
||||
// adjust height
|
||||
if ((mobj->z += mobj->momz) <= mobj->floorz)
|
||||
if ((flip) ? (mobj->z >= mobj->ceilingz) : (mobj->z <= mobj->floorz))
|
||||
{
|
||||
if ((mobj->info->deathstate == S_NULL) || (mobj->precipflags & PCF_PIT)) // no splashes on sky or bottomless pits
|
||||
{
|
||||
mobj->z = mobj->ceilingz;
|
||||
mobj->z = (flip) ? (mobj->floorz) : (mobj->ceilingz);
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
}
|
||||
else
|
||||
{
|
||||
P_SetPrecipMobjState(mobj, mobj->info->deathstate);
|
||||
mobj->z = mobj->floorz;
|
||||
mobj->z = (flip) ? (mobj->ceilingz) : (mobj->floorz);
|
||||
mobj->precipflags |= PCF_SPLASH;
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
}
|
||||
|
|
@ -10341,8 +10381,8 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
|
|||
{
|
||||
const mobjinfo_t *info = &mobjinfo[type];
|
||||
state_t *st;
|
||||
fixed_t start_z = INT32_MIN;
|
||||
precipmobj_t *mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
|
||||
fixed_t starting_floorz;
|
||||
|
||||
mobj->type = type;
|
||||
mobj->info = info;
|
||||
|
|
@ -10364,26 +10404,43 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
|
|||
// set subsector and/or block links
|
||||
P_SetPrecipitationThingPosition(mobj);
|
||||
|
||||
mobj->floorz = starting_floorz = P_GetSectorFloorZAt (mobj->subsector->sector, x, y);
|
||||
mobj->floorz = P_GetSectorFloorZAt (mobj->subsector->sector, x, y);
|
||||
mobj->ceilingz = P_GetSectorCeilingZAt(mobj->subsector->sector, x, y);
|
||||
|
||||
mobj->floorrover = NULL;
|
||||
mobj->ceilingrover = NULL;
|
||||
|
||||
mobj->z = z;
|
||||
mobj->momz = info->speed;
|
||||
mobj->momz = -info->speed;
|
||||
|
||||
if (info->speed < 0)
|
||||
{
|
||||
mobj->precipflags |= PCF_FLIP;
|
||||
}
|
||||
|
||||
start_z = mobj->floorz;
|
||||
|
||||
mobj->thinker.function.acp1 = (actionf_p1)P_NullPrecipThinker;
|
||||
P_AddThinker(THINK_PRECIP, &mobj->thinker);
|
||||
|
||||
CalculatePrecipFloor(mobj);
|
||||
P_CalculatePrecipFloor(mobj);
|
||||
|
||||
if (mobj->floorz != starting_floorz)
|
||||
mobj->precipflags |= PCF_FOF;
|
||||
else if (GETSECSPECIAL(mobj->subsector->sector->special, 1) == 7
|
||||
|| GETSECSPECIAL(mobj->subsector->sector->special, 1) == 6
|
||||
|| mobj->subsector->sector->floorpic == skyflatnum)
|
||||
if (mobj->floorz != start_z)
|
||||
{
|
||||
; //mobj->precipflags |= PCF_FOF;
|
||||
}
|
||||
else
|
||||
{
|
||||
INT32 special = GETSECSPECIAL(mobj->subsector->sector->special, 1);
|
||||
boolean sFlag = (mobj->precipflags & PCF_FLIP) ? (mobj->subsector->sector->flags & SF_FLIPSPECIAL_CEILING) : (mobj->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR);
|
||||
boolean pitFloor = ((special == 6 || special == 7) && sFlag);
|
||||
boolean skyFloor = (mobj->precipflags & PCF_FLIP) ? (mobj->subsector->sector->ceilingpic == skyflatnum) : (mobj->subsector->sector->floorpic == skyflatnum);
|
||||
|
||||
if (pitFloor || skyFloor)
|
||||
{
|
||||
mobj->precipflags |= PCF_PIT;
|
||||
}
|
||||
}
|
||||
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
|
||||
|
|
@ -10588,13 +10645,19 @@ consvar_t cv_itemrespawn = CVAR_INIT ("respawnitem", "On", CV_NETVAR, CV_OnOff,
|
|||
void P_SpawnPrecipitation(void)
|
||||
{
|
||||
INT32 i, j, k;
|
||||
mobjtype_t type = precipprops[curWeather].type;
|
||||
UINT8 randomstates = (UINT8)mobjinfo[type].damage;
|
||||
|
||||
const mobjtype_t type = precipprops[curWeather].type;
|
||||
const UINT8 randomstates = (UINT8)mobjinfo[type].damage;
|
||||
const boolean flip = (mobjinfo[type].speed < 0);
|
||||
|
||||
fixed_t basex, basey, x, y, z, height;
|
||||
UINT16 numparticles = 0;
|
||||
boolean condition = false;
|
||||
|
||||
subsector_t *precipsector = NULL;
|
||||
precipmobj_t *rainmo = NULL;
|
||||
|
||||
if (dedicated || !cv_drawdist_precip.value || curWeather == PRECIP_NONE) // SRB2Kart
|
||||
if (dedicated || !cv_drawdist_precip.value || type == MT_NULL)
|
||||
return;
|
||||
|
||||
// Use the blockmap to narrow down our placing patterns
|
||||
|
|
@ -10603,9 +10666,6 @@ void P_SpawnPrecipitation(void)
|
|||
basex = bmaporgx + (i % bmapwidth) * MAPBLOCKSIZE;
|
||||
basey = bmaporgy + (i / bmapwidth) * MAPBLOCKSIZE;
|
||||
|
||||
{
|
||||
UINT16 numparticles = 0;
|
||||
|
||||
x = basex + ((M_RandomKey(MAPBLOCKUNITS << 3) << FRACBITS) >> 3);
|
||||
y = basey + ((M_RandomKey(MAPBLOCKUNITS << 3) << FRACBITS) >> 3);
|
||||
|
||||
|
|
@ -10617,9 +10677,42 @@ void P_SpawnPrecipitation(void)
|
|||
continue;
|
||||
|
||||
// Not in a sector with visible sky?
|
||||
if (precipsector->sector->ceilingpic != skyflatnum)
|
||||
if (precipprops[curWeather].effects & PRECIPFX_WATERPARTICLES)
|
||||
{
|
||||
condition = false;
|
||||
|
||||
if (precipsector->sector->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
|
||||
for (rover = precipsector->sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
|
||||
if (!(rover->flags & FF_SWIMMABLE))
|
||||
continue;
|
||||
|
||||
condition = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
condition = (precipsector->sector->ceilingpic == skyflatnum);
|
||||
}
|
||||
|
||||
if (precipsector->sector->flags & SF_INVERTPRECIP)
|
||||
{
|
||||
condition = !condition;
|
||||
}
|
||||
|
||||
if (!condition)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
height = precipsector->sector->ceilingheight - precipsector->sector->floorheight;
|
||||
|
||||
// Exists, but is too small for reasonable precipitation.
|
||||
|
|
@ -10630,7 +10723,7 @@ void P_SpawnPrecipitation(void)
|
|||
numparticles = 1 + (height / (MAPBLOCKUNITS<<4<<FRACBITS));
|
||||
|
||||
// Don't set z properly yet...
|
||||
z = precipsector->sector->ceilingheight;
|
||||
z = (flip) ? (precipsector->sector->floorheight) : (precipsector->sector->ceilingheight);
|
||||
|
||||
for (j = 0; j < numparticles; j++)
|
||||
{
|
||||
|
|
@ -10657,7 +10750,6 @@ void P_SpawnPrecipitation(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_PrecipitationEffects
|
||||
|
|
|
|||
15
src/p_mobj.h
15
src/p_mobj.h
|
|
@ -262,12 +262,11 @@ typedef enum
|
|||
// PRECIPITATION flags ?! ?! ?!
|
||||
//
|
||||
typedef enum {
|
||||
PCF_INVISIBLE = 1, // Don't draw.
|
||||
PCF_PIT = 1<<1, // Above pit.
|
||||
PCF_FOF = 1<<2, // Above FOF.
|
||||
PCF_MOVINGFOF = 1<<3, // Above MOVING FOF (this means we need to keep floorz up to date...)
|
||||
PCF_SPLASH = 1<<4, // Splashed on the ground, return to the ceiling after the animation's over
|
||||
PCF_THUNK = 1<<5, // Ran the thinker this tic.
|
||||
PCF_THUNK = 1, // Ran the thinker this tic.
|
||||
PCF_SPLASH = 1<<1, // Splashed on the ground, return to the ceiling after the animation's over
|
||||
PCF_INVISIBLE = 1<<2, // Don't draw.
|
||||
PCF_PIT = 1<<3, // Above pit.
|
||||
PCF_FLIP = 1<<4, // Spawning from floor, moving upwards.
|
||||
} precipflag_t;
|
||||
|
||||
// Map Object definition.
|
||||
|
|
@ -462,6 +461,8 @@ typedef struct precipmobj_s
|
|||
fixed_t ceilingz; // Nearest ceiling above.
|
||||
struct ffloor_s *floorrover; // FOF referred by floorz
|
||||
struct ffloor_s *ceilingrover; // FOF referred by ceilingz
|
||||
fixed_t floordrop;
|
||||
fixed_t ceilingdrop;
|
||||
|
||||
// For movement checking.
|
||||
fixed_t radius; // Fixed at 2*FRACUNIT
|
||||
|
|
@ -473,7 +474,7 @@ typedef struct precipmobj_s
|
|||
|
||||
INT32 tics; // state tic counter
|
||||
state_t *state;
|
||||
INT32 flags; // flags from mobjinfo tables
|
||||
UINT32 flags; // flags from mobjinfo tables
|
||||
} precipmobj_t;
|
||||
|
||||
typedef struct actioncache_s
|
||||
|
|
|
|||
|
|
@ -390,7 +390,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
|||
mapheaderinfo[num]->muspostbossfadein = 0;
|
||||
mapheaderinfo[num]->musforcereset = -1;
|
||||
mapheaderinfo[num]->forcecharacter[0] = '\0';
|
||||
mapheaderinfo[num]->weather = 0;
|
||||
mapheaderinfo[num]->weather = PRECIP_NONE;
|
||||
snprintf(mapheaderinfo[num]->skytexture, 5, "SKY1");
|
||||
mapheaderinfo[num]->skytexture[4] = 0;
|
||||
mapheaderinfo[num]->skybox_scalex = 16;
|
||||
|
|
|
|||
30
src/p_spec.c
30
src/p_spec.c
|
|
@ -1769,10 +1769,18 @@ void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller)
|
|||
//
|
||||
// Switches the weather!
|
||||
//
|
||||
void P_SwitchWeather(UINT8 newWeather)
|
||||
void P_SwitchWeather(preciptype_t newWeather)
|
||||
{
|
||||
boolean purge = false;
|
||||
mobjtype_t swap = MT_NULL;
|
||||
INT32 oldEffects = precipprops[curWeather].effects;
|
||||
|
||||
if (newWeather >= precip_freeslot)
|
||||
{
|
||||
// Weather type invalid, set to no weather.
|
||||
CONS_Debug(DBG_SETUP, "Weather ID %d out of bounds\n", newWeather);
|
||||
newWeather = PRECIP_NONE;
|
||||
}
|
||||
|
||||
if (precipprops[newWeather].type == MT_NULL)
|
||||
{
|
||||
|
|
@ -1790,6 +1798,8 @@ void P_SwitchWeather(UINT8 newWeather)
|
|||
}
|
||||
}
|
||||
|
||||
curWeather = newWeather;
|
||||
|
||||
if (purge == true)
|
||||
{
|
||||
thinker_t *think;
|
||||
|
|
@ -1844,14 +1854,22 @@ void P_SwitchWeather(UINT8 newWeather)
|
|||
precipmobj->sprite = precipmobj->state->sprite;
|
||||
precipmobj->frame = precipmobj->state->frame;
|
||||
|
||||
precipmobj->momz = mobjinfo[swap].speed;
|
||||
precipmobj->precipflags &= ~PCF_INVISIBLE;
|
||||
precipmobj->momz = -mobjinfo[swap].speed;
|
||||
precipmobj->precipflags &= ~(PCF_INVISIBLE|PCF_FLIP);
|
||||
|
||||
if (precipmobj->momz > 0)
|
||||
{
|
||||
precipmobj->precipflags |= PCF_FLIP;
|
||||
}
|
||||
|
||||
if ((oldEffects & PRECIPFX_WATERPARTICLES) != (precipprops[curWeather].effects & PRECIPFX_WATERPARTICLES))
|
||||
{
|
||||
P_CalculatePrecipFloor(precipmobj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
curWeather = newWeather;
|
||||
|
||||
if (swap == MT_NULL && precipprops[newWeather].type != MT_NULL)
|
||||
if (swap == MT_NULL && precipprops[curWeather].type != MT_NULL)
|
||||
P_SpawnPrecipitation();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ void P_CrossSpecialLine(line_t *ld, INT32 side, mobj_t *thing);
|
|||
void P_SetupSignExit(player_t *player);
|
||||
boolean P_IsFlagAtBase(mobjtype_t flag);
|
||||
|
||||
void P_SwitchWeather(UINT8 newWeather);
|
||||
void P_SwitchWeather(preciptype_t newWeather);
|
||||
|
||||
boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller);
|
||||
void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller);
|
||||
|
|
|
|||
|
|
@ -2188,6 +2188,9 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
//SoM: 3/17/2000
|
||||
fixed_t gz, gzt;
|
||||
|
||||
UINT32 blendmode;
|
||||
UINT32 trans;
|
||||
|
||||
// uncapped/interpolation
|
||||
interpmobjstate_t interp = {0};
|
||||
|
||||
|
|
@ -2281,6 +2284,17 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
goto weatherthink;
|
||||
}
|
||||
|
||||
// Determine the blendmode and translucency value
|
||||
{
|
||||
blendmode = (thing->frame & FF_BLENDMASK) >> FF_BLENDSHIFT;
|
||||
if (blendmode)
|
||||
blendmode++; // realign to constants
|
||||
|
||||
trans = (thing->frame & FF_TRANSMASK) >> FF_TRANSSHIFT;
|
||||
if (trans >= NUMTRANSMAPS)
|
||||
goto weatherthink; // cap
|
||||
}
|
||||
|
||||
// store information in a vissprite
|
||||
vis = R_NewVisSprite();
|
||||
vis->scale = vis->sortscale = yscale; //<<detailshift;
|
||||
|
|
@ -2318,12 +2332,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
|||
// than lumpid for sprites-in-pwad : the graphics are patched
|
||||
vis->patch = W_CachePatchNum(sprframe->lumppat[0], PU_SPRITE);
|
||||
|
||||
// specific translucency
|
||||
// (no draw flags)
|
||||
if (thing->frame & FF_TRANSMASK)
|
||||
vis->transmap = ((thing->frame & FF_TRANSMASK) - FF_TRANS10) + transtables;
|
||||
else
|
||||
vis->transmap = NULL;
|
||||
vis->transmap = R_GetBlendTable(blendmode, trans);
|
||||
|
||||
vis->mobj = (mobj_t *)thing;
|
||||
vis->mobjflags = 0;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue