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);
|
Z_Free(s);
|
||||||
lua_remove(L, 1);
|
lua_remove(L, 1);
|
||||||
continue;
|
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);
|
if (mathlib) return luaL_error(L, "menutype '%s' could not be found.\n", word);
|
||||||
return 0;
|
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)) {
|
else if (!mathlib && fastncmp("A_",word,2)) {
|
||||||
char *caps;
|
char *caps;
|
||||||
// Try to get a Lua action first.
|
// Try to get a Lua action first.
|
||||||
|
|
|
||||||
|
|
@ -481,6 +481,25 @@ void readfreeslots(MYFILE *f)
|
||||||
lastcustomtol <<= 1;
|
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
|
else
|
||||||
deh_warning("Freeslots: unknown enum class '%s' for '%s_%s'", type, type, word);
|
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
|
strlwr(mapheaderinfo[num-1]->forcecharacter); // skin names are lowercase
|
||||||
}
|
}
|
||||||
else if (fastcmp(word, "WEATHER"))
|
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"))
|
else if (fastcmp(word, "SKYTEXTURE"))
|
||||||
deh_strlcpy(mapheaderinfo[num-1]->skytexture, word2,
|
deh_strlcpy(mapheaderinfo[num-1]->skytexture, word2,
|
||||||
sizeof(mapheaderinfo[num-1]->skytexture), va("Level header %d: sky texture", num));
|
sizeof(mapheaderinfo[num-1]->skytexture), va("Level header %d: sky texture", num));
|
||||||
|
|
@ -4086,6 +4105,61 @@ if (!followers[numfollowers].field) \
|
||||||
Z_Free(s);
|
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;
|
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.
|
/// \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_mul(fixed_t a, fixed_t b) { return a*b; }
|
||||||
static fixed_t op_div(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 readcupheader(MYFILE *f, cupheader_t *cup);
|
||||||
void readfollower(MYFILE *f);
|
void readfollower(MYFILE *f);
|
||||||
|
preciptype_t get_precip(const char *word);
|
||||||
|
void readweather(MYFILE *f, INT32 num);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -6741,6 +6741,11 @@ struct int_const_s const INT_CONST[] = {
|
||||||
{"SPOT_WEAK",SPOT_WEAK},
|
{"SPOT_WEAK",SPOT_WEAK},
|
||||||
{"SPOT_BUMP",SPOT_BUMP},
|
{"SPOT_BUMP",SPOT_BUMP},
|
||||||
|
|
||||||
|
// precipeffect_t
|
||||||
|
{"PRECIPFX_THUNDER",PRECIPFX_THUNDER},
|
||||||
|
{"PRECIPFX_LIGHTNING",PRECIPFX_LIGHTNING},
|
||||||
|
{"PRECIPFX_WATERPARTICLES",PRECIPFX_WATERPARTICLES},
|
||||||
|
|
||||||
{NULL,0}
|
{NULL,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -576,6 +576,18 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
|
||||||
|
|
||||||
readcupheader(f, cup);
|
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"))
|
else if (fastcmp(word, "RINGRACERS"))
|
||||||
{
|
{
|
||||||
if (isdigit(word2[0]))
|
if (isdigit(word2[0]))
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,7 @@ extern UINT32 mapmusresume;
|
||||||
// Use other bits if necessary.
|
// Use other bits if necessary.
|
||||||
|
|
||||||
extern UINT32 maptol;
|
extern UINT32 maptol;
|
||||||
extern UINT8 globalweather;
|
|
||||||
extern UINT8 curWeather;
|
|
||||||
extern INT32 cursaveslot;
|
extern INT32 cursaveslot;
|
||||||
//extern INT16 lastmapsaved;
|
//extern INT16 lastmapsaved;
|
||||||
extern INT16 lastmaploaded;
|
extern INT16 lastmaploaded;
|
||||||
|
|
@ -64,31 +63,44 @@ extern tic_t marathontime;
|
||||||
extern UINT8 numgameovers;
|
extern UINT8 numgameovers;
|
||||||
extern SINT8 startinglivesbalance[maxgameovers+1];
|
extern SINT8 startinglivesbalance[maxgameovers+1];
|
||||||
|
|
||||||
|
#define NUMPRECIPFREESLOTS 64
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
PRECIP_NONE = 0,
|
PRECIP_NONE = 0,
|
||||||
|
|
||||||
PRECIP_RAIN,
|
PRECIP_RAIN,
|
||||||
PRECIP_SNOW,
|
PRECIP_SNOW,
|
||||||
PRECIP_BLIZZARD,
|
PRECIP_BLIZZARD,
|
||||||
PRECIP_STORM,
|
PRECIP_STORM,
|
||||||
PRECIP_STORM_NORAIN,
|
PRECIP_STORM_NORAIN,
|
||||||
PRECIP_STORM_NOSTRIKES,
|
PRECIP_STORM_NOSTRIKES,
|
||||||
|
|
||||||
|
PRECIP_FIRSTFREESLOT,
|
||||||
|
PRECIP_LASTFREESLOT = PRECIP_FIRSTFREESLOT + NUMPRECIPFREESLOTS - 1,
|
||||||
|
|
||||||
MAXPRECIP
|
MAXPRECIP
|
||||||
} preciptype_t;
|
} preciptype_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
PRECIPFX_THUNDER = 1,
|
PRECIPFX_THUNDER = 1,
|
||||||
PRECIPFX_LIGHTNING = 1<<1
|
PRECIPFX_LIGHTNING = 1<<1,
|
||||||
|
PRECIPFX_WATERPARTICLES = 1<<2
|
||||||
} precipeffect_t;
|
} precipeffect_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
const char *name;
|
||||||
mobjtype_t type;
|
mobjtype_t type;
|
||||||
precipeffect_t effects;
|
precipeffect_t effects;
|
||||||
} precipprops_t;
|
} precipprops_t;
|
||||||
|
|
||||||
extern precipprops_t precipprops[MAXPRECIP];
|
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.
|
// Set if homebrew PWAD stuff has been added.
|
||||||
extern boolean modifiedgame;
|
extern boolean modifiedgame;
|
||||||
|
|
|
||||||
20
src/g_game.c
20
src/g_game.c
|
|
@ -93,20 +93,22 @@ UINT32 mapmusresume;
|
||||||
INT16 gamemap = 1;
|
INT16 gamemap = 1;
|
||||||
UINT32 maptol;
|
UINT32 maptol;
|
||||||
|
|
||||||
UINT8 globalweather = PRECIP_NONE;
|
preciptype_t globalweather = PRECIP_NONE;
|
||||||
UINT8 curWeather = PRECIP_NONE;
|
preciptype_t curWeather = PRECIP_NONE;
|
||||||
|
|
||||||
precipprops_t precipprops[MAXPRECIP] =
|
precipprops_t precipprops[MAXPRECIP] =
|
||||||
{
|
{
|
||||||
{MT_NULL, 0}, // PRECIP_NONE
|
{"NONE", MT_NULL, 0}, // PRECIP_NONE
|
||||||
{MT_RAIN, 0}, // PRECIP_RAIN
|
{"RAIN", MT_RAIN, 0}, // PRECIP_RAIN
|
||||||
{MT_SNOWFLAKE, 0}, // PRECIP_SNOW
|
{"SNOW", MT_SNOWFLAKE, 0}, // PRECIP_SNOW
|
||||||
{MT_BLIZZARDSNOW, 0}, // PRECIP_BLIZZARD
|
{"BLIZZARD", MT_BLIZZARDSNOW, 0}, // PRECIP_BLIZZARD
|
||||||
{MT_RAIN, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING}, // PRECIP_STORM
|
{"STORM", MT_RAIN, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING}, // PRECIP_STORM
|
||||||
{MT_NULL, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING}, // PRECIP_STORM_NORAIN
|
{"STORM_NORAIN", MT_NULL, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING}, // PRECIP_STORM_NORAIN
|
||||||
{MT_RAIN, PRECIPFX_THUNDER} // PRECIP_STORM_NOSTRIKES
|
{"STORM_NOSTRIKES", MT_RAIN, PRECIPFX_THUNDER} // PRECIP_STORM_NOSTRIKES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
preciptype_t precip_freeslot = PRECIP_FIRSTFREESLOT;
|
||||||
|
|
||||||
INT32 cursaveslot = 0; // Auto-save 1p savegame slot
|
INT32 cursaveslot = 0; // Auto-save 1p savegame slot
|
||||||
//INT16 lastmapsaved = 0; // Last map we auto-saved at
|
//INT16 lastmapsaved = 0; // Last map we auto-saved at
|
||||||
INT16 lastmaploaded = 0; // Last map the game loaded
|
INT16 lastmaploaded = 0; // Last map the game loaded
|
||||||
|
|
|
||||||
|
|
@ -18246,7 +18246,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_SPLASH1, // deathstate
|
S_SPLASH1, // deathstate
|
||||||
S_NULL, // xdeathstate
|
S_NULL, // xdeathstate
|
||||||
sfx_None, // deathsound
|
sfx_None, // deathsound
|
||||||
-72*FRACUNIT, // speed
|
72*FRACUNIT, // speed
|
||||||
1*FRACUNIT, // radius
|
1*FRACUNIT, // radius
|
||||||
8*FRACUNIT, // height
|
8*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
|
|
@ -18273,7 +18273,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL, // deathstate
|
S_NULL, // deathstate
|
||||||
S_NULL, // xdeathstate
|
S_NULL, // xdeathstate
|
||||||
sfx_None, // deathsound
|
sfx_None, // deathsound
|
||||||
-2*FRACUNIT, // speed
|
2*FRACUNIT, // speed
|
||||||
4*FRACUNIT, // radius
|
4*FRACUNIT, // radius
|
||||||
4*FRACUNIT, // height
|
4*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
|
|
@ -18300,7 +18300,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
S_NULL, // deathstate
|
S_NULL, // deathstate
|
||||||
S_NULL, // xdeathstate
|
S_NULL, // xdeathstate
|
||||||
sfx_None, // deathsound
|
sfx_None, // deathsound
|
||||||
-24*FRACUNIT, // speed
|
24*FRACUNIT, // speed
|
||||||
4*FRACUNIT, // radius
|
4*FRACUNIT, // radius
|
||||||
4*FRACUNIT, // height
|
4*FRACUNIT, // height
|
||||||
0, // display offset
|
0, // display offset
|
||||||
|
|
|
||||||
|
|
@ -163,6 +163,7 @@ static const struct {
|
||||||
{META_SPRITEINFO, "spriteinfo_t"},
|
{META_SPRITEINFO, "spriteinfo_t"},
|
||||||
{META_PIVOTLIST, "spriteframepivot_t[]"},
|
{META_PIVOTLIST, "spriteframepivot_t[]"},
|
||||||
{META_FRAMEPIVOT, "spriteframepivot_t"},
|
{META_FRAMEPIVOT, "spriteframepivot_t"},
|
||||||
|
{META_PRECIPPROPS, "precipprops_t"},
|
||||||
|
|
||||||
{META_TAGLIST, "taglist"},
|
{META_TAGLIST, "taglist"},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1758,6 +1758,151 @@ static int colorramp_len(lua_State *L)
|
||||||
return 1;
|
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!
|
// 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_setfield(L, -2, "__len");
|
||||||
lua_pop(L, 1);
|
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_newuserdata(L, 0);
|
||||||
lua_createtable(L, 0, 2);
|
lua_createtable(L, 0, 2);
|
||||||
lua_pushcfunction(L, lib_getSprname);
|
lua_pushcfunction(L, lib_getSprname);
|
||||||
|
|
@ -1961,6 +2117,19 @@ int LUA_InfoLib(lua_State *L)
|
||||||
lua_setmetatable(L, -2);
|
lua_setmetatable(L, -2);
|
||||||
lua_setglobal(L, "spriteinfo");
|
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);
|
luaL_newmetatable(L, META_LUABANKS);
|
||||||
lua_pushcfunction(L, lib_getluabanks);
|
lua_pushcfunction(L, lib_getluabanks);
|
||||||
lua_setfield(L, -2, "__index");
|
lua_setfield(L, -2, "__index");
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ extern lua_State *gL;
|
||||||
#define META_SPRITEINFO "SPRITEINFO_T*"
|
#define META_SPRITEINFO "SPRITEINFO_T*"
|
||||||
#define META_PIVOTLIST "SPRITEFRAMEPIVOT_T[]"
|
#define META_PIVOTLIST "SPRITEFRAMEPIVOT_T[]"
|
||||||
#define META_FRAMEPIVOT "SPRITEFRAMEPIVOT_T*"
|
#define META_FRAMEPIVOT "SPRITEFRAMEPIVOT_T*"
|
||||||
|
#define META_PRECIPPROPS "PRECIPPROPS_T*"
|
||||||
|
|
||||||
#define META_TAGLIST "TAGLIST"
|
#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);
|
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_RecalcPrecipInSector(sector_t *sector);
|
||||||
void P_PrecipitationEffects(void);
|
void P_PrecipitationEffects(void);
|
||||||
|
|
||||||
|
|
|
||||||
232
src/p_mobj.c
232
src/p_mobj.c
|
|
@ -3760,19 +3760,25 @@ animonly:
|
||||||
P_CyclePlayerMobjState(mobj);
|
P_CyclePlayerMobjState(mobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CalculatePrecipFloor(precipmobj_t *mobj)
|
void P_CalculatePrecipFloor(precipmobj_t *mobj)
|
||||||
{
|
{
|
||||||
// recalculate floorz each time
|
// recalculate floorz each time
|
||||||
const sector_t *mobjsecsubsec;
|
const sector_t *mobjsecsubsec;
|
||||||
|
boolean setWater = false;
|
||||||
|
|
||||||
if (mobj && mobj->subsector && mobj->subsector->sector)
|
if (mobj && mobj->subsector && mobj->subsector->sector)
|
||||||
mobjsecsubsec = mobj->subsector->sector;
|
mobjsecsubsec = mobj->subsector->sector;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
mobj->precipflags &= ~PCF_INVISIBLE;
|
||||||
mobj->floorz = P_GetSectorFloorZAt(mobjsecsubsec, mobj->x, mobj->y);
|
mobj->floorz = P_GetSectorFloorZAt(mobjsecsubsec, mobj->x, mobj->y);
|
||||||
|
mobj->ceilingz = P_GetSectorCeilingZAt(mobjsecsubsec, mobj->x, mobj->y);
|
||||||
|
|
||||||
if (mobjsecsubsec->ffloors)
|
if (mobjsecsubsec->ffloors)
|
||||||
{
|
{
|
||||||
ffloor_t *rover;
|
ffloor_t *rover;
|
||||||
fixed_t topheight;
|
fixed_t height;
|
||||||
|
|
||||||
for (rover = mobjsecsubsec->ffloors; rover; rover = rover->next)
|
for (rover = mobjsecsubsec->ffloors; rover; rover = rover->next)
|
||||||
{
|
{
|
||||||
|
|
@ -3780,14 +3786,44 @@ static void CalculatePrecipFloor(precipmobj_t *mobj)
|
||||||
if (!(rover->flags & FF_EXISTS))
|
if (!(rover->flags & FF_EXISTS))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!(rover->flags & FF_BLOCKOTHERS) && !(rover->flags & FF_SWIMMABLE))
|
if (precipprops[curWeather].effects & PRECIPFX_WATERPARTICLES)
|
||||||
continue;
|
{
|
||||||
|
if (!(rover->flags & FF_SWIMMABLE))
|
||||||
|
continue;
|
||||||
|
|
||||||
topheight = P_GetFFloorTopZAt(rover, mobj->x, mobj->y);
|
if (setWater == false)
|
||||||
if (topheight > mobj->floorz)
|
{
|
||||||
mobj->floorz = topheight;
|
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;
|
||||||
|
|
||||||
|
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)
|
void P_RecalcPrecipInSector(sector_t *sector)
|
||||||
|
|
@ -3800,7 +3836,7 @@ void P_RecalcPrecipInSector(sector_t *sector)
|
||||||
sector->moved = true; // Recalc lighting and things too, maybe
|
sector->moved = true; // Recalc lighting and things too, maybe
|
||||||
|
|
||||||
for (psecnode = sector->touching_preciplist; psecnode; psecnode = psecnode->m_thinglist_next)
|
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;
|
//(void)mobj;
|
||||||
mobj->precipflags &= ~PCF_THUNK;
|
mobj->precipflags &= ~PCF_THUNK;
|
||||||
|
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void P_PrecipThinker(precipmobj_t *mobj)
|
void P_PrecipThinker(precipmobj_t *mobj)
|
||||||
{
|
{
|
||||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
boolean flip = (mobj->precipflags & PCF_FLIP);
|
||||||
|
|
||||||
P_CycleStateAnimation((mobj_t *)mobj);
|
P_CycleStateAnimation((mobj_t *)mobj);
|
||||||
|
|
||||||
|
|
@ -3824,9 +3861,10 @@ void P_PrecipThinker(precipmobj_t *mobj)
|
||||||
{
|
{
|
||||||
// Reset to ceiling!
|
// Reset to ceiling!
|
||||||
P_SetPrecipMobjState(mobj, mobj->info->spawnstate);
|
P_SetPrecipMobjState(mobj, mobj->info->spawnstate);
|
||||||
mobj->z = mobj->ceilingz;
|
mobj->z = (flip) ? (mobj->floorz) : (mobj->ceilingz);
|
||||||
mobj->momz = mobj->info->speed;
|
mobj->momz = -mobj->info->speed;
|
||||||
mobj->precipflags &= ~PCF_SPLASH;
|
mobj->precipflags &= ~PCF_SPLASH;
|
||||||
|
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mobj->tics != -1)
|
if (mobj->tics != -1)
|
||||||
|
|
@ -3858,18 +3896,20 @@ void P_PrecipThinker(precipmobj_t *mobj)
|
||||||
if (mobj->precipflags & PCF_SPLASH)
|
if (mobj->precipflags & PCF_SPLASH)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
mobj->z += mobj->momz;
|
||||||
|
|
||||||
// adjust height
|
// 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
|
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);
|
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
P_SetPrecipMobjState(mobj, mobj->info->deathstate);
|
P_SetPrecipMobjState(mobj, mobj->info->deathstate);
|
||||||
mobj->z = mobj->floorz;
|
mobj->z = (flip) ? (mobj->ceilingz) : (mobj->floorz);
|
||||||
mobj->precipflags |= PCF_SPLASH;
|
mobj->precipflags |= PCF_SPLASH;
|
||||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
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];
|
const mobjinfo_t *info = &mobjinfo[type];
|
||||||
state_t *st;
|
state_t *st;
|
||||||
|
fixed_t start_z = INT32_MIN;
|
||||||
precipmobj_t *mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
|
precipmobj_t *mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
|
||||||
fixed_t starting_floorz;
|
|
||||||
|
|
||||||
mobj->type = type;
|
mobj->type = type;
|
||||||
mobj->info = info;
|
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
|
// set subsector and/or block links
|
||||||
P_SetPrecipitationThingPosition(mobj);
|
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->ceilingz = P_GetSectorCeilingZAt(mobj->subsector->sector, x, y);
|
||||||
|
|
||||||
mobj->floorrover = NULL;
|
mobj->floorrover = NULL;
|
||||||
mobj->ceilingrover = NULL;
|
mobj->ceilingrover = NULL;
|
||||||
|
|
||||||
mobj->z = z;
|
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;
|
mobj->thinker.function.acp1 = (actionf_p1)P_NullPrecipThinker;
|
||||||
P_AddThinker(THINK_PRECIP, &mobj->thinker);
|
P_AddThinker(THINK_PRECIP, &mobj->thinker);
|
||||||
|
|
||||||
CalculatePrecipFloor(mobj);
|
P_CalculatePrecipFloor(mobj);
|
||||||
|
|
||||||
if (mobj->floorz != starting_floorz)
|
if (mobj->floorz != start_z)
|
||||||
mobj->precipflags |= PCF_FOF;
|
{
|
||||||
else if (GETSECSPECIAL(mobj->subsector->sector->special, 1) == 7
|
; //mobj->precipflags |= PCF_FOF;
|
||||||
|| GETSECSPECIAL(mobj->subsector->sector->special, 1) == 6
|
}
|
||||||
|| mobj->subsector->sector->floorpic == skyflatnum)
|
else
|
||||||
mobj->precipflags |= PCF_PIT;
|
{
|
||||||
|
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);
|
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||||
|
|
||||||
|
|
@ -10588,13 +10645,19 @@ consvar_t cv_itemrespawn = CVAR_INIT ("respawnitem", "On", CV_NETVAR, CV_OnOff,
|
||||||
void P_SpawnPrecipitation(void)
|
void P_SpawnPrecipitation(void)
|
||||||
{
|
{
|
||||||
INT32 i, j, k;
|
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;
|
fixed_t basex, basey, x, y, z, height;
|
||||||
|
UINT16 numparticles = 0;
|
||||||
|
boolean condition = false;
|
||||||
|
|
||||||
subsector_t *precipsector = NULL;
|
subsector_t *precipsector = NULL;
|
||||||
precipmobj_t *rainmo = 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;
|
return;
|
||||||
|
|
||||||
// Use the blockmap to narrow down our placing patterns
|
// Use the blockmap to narrow down our placing patterns
|
||||||
|
|
@ -10603,58 +10666,87 @@ void P_SpawnPrecipitation(void)
|
||||||
basex = bmaporgx + (i % bmapwidth) * MAPBLOCKSIZE;
|
basex = bmaporgx + (i % bmapwidth) * MAPBLOCKSIZE;
|
||||||
basey = bmaporgy + (i / bmapwidth) * MAPBLOCKSIZE;
|
basey = bmaporgy + (i / bmapwidth) * MAPBLOCKSIZE;
|
||||||
|
|
||||||
|
x = basex + ((M_RandomKey(MAPBLOCKUNITS << 3) << FRACBITS) >> 3);
|
||||||
|
y = basey + ((M_RandomKey(MAPBLOCKUNITS << 3) << FRACBITS) >> 3);
|
||||||
|
|
||||||
|
precipsector = R_PointInSubsectorOrNull(x, y);
|
||||||
|
|
||||||
|
// No sector? Stop wasting time,
|
||||||
|
// move on to the next entry in the blockmap
|
||||||
|
if (!precipsector)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Not in a sector with visible sky?
|
||||||
|
if (precipprops[curWeather].effects & PRECIPFX_WATERPARTICLES)
|
||||||
{
|
{
|
||||||
UINT16 numparticles = 0;
|
condition = false;
|
||||||
|
|
||||||
x = basex + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3);
|
if (precipsector->sector->ffloors)
|
||||||
y = basey + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3);
|
|
||||||
|
|
||||||
precipsector = R_PointInSubsectorOrNull(x, y);
|
|
||||||
|
|
||||||
// No sector? Stop wasting time,
|
|
||||||
// move on to the next entry in the blockmap
|
|
||||||
if (!precipsector)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Not in a sector with visible sky?
|
|
||||||
if (precipsector->sector->ceilingpic != skyflatnum)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
height = precipsector->sector->ceilingheight - precipsector->sector->floorheight;
|
|
||||||
|
|
||||||
// Exists, but is too small for reasonable precipitation.
|
|
||||||
if (height < 64<<FRACBITS)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Hack around a quirk of this entire system, where taller sectors look like they get less precipitation.
|
|
||||||
numparticles = 1 + (height / (MAPBLOCKUNITS<<4<<FRACBITS));
|
|
||||||
|
|
||||||
// Don't set z properly yet...
|
|
||||||
z = precipsector->sector->ceilingheight;
|
|
||||||
|
|
||||||
for (j = 0; j < numparticles; j++)
|
|
||||||
{
|
{
|
||||||
rainmo = P_SpawnPrecipMobj(x, y, z, type);
|
ffloor_t *rover;
|
||||||
|
|
||||||
if (randomstates > 0)
|
for (rover = precipsector->sector->ffloors; rover; rover = rover->next)
|
||||||
{
|
{
|
||||||
UINT8 mrand = M_RandomByte();
|
if (!(rover->flags & FF_EXISTS))
|
||||||
UINT8 threshold = UINT8_MAX / (randomstates + 1);
|
continue;
|
||||||
statenum_t st = mobjinfo[type].spawnstate;
|
|
||||||
|
|
||||||
for (k = 0; k < randomstates; k++)
|
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.
|
||||||
|
if (height < 64<<FRACBITS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Hack around a quirk of this entire system, where taller sectors look like they get less precipitation.
|
||||||
|
numparticles = 1 + (height / (MAPBLOCKUNITS<<4<<FRACBITS));
|
||||||
|
|
||||||
|
// Don't set z properly yet...
|
||||||
|
z = (flip) ? (precipsector->sector->floorheight) : (precipsector->sector->ceilingheight);
|
||||||
|
|
||||||
|
for (j = 0; j < numparticles; j++)
|
||||||
|
{
|
||||||
|
rainmo = P_SpawnPrecipMobj(x, y, z, type);
|
||||||
|
|
||||||
|
if (randomstates > 0)
|
||||||
|
{
|
||||||
|
UINT8 mrand = M_RandomByte();
|
||||||
|
UINT8 threshold = UINT8_MAX / (randomstates + 1);
|
||||||
|
statenum_t st = mobjinfo[type].spawnstate;
|
||||||
|
|
||||||
|
for (k = 0; k < randomstates; k++)
|
||||||
|
{
|
||||||
|
if (mrand < (threshold * (k+1)))
|
||||||
{
|
{
|
||||||
if (mrand < (threshold * (k+1)))
|
P_SetPrecipMobjState(rainmo, st+k+1);
|
||||||
{
|
break;
|
||||||
P_SetPrecipMobjState(rainmo, st+k+1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Randomly assign a height, now that floorz is set.
|
|
||||||
rainmo->z = M_RandomRange(rainmo->floorz>>FRACBITS, rainmo->ceilingz>>FRACBITS)<<FRACBITS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Randomly assign a height, now that floorz is set.
|
||||||
|
rainmo->z = M_RandomRange(rainmo->floorz >> FRACBITS, rainmo->ceilingz >> FRACBITS) << FRACBITS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
src/p_mobj.h
15
src/p_mobj.h
|
|
@ -262,12 +262,11 @@ typedef enum
|
||||||
// PRECIPITATION flags ?! ?! ?!
|
// PRECIPITATION flags ?! ?! ?!
|
||||||
//
|
//
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PCF_INVISIBLE = 1, // Don't draw.
|
PCF_THUNK = 1, // Ran the thinker this tic.
|
||||||
PCF_PIT = 1<<1, // Above pit.
|
PCF_SPLASH = 1<<1, // Splashed on the ground, return to the ceiling after the animation's over
|
||||||
PCF_FOF = 1<<2, // Above FOF.
|
PCF_INVISIBLE = 1<<2, // Don't draw.
|
||||||
PCF_MOVINGFOF = 1<<3, // Above MOVING FOF (this means we need to keep floorz up to date...)
|
PCF_PIT = 1<<3, // Above pit.
|
||||||
PCF_SPLASH = 1<<4, // Splashed on the ground, return to the ceiling after the animation's over
|
PCF_FLIP = 1<<4, // Spawning from floor, moving upwards.
|
||||||
PCF_THUNK = 1<<5, // Ran the thinker this tic.
|
|
||||||
} precipflag_t;
|
} precipflag_t;
|
||||||
|
|
||||||
// Map Object definition.
|
// Map Object definition.
|
||||||
|
|
@ -462,6 +461,8 @@ typedef struct precipmobj_s
|
||||||
fixed_t ceilingz; // Nearest ceiling above.
|
fixed_t ceilingz; // Nearest ceiling above.
|
||||||
struct ffloor_s *floorrover; // FOF referred by floorz
|
struct ffloor_s *floorrover; // FOF referred by floorz
|
||||||
struct ffloor_s *ceilingrover; // FOF referred by ceilingz
|
struct ffloor_s *ceilingrover; // FOF referred by ceilingz
|
||||||
|
fixed_t floordrop;
|
||||||
|
fixed_t ceilingdrop;
|
||||||
|
|
||||||
// For movement checking.
|
// For movement checking.
|
||||||
fixed_t radius; // Fixed at 2*FRACUNIT
|
fixed_t radius; // Fixed at 2*FRACUNIT
|
||||||
|
|
@ -473,7 +474,7 @@ typedef struct precipmobj_s
|
||||||
|
|
||||||
INT32 tics; // state tic counter
|
INT32 tics; // state tic counter
|
||||||
state_t *state;
|
state_t *state;
|
||||||
INT32 flags; // flags from mobjinfo tables
|
UINT32 flags; // flags from mobjinfo tables
|
||||||
} precipmobj_t;
|
} precipmobj_t;
|
||||||
|
|
||||||
typedef struct actioncache_s
|
typedef struct actioncache_s
|
||||||
|
|
|
||||||
|
|
@ -390,7 +390,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
||||||
mapheaderinfo[num]->muspostbossfadein = 0;
|
mapheaderinfo[num]->muspostbossfadein = 0;
|
||||||
mapheaderinfo[num]->musforcereset = -1;
|
mapheaderinfo[num]->musforcereset = -1;
|
||||||
mapheaderinfo[num]->forcecharacter[0] = '\0';
|
mapheaderinfo[num]->forcecharacter[0] = '\0';
|
||||||
mapheaderinfo[num]->weather = 0;
|
mapheaderinfo[num]->weather = PRECIP_NONE;
|
||||||
snprintf(mapheaderinfo[num]->skytexture, 5, "SKY1");
|
snprintf(mapheaderinfo[num]->skytexture, 5, "SKY1");
|
||||||
mapheaderinfo[num]->skytexture[4] = 0;
|
mapheaderinfo[num]->skytexture[4] = 0;
|
||||||
mapheaderinfo[num]->skybox_scalex = 16;
|
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!
|
// Switches the weather!
|
||||||
//
|
//
|
||||||
void P_SwitchWeather(UINT8 newWeather)
|
void P_SwitchWeather(preciptype_t newWeather)
|
||||||
{
|
{
|
||||||
boolean purge = false;
|
boolean purge = false;
|
||||||
mobjtype_t swap = MT_NULL;
|
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)
|
if (precipprops[newWeather].type == MT_NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -1790,6 +1798,8 @@ void P_SwitchWeather(UINT8 newWeather)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curWeather = newWeather;
|
||||||
|
|
||||||
if (purge == true)
|
if (purge == true)
|
||||||
{
|
{
|
||||||
thinker_t *think;
|
thinker_t *think;
|
||||||
|
|
@ -1844,14 +1854,22 @@ void P_SwitchWeather(UINT8 newWeather)
|
||||||
precipmobj->sprite = precipmobj->state->sprite;
|
precipmobj->sprite = precipmobj->state->sprite;
|
||||||
precipmobj->frame = precipmobj->state->frame;
|
precipmobj->frame = precipmobj->state->frame;
|
||||||
|
|
||||||
precipmobj->momz = mobjinfo[swap].speed;
|
precipmobj->momz = -mobjinfo[swap].speed;
|
||||||
precipmobj->precipflags &= ~PCF_INVISIBLE;
|
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[curWeather].type != MT_NULL)
|
||||||
|
|
||||||
if (swap == MT_NULL && precipprops[newWeather].type != MT_NULL)
|
|
||||||
P_SpawnPrecipitation();
|
P_SpawnPrecipitation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ void P_CrossSpecialLine(line_t *ld, INT32 side, mobj_t *thing);
|
||||||
void P_SetupSignExit(player_t *player);
|
void P_SetupSignExit(player_t *player);
|
||||||
boolean P_IsFlagAtBase(mobjtype_t flag);
|
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);
|
boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller);
|
||||||
void P_LinedefExecute(INT16 tag, 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
|
//SoM: 3/17/2000
|
||||||
fixed_t gz, gzt;
|
fixed_t gz, gzt;
|
||||||
|
|
||||||
|
UINT32 blendmode;
|
||||||
|
UINT32 trans;
|
||||||
|
|
||||||
// uncapped/interpolation
|
// uncapped/interpolation
|
||||||
interpmobjstate_t interp = {0};
|
interpmobjstate_t interp = {0};
|
||||||
|
|
||||||
|
|
@ -2281,6 +2284,17 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
||||||
goto weatherthink;
|
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
|
// store information in a vissprite
|
||||||
vis = R_NewVisSprite();
|
vis = R_NewVisSprite();
|
||||||
vis->scale = vis->sortscale = yscale; //<<detailshift;
|
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
|
// than lumpid for sprites-in-pwad : the graphics are patched
|
||||||
vis->patch = W_CachePatchNum(sprframe->lumppat[0], PU_SPRITE);
|
vis->patch = W_CachePatchNum(sprframe->lumppat[0], PU_SPRITE);
|
||||||
|
|
||||||
// specific translucency
|
vis->transmap = R_GetBlendTable(blendmode, trans);
|
||||||
// (no draw flags)
|
|
||||||
if (thing->frame & FF_TRANSMASK)
|
|
||||||
vis->transmap = ((thing->frame & FF_TRANSMASK) - FF_TRANS10) + transtables;
|
|
||||||
else
|
|
||||||
vis->transmap = NULL;
|
|
||||||
|
|
||||||
vis->mobj = (mobj_t *)thing;
|
vis->mobj = (mobj_t *)thing;
|
||||||
vis->mobjflags = 0;
|
vis->mobjflags = 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue