diff --git a/src/blua/ldebug.c b/src/blua/ldebug.c index 542e209a1..143d5d614 100644 --- a/src/blua/ldebug.c +++ b/src/blua/ldebug.c @@ -31,6 +31,9 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); +#ifdef DEVELOP +static const char *getcanonicalfuncname (Closure *f, const char **name); +#endif static int currentpc (lua_State *L, CallInfo *ci) { @@ -212,7 +215,11 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, break; } case 'n': { +#ifdef DEVELOP + ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : getcanonicalfuncname(f, &ar->name); +#else ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; +#endif if (ar->namewhat == NULL) { ar->namewhat = ""; /* not found */ ar->name = NULL; @@ -555,6 +562,19 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { } +#ifdef DEVELOP +static const char *getcanonicalfuncname (Closure *cl, const char **name) { + if (!cl->c.isC && cl->l.p->canonicalname) + { + *name = cl->l.p->canonicalname; + return "global"; + } + else + return NULL; +} +#endif + + /* only ANSI way to check whether a pointer points to an array */ static int isinstack (CallInfo *ci, const TValue *o) { StkId p; diff --git a/src/blua/lfunc.c b/src/blua/lfunc.c index 22f670e67..a07824c44 100644 --- a/src/blua/lfunc.c +++ b/src/blua/lfunc.c @@ -134,6 +134,9 @@ Proto *luaF_newproto (lua_State *L) { f->linedefined = 0; f->lastlinedefined = 0; f->source = NULL; +#ifdef DEVELOP + f->canonicalname = NULL; +#endif return f; } diff --git a/src/blua/lobject.h b/src/blua/lobject.h index 24309a1ec..6484e0e8c 100644 --- a/src/blua/lobject.h +++ b/src/blua/lobject.h @@ -237,6 +237,9 @@ typedef struct Proto { struct LocVar *locvars; /* information about local variables */ TString **upvalues; /* upvalue names */ TString *source; +#ifdef DEVELOP + const char *canonicalname; /* function name, only for globals right now */ +#endif int sizeupvalues; int sizek; /* size of `k' */ int sizecode; diff --git a/src/blua/lparser.c b/src/blua/lparser.c index 3f392ae7b..aeed307ec 100644 --- a/src/blua/lparser.c +++ b/src/blua/lparser.c @@ -246,8 +246,7 @@ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { } -static void singlevar (LexState *ls, expdesc *var) { - TString *varname = str_checkname(ls); +static void singlevar (LexState *ls, expdesc *var, TString *varname) { FuncState *fs = ls->fs; if (singlevaraux(fs, varname, var, 1) == VGLOBAL) var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */ @@ -603,11 +602,16 @@ static void body_noparms (LexState *ls, expdesc *e, int line) { close_func(ls); pushclosure(ls, &new_fs, e); } -static void body (LexState *ls, expdesc *e, int needself, int line) { +static void body (LexState *ls, expdesc *e, int needself, int line, const char *name) { /* body -> `(' parlist `)' chunk END */ FuncState new_fs; open_func(ls, &new_fs); new_fs.f->linedefined = line; +#ifdef DEVELOP + new_fs.f->canonicalname = name; +#else + (void)name; +#endif checknext(ls, '('); if (needself) { new_localvarliteral(ls, "self", 0); @@ -706,7 +710,7 @@ static void prefixexp (LexState *ls, expdesc *v) { return; } case TK_NAME: { - singlevar(ls, v); + singlevar(ls, v, str_checkname(ls)); return; } case '$': { @@ -826,7 +830,7 @@ static void simpleexp (LexState *ls, expdesc *v) { } case TK_FUNCTION: { luaX_next(ls); - body(ls, v, 0, ls->linenumber); + body(ls, v, 0, ls->linenumber, NULL); return; } default: { @@ -1315,11 +1319,12 @@ static void ifstat (LexState *ls, int line) { static void localfunc (LexState *ls) { expdesc v, b; FuncState *fs = ls->fs; - new_localvar(ls, str_checkname(ls), 0); + TString *name = str_checkname(ls); + new_localvar(ls, name, 0); init_exp(&v, VLOCAL, fs->freereg); luaK_reserveregs(fs, 1); adjustlocalvars(ls, 1); - body(ls, &b, 0, ls->linenumber); + body(ls, &b, 0, ls->linenumber, NULL); luaK_storevar(fs, &v, &b); /* debug information will only see the variable after this point! */ getlocvar(fs, fs->nactvar - 1).startpc = fs->pc; @@ -1345,10 +1350,10 @@ static void localstat (LexState *ls) { } -static int funcname (LexState *ls, expdesc *v) { +static int funcname (LexState *ls, expdesc *v, TString *varname) { /* funcname -> NAME {field} [`:' NAME] */ int needself = 0; - singlevar(ls, v); + singlevar(ls, v, varname); while (ls->t.token == '.') field(ls, v); if (ls->t.token == ':') { @@ -1363,9 +1368,16 @@ static void funcstat (LexState *ls, int line) { /* funcstat -> FUNCTION funcname body */ int needself; expdesc v, b; + TString *name; luaX_next(ls); /* skip FUNCTION */ - needself = funcname(ls, &v); - body(ls, &b, needself, line); + name = str_checkname(ls); + needself = funcname(ls, &v, name); +#ifdef DEVELOP + /* just strdup this because I couldn't figure out gc */ + body(ls, &b, needself, line, name ? strdup(getstr(name)) : NULL); +#else + body(ls, &b, needself, line, NULL); +#endif luaK_storevar(ls->fs, &v, &b); luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ } diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7c3fbb4b3..7975891e9 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2915,16 +2915,6 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) pnum = READUINT8(*p); msg = READUINT8(*p); - if (pnum == serverplayer && IsPlayerAdmin(playernum)) - { - CONS_Printf(M_GetText("Server is being shut down remotely. Goodbye!\n")); - - if (server) - COM_BufAddText("quit\n"); - - return; - } - // Is playernum authorized to make this kick? if (playernum != serverplayer && !IsPlayerAdmin(playernum) /*&& !(playernode[playernum] != UINT8_MAX && playerpernode[playernode[playernum]] == 2 @@ -2974,6 +2964,12 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) READSTRINGN(*p, reason, MAX_REASONLENGTH+1); } + if (playernode[pnum] == servernode) + { + CONS_Printf(M_GetText("Ignoring kick attempt from %s on node %d (it's the server)\n"), player_names[playernum], servernode); + return; + } + //CONS_Printf("\x82%s ", player_names[pnum]); // Save bans here. Used to be split between here and the actual command, depending on diff --git a/src/d_main.c b/src/d_main.c index 600bc04e9..88e98f134 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1661,7 +1661,7 @@ void D_SRB2Main(void) I_Error("Cannot find a map remotely named '%s'\n", word); else { - if (!M_CheckParm("-server")) + if (!M_CheckParm("-server") && !M_CheckParm("-dedicated")) { G_SetGameModified(true, true); diff --git a/src/deh_tables.c b/src/deh_tables.c index 44c34c896..801f1d29b 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5126,7 +5126,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_SKYBOX", // Debris - "MT_SPARK", //spark + "MT_SPARK", //spark, only used for debugging, actually "MT_EXPLODE", // Robot Explosion "MT_UWEXPLODE", // Underwater Explosion "MT_DUST", diff --git a/src/g_demo.c b/src/g_demo.c index 9481295b5..2d6998e80 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1113,7 +1113,7 @@ void G_GhostTicker(void) for(g = ghosts, p = NULL; g; g = g->next) { // Skip normal demo data. - UINT8 ziptic = READUINT8(g->p); + UINT16 ziptic = READUINT8(g->p); UINT8 xziptic = 0; while (ziptic != DW_END) // Get rid of extradata stuff @@ -1142,12 +1142,16 @@ void G_GhostTicker(void) ziptic = READUINT8(g->p); } - ziptic = READUINT8(g->p); + ziptic = READUINT16(g->p); if (ziptic & ZT_FWD) g->p++; + if (ziptic & ZT_SIDE) + g->p++; if (ziptic & ZT_TURNING) g->p += 2; + if (ziptic & ZT_ANGLE) + g->p += 2; if (ziptic & ZT_THROWDIR) g->p += 2; if (ziptic & ZT_BUTTONS) diff --git a/src/info.h b/src/info.h index 1d2102756..0c2d9be69 100644 --- a/src/info.h +++ b/src/info.h @@ -6143,7 +6143,7 @@ typedef enum mobj_type MT_SKYBOX, // Debris - MT_SPARK, //spark + MT_SPARK, //spark, only used for debugging, actually MT_EXPLODE, // Robot Explosion MT_UWEXPLODE, // Underwater Explosion MT_DUST, diff --git a/src/k_collide.c b/src/k_collide.c index 61bddb9b3..80847fa01 100644 --- a/src/k_collide.c +++ b/src/k_collide.c @@ -514,10 +514,7 @@ boolean K_DropTargetCollide(mobj_t *t1, mobj_t *t2) { mobj_t *draggeddroptarget = (t1->type == MT_DROPTARGET_SHIELD) ? t1->target : NULL; - if ((t1->threshold > 0 && (!draggeddroptarget)) || (t2->threshold > 0)) - return true; - - if (((t1->target == t2) || (t1->target == t2->target)) && (t1->threshold > 0 || (t2->type != MT_PLAYER && t2->threshold > 0))) + if (((t1->target == t2) || (t1->target == t2->target)) && ((t1->threshold > 0 && t2->type == MT_PLAYER) || (t2->type != MT_PLAYER && t2->threshold > 0))) return true; if (t1->health <= 0 || t2->health <= 0) diff --git a/src/k_kart.c b/src/k_kart.c index 3ec6c9aaf..09001f98c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8902,18 +8902,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) { player->pflags &= ~PF_AIRFAILSAFE; } - - // Play the starting countdown sounds - if (!(gametyperules & GTR_FREEROAM) && player == &players[g_localplayers[0]]) // Don't play louder in splitscreen - { - if ((leveltime == starttime-(3*TICRATE)) || (leveltime == starttime-(2*TICRATE)) || (leveltime == starttime-TICRATE)) - S_StartSound(NULL, sfx_s3ka7); - - if (leveltime == starttime-(3*TICRATE)) - S_FadeOutStopMusic(3500); - else if (leveltime == starttime) - S_StartSound(NULL, sfx_s3kad); - } } void K_CheckSpectateStatus(void) diff --git a/src/k_waypoint.c b/src/k_waypoint.c index 8bf8d1222..88fc02c20 100644 --- a/src/k_waypoint.c +++ b/src/k_waypoint.c @@ -620,6 +620,13 @@ void K_DebugWaypointsVisualise(void) // Hunt through the waypointcap so we can show all waypoint mobjs and not just ones that were able to be graphed for (waypointmobj = waypointcap; waypointmobj != NULL; waypointmobj = waypointmobj->tracer) { + // If this waypoint is outside of draw distance, don't spawn all the debug crap because it is SLOW + if (cv_drawdist.value != 0 && + R_PointToDist(waypointmobj->x, waypointmobj->y) > cv_drawdist.value * mapobjectscale) + { + continue; + } + waypoint = K_SearchWaypointHeapForMobj(waypointmobj); debugmobj = P_SpawnMobj(waypointmobj->x, waypointmobj->y, waypointmobj->z, MT_SPARK); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 1e3157500..75ce379ed 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -671,6 +671,23 @@ static int lib_pSpawnMobjFromMobj(lua_State *L) return 1; } +static int lib_pSpawnMobjFromMobjUnscaled(lua_State *L) +{ + mobj_t *actor = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + fixed_t x = luaL_checkfixed(L, 2); + fixed_t y = luaL_checkfixed(L, 3); + fixed_t z = luaL_checkfixed(L, 4); + mobjtype_t type = luaL_checkinteger(L, 5); + NOHUD + INLEVEL + if (!actor) + return LUA_ErrInvalid(L, "mobj_t"); + if (type >= NUMMOBJTYPES) + return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); + LUA_PushUserdata(L, P_SpawnMobjFromMobjUnscaled(actor, x, y, z, type), META_MOBJ); + return 1; +} + static int lib_pRemoveMobj(lua_State *L) { mobj_t *th = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -3847,6 +3864,7 @@ static luaL_Reg lib[] = { // don't add P_SetMobjState or P_SetPlayerMobjState, use "mobj.state = S_NEWSTATE" instead. {"P_SpawnMobj",lib_pSpawnMobj}, {"P_SpawnMobjFromMobj",lib_pSpawnMobjFromMobj}, + {"P_SpawnMobjFromMobjUnscaled",lib_pSpawnMobjFromMobjUnscaled}, {"P_RemoveMobj",lib_pRemoveMobj}, {"P_IsValidSprite2", lib_pIsValidSprite2}, {"P_SpawnLockOn", lib_pSpawnLockOn}, diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 5f25a7931..210eb446a 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -672,7 +672,7 @@ void LUA_HookThinkFrame(void) { get_hook(&hook, map->ids, k); - if (cv_perfstats.value == 3) + if (cv_perfstats.value == PS_THINKFRAME) { lua_pushvalue(gL, -1);/* need the function again */ time_taken = I_GetPreciseTime(); @@ -680,7 +680,7 @@ void LUA_HookThinkFrame(void) call_single_hook(&hook); - if (cv_perfstats.value == 3) + if (cv_perfstats.value == PS_THINKFRAME) { lua_Debug ar; time_taken = I_GetPreciseTime() - time_taken; diff --git a/src/lua_infolib.c b/src/lua_infolib.c index 0b8359065..555bf3196 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -43,7 +43,8 @@ enum sfxinfo_read { sfxinfor_flags, // "pitch" sfxinfor_volume, sfxinfor_caption, - sfxinfor_skinsound + sfxinfor_skinsound, + sfxinfor_string, }; const char *const sfxinfo_ropt[] = { "name", @@ -53,6 +54,7 @@ const char *const sfxinfo_ropt[] = { "volume", "caption", "skinsound", + "string", NULL}; enum sfxinfo_write { @@ -917,12 +919,52 @@ static int state_get(lua_State *L) // because the metatable will trigger. lua_getglobal(L, name); // actually gets from LREG_ACTIONS if applicable, and pushes a META_ACTION userdata if not. return 1; // return just the function +#ifdef DEVELOP + } else if (fastcmp(field,"actionname")) { + if (!st->action.acp1) { // Action is NULL. + lua_pushstring(L, "NULL"); + } else if (st->action.acp1 == (actionf_p1)A_Lua) { // This is a Lua function? + lua_Debug ar; + lua_getfield(L, LUA_REGISTRYINDEX, LREG_STATEACTION); + I_Assert(lua_istable(L, -1)); + lua_pushlightuserdata(L, st); // Push the state pointer and + lua_rawget(L, -2); // use it to get the actual Lua function. + lua_remove(L, -2); // pop LREG_STATEACTION + // This normally doesn't get a function's name because the same Lua function can have many names. + // It only works because of a hack called 'canonicalname' in blua/lparser.c, which records the + // name a GLOBAL function was defined with. This does not work for local functions! (Lua actions + // are almost always global functions though.) + lua_getinfo(L, ">n", &ar); + lua_pushstring(L, ar.name); + } else { + lua_pushstring(L, LUA_GetActionName(&st->action)); // find a hardcoded function name + } + return 1; +#endif } else if (fastcmp(field,"var1")) number = st->var1; else if (fastcmp(field,"var2")) number = st->var2; else if (fastcmp(field,"nextstate")) number = st->nextstate; + else if (fastcmp(field,"string")) + { + statenum_t id = st-states; + if (id < S_FIRSTFREESLOT) + { + lua_pushstring(L, STATE_LIST[id]+2); + return 1; + } + + id -= S_FIRSTFREESLOT; + if (id < NUMSTATEFREESLOTS && FREE_STATES[id]) + { + lua_pushstring(L, FREE_STATES[id]); + return 1; + } + + return 0; + } else if (devparm) return luaL_error(L, LUA_QL("state_t") " has no field named " LUA_QS, field); else @@ -1188,6 +1230,23 @@ static int mobjinfo_get(lua_State *L) lua_pushinteger(L, info->flags); else if (fastcmp(field,"raisestate")) lua_pushinteger(L, info->raisestate); + else if (fastcmp(field,"string")) { + mobjtype_t id = info-mobjinfo; + if (id < MT_FIRSTFREESLOT) + { + lua_pushstring(L, MOBJTYPE_LIST[id]+3); + return 1; + } + + id -= MT_FIRSTFREESLOT; + if (id < NUMMOBJFREESLOTS && FREE_MOBJS[id]) + { + lua_pushstring(L, FREE_MOBJS[id]); + return 1; + } + + return 0; + } else { lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); @@ -1411,6 +1470,10 @@ static int sfxinfo_get(lua_State *L) case sfxinfor_skinsound: lua_pushinteger(L, sfx->skinsound); return 1; + case sfxinfor_string: { + lua_pushstring(L, sfx->name); + return 1; + } default: return luaL_error(L, "Field does not exist in sfxinfo_t"); } diff --git a/src/lua_script.c b/src/lua_script.c index c42f568c2..688fb31e3 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -36,6 +36,7 @@ #include "doomstat.h" #include "g_state.h" +#include "m_argv.h" lua_State *gL = NULL; @@ -608,6 +609,12 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump, boolean noresults) MYFILE f; char *name; size_t len; + + if (M_CheckParm("-nolua")) + { + return; + } + f.wad = wad; f.size = W_LumpLengthPwad(wad, lump); f.data = Z_Malloc(f.size, PU_LUA, NULL); diff --git a/src/p_inter.c b/src/p_inter.c index 707ea374a..a99a1aa02 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1870,6 +1870,12 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, { (void)source; + if (player->respawn) + { + K_DoInstashield(player); + return false; + } + if (player->exiting) { player->mo->destscale = 1; diff --git a/src/p_local.h b/src/p_local.h index 34f68918f..7ca2b63d6 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -46,9 +46,7 @@ #define BMBOUNDFIX(xl, xh, yl, yh) {if (xl > xh) xl = 0; if (yl > yh) yl = 0;} // MAXRADIUS is for precalculated sector block boxes -// the spider demon is larger, -// but we do not have any moving sectors nearby -#define MAXRADIUS (32*FRACUNIT) +#define MAXRADIUS (MAPBLOCKSIZE >> 1) // max Z move up or down without jumping // above this, a height difference is considered as a 'dropoff' @@ -326,6 +324,7 @@ boolean P_CheckDeathPitCollide(mobj_t *mo); boolean P_CheckSolidLava(ffloor_t *rover); void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype); +mobj_t *P_SpawnMobjFromMobjUnscaled(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type); mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type); mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type); diff --git a/src/p_mobj.c b/src/p_mobj.c index 67a5b3408..efe8d51dd 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12276,7 +12276,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean // Ambush = double size (grounded) / half size (aerial) if (!(mthing->args[2] & TMICF_INVERTSIZE) == !P_IsObjectOnGround(mobj)) { - mobj->extravalue1 = min(mobj->extravalue1 << 1, FixedDiv(64*FRACUNIT, mobj->info->radius)); // don't make them larger than the blockmap can handle + mobj->extravalue1 = min(mobj->extravalue1 << 1, FixedDiv(MAPBLOCKSIZE, mobj->info->radius)); // don't make them larger than the blockmap can handle mobj->scalespeed <<= 1; } break; @@ -13239,6 +13239,65 @@ fixed_t P_ScaleFromMap(fixed_t n, fixed_t scale) return FixedMul(n, FixedDiv(scale, mapobjectscale)); } +// +// P_SpawnMobjFromMobjUnscaled +// Spawns an object with offsets relative to the position of another object. +// Scale, gravity flip, etc. is taken into account automatically. +// +mobj_t *P_SpawnMobjFromMobjUnscaled(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type) +{ + mobj_t *newmobj; + + newmobj = P_SpawnMobj(mobj->x + xofs, mobj->y + yofs, mobj->z + zofs, type); + if (!newmobj) + return NULL; + + newmobj->destscale = P_ScaleFromMap(mobj->destscale, newmobj->destscale); + P_SetScale(newmobj, P_ScaleFromMap(mobj->scale, newmobj->scale)); + + if (mobj->eflags & MFE_VERTICALFLIP) + { + newmobj->eflags |= MFE_VERTICALFLIP; + newmobj->flags2 |= MF2_OBJECTFLIP; + newmobj->z = mobj->z + mobj->height - zofs - newmobj->height; + + newmobj->old_z = mobj->old_z + mobj->height - zofs - newmobj->height; + newmobj->old_z2 = mobj->old_z2 + mobj->height - zofs - newmobj->height; + } + else + { + newmobj->old_z = mobj->old_z + zofs; + newmobj->old_z2 = mobj->old_z2 + zofs; + } + + newmobj->old_x2 = mobj->old_x2 + xofs; + newmobj->old_y2 = mobj->old_y2 + yofs; + newmobj->old_x = mobj->old_x + xofs; + newmobj->old_y = mobj->old_y + yofs; + + // This angle hack is needed for Lua scripts that set the angle after + // spawning, to avoid erroneous interpolation. + if (mobj->player) + { + newmobj->old_angle2 = mobj->player->old_drawangle2; + newmobj->old_angle = mobj->player->old_drawangle; + } + else + { + newmobj->old_angle2 = mobj->old_angle2; + newmobj->old_angle = mobj->old_angle; + } + + newmobj->old_scale2 = mobj->old_scale2; + newmobj->old_scale = mobj->old_scale; + newmobj->old_spritexscale = mobj->old_spritexscale; + newmobj->old_spriteyscale = mobj->old_spriteyscale; + newmobj->old_spritexoffset = mobj->old_spritexoffset; + newmobj->old_spriteyoffset = mobj->old_spriteyoffset; + + return newmobj; +} + // // P_SpawnMobjFromMobj // Spawns an object with offsets relative to the position of another object. diff --git a/src/p_saveg.c b/src/p_saveg.c index b6089bda3..5732cb839 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1749,6 +1749,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) if (mobj->type == MT_HOOPCENTER && mobj->threshold == 4242) return; + // MT_SPARK: used for debug stuff + if (mobj->type == MT_SPARK) + return; + if (mobj->spawnpoint) { // spawnpoint is not modified but we must save it since it is an identifier @@ -4236,7 +4240,9 @@ static void P_RelinkPointers(void) mobj = (mobj_t *)currentthinker; - if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER) + if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER + // MT_SPARK: used for debug stuff + || mobj->type == MT_SPARK) continue; if (mobj->tracer) @@ -4869,7 +4875,9 @@ void P_SaveNetGame(boolean resending) continue; mobj = (mobj_t *)th; - if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER) + if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER + // MT_SPARK: used for debug stuff + || mobj->type == MT_SPARK) continue; mobj->mobjnum = i++; } diff --git a/src/p_tick.c b/src/p_tick.c index d300a6635..5f6c15c18 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -672,7 +672,7 @@ void P_Ticker(boolean run) // Bosses have a punchy start, so no position. if (bossinfo.boss == true) { - if (leveltime == 3) + if (leveltime == 0) { S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0); S_ShowMusicCredit(); @@ -681,6 +681,19 @@ void P_Ticker(boolean run) // Plays the music after the starting countdown. else { + if (leveltime == starttime-(3*TICRATE)) + { + S_StartSound(NULL, sfx_s3ka7); // 3, + S_FadeOutStopMusic(3500); + } + else if ((leveltime == starttime-(2*TICRATE)) || (leveltime == starttime-TICRATE)) + { + S_StartSound(NULL, sfx_s3ka7); // 2, 1, + } + else if (leveltime == starttime) + { + S_StartSound(NULL, sfx_s3kad); // GO! + } if (leveltime == (starttime + (TICRATE/2))) { S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0); @@ -689,7 +702,7 @@ void P_Ticker(boolean run) } ps_lua_thinkframe_time = I_GetPreciseTime(); - LUA_HOOK(ThinkFrame); + LUA_HookThinkFrame(); ps_lua_thinkframe_time = I_GetPreciseTime() - ps_lua_thinkframe_time; } diff --git a/src/r_things.c b/src/r_things.c index b802e0145..02b16f44d 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2615,39 +2615,41 @@ static boolean R_SortVisSpriteFunc(vissprite_t *ds, fixed_t bestscale, INT32 bes // static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 end) { - UINT32 i, linkedvissprites = 0; + UINT32 i, count = 0; vissprite_t *ds, *dsprev, *dsnext, *dsfirst; vissprite_t *best = NULL; vissprite_t unsorted; fixed_t bestscale; INT32 bestdispoffset; - unsorted.next = unsorted.prev = &unsorted; + dsfirst = &unsorted; + dsprev = dsfirst; + dsnext = dsfirst; - dsfirst = R_GetVisSprite(start); + I_Assert(start <= end); - // The first's prev and last's next will be set to - // nonsense, but are fixed in a moment - for (i = start, dsnext = dsfirst, ds = NULL; i < end; i++) + for (i = start; i < end; ++i) { - dsprev = ds; - ds = dsnext; - if (i < end - 1) dsnext = R_GetVisSprite(i + 1); + ds = R_GetVisSprite(i); - ds->next = dsnext; - ds->prev = dsprev; - ds->linkdraw = NULL; + // Do not include this sprite, since it is completely obscured + if (ds->cut & SC_CULL) + { + continue; + } + + dsnext = ds; + dsnext->linkdraw = NULL; + + dsprev->next = dsnext; + dsnext->prev = dsprev; + dsprev = dsnext; + + count++; } - // Fix first and last. ds still points to the last one after the loop - dsfirst->prev = &unsorted; - unsorted.next = dsfirst; - if (ds) - { - ds->next = &unsorted; - ds->linkdraw = NULL; - } - unsorted.prev = ds; + dsnext->next = dsfirst; + dsfirst->prev = dsnext; // bundle linkdraw for (ds = unsorted.prev; ds != &unsorted; ds = ds->prev) @@ -2693,7 +2695,7 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e // remove from chain ds->next->prev = ds->prev; ds->prev->next = ds->next; - linkedvissprites++; + count--; if (dsfirst != &unsorted) { @@ -2727,7 +2729,7 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e // pull the vissprites out by scale vsprsortedhead->next = vsprsortedhead->prev = vsprsortedhead; - for (i = start; i < end-linkedvissprites; i++) + for (i = 0; i < count; i++) { bestscale = bestdispoffset = INT32_MAX; for (ds = unsorted.next; ds != &unsorted; ds = ds->next) @@ -3142,6 +3144,7 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, portal_t* portal) fixed_t scale; fixed_t lowscale; INT32 silhouette; + INT32 xclip; for (x = x1; x <= x2; x++) { @@ -3314,7 +3317,7 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, portal_t* portal) // all clipping has been performed, so store the values - what, did you think we were drawing them NOW? // check for unclipped columns - for (x = x1; x <= x2; x++) + for (xclip = x = x1; x <= x2; x++) { if (spr->clipbot[x] == CLIP_UNDEF) spr->clipbot[x] = (INT16)viewheight; @@ -3322,9 +3325,17 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, portal_t* portal) if (spr->cliptop[x] == CLIP_UNDEF) //Fab : 26-04-98: was -1, now clips against console bottom spr->cliptop[x] = (INT16)con_clipviewtop; + + // Sprite is completely above or below clip plane + if (spr->szt >= spr->clipbot[x] || spr->sz <= spr->cliptop[x]) + xclip++; } - if (portal) + if (xclip == x) + { + spr->cut |= SC_CULL; // completely skip this sprite going forward + } + else if (portal) { INT32 start_index = max(portal->start, x1); INT32 end_index = min(portal->start + portal->end - portal->start, x2); diff --git a/src/r_things.h b/src/r_things.h index ba44acecd..789e7aab8 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -138,6 +138,7 @@ typedef enum // srb2kart SC_SEMIBRIGHT = 1<<12, SC_BBOX = 1<<13, + SC_CULL = 1<<14, // masks SC_CUTMASK = SC_TOP|SC_BOTTOM, SC_FLAGMASK = ~SC_CUTMASK diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 442109da5..691aaab28 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -1960,6 +1960,12 @@ void I_Error(const char *error, ...) exit(-1); // recursive errors detected } } + else + { + // This makes crashes funnier by stimulating the funnicampus of the brain + S_StopSounds(); + S_StartSound(NULL, sfx_s3k35); + } shutdowning = true; @@ -1989,13 +1995,10 @@ void I_Error(const char *error, ...) D_QuitNetGame(); CL_AbortDownloadResume(); M_FreePlayerSetupColors(); + I_ShutdownMusic(); - I_ShutdownSound(); - // use this for 1.28 19990220 by Kin I_ShutdownGraphics(); I_ShutdownInput(); - I_ShutdownSystem(); - SDL_Quit(); // Implement message box with SDL_ShowSimpleMessageBox, // which should fail gracefully if it can't put a message box up @@ -2005,6 +2008,12 @@ void I_Error(const char *error, ...) "SRB2Kart "VERSIONSTRING" Error", buffer, NULL); + // We wait until now to do this so the funny sound can be heard + I_ShutdownSound(); + // use this for 1.28 19990220 by Kin + I_ShutdownSystem(); + SDL_Quit(); + // Note that SDL_ShowSimpleMessageBox does *not* require SDL to be // initialized at the time, so calling it after SDL_Quit() is // perfectly okay! In addition, we do this on purpose so the diff --git a/src/st_stuff.c b/src/st_stuff.c index 9a471dcbc..2fef9536d 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -242,7 +242,9 @@ void ST_Start(void) ST_Stop(); ST_InitData(); - st_stopped = false; + + if (!dedicated) + st_stopped = false; } //