Exemple #1
0
// restore the players position -- sector must be the same shape
void P_RestorePlayerPosition(void)
{
   sector_t *sec;
   int secnum;
   
   // we always save and restore the psprites
   
   memcpy(save_player->psprites, save_psprites, sizeof(save_player->psprites));
   
   // restore player position from x,y offset
   
   if(save_sectag == -1) return;      // no sector relativeness
   
   if((secnum = P_FindSectorFromTag(save_sectag, -1)) < 0)
   {
      // invalid: sector not found
      return;
   }
   
   sec = &sectors[secnum];
   
   // restore position
   
   P_UnsetThingPosition(save_player->mo);
   
   save_player->mo->x = sec->soundorg.x + save_xoffset;
   save_player->mo->y = sec->soundorg.y + save_yoffset;
   
   // restore various other things
   save_player->mo->angle = save_mobj.angle;
   save_player->mo->momx = save_mobj.momx;    // keep momentum
   save_player->mo->momy = save_mobj.momy;
   
   P_SetThingPosition(save_player->mo);
}
Exemple #2
0
boolean P_TeleportMove(mobj_t * thing, fixed_t x, fixed_t y)
{
    int xl, xh, yl, yh, bx, by;
    subsector_t *newsubsec;

//
// kill anything occupying the position
//

    tmthing = thing;
    tmflags = thing->flags;

    tmx = x;
    tmy = y;

    tmbbox[BOXTOP] = y + tmthing->radius;
    tmbbox[BOXBOTTOM] = y - tmthing->radius;
    tmbbox[BOXRIGHT] = x + tmthing->radius;
    tmbbox[BOXLEFT] = x - tmthing->radius;

    newsubsec = R_PointInSubsector(x, y);
    ceilingline = NULL;

//
// the base floor / ceiling is from the subsector that contains the
// point.  Any contacted lines the step closer together will adjust them
//
    tmfloorz = tmdropoffz = newsubsec->sector->floorheight;
    tmceilingz = newsubsec->sector->ceilingheight;

    validcount++;
    numspechit = 0;

//
// stomp on any things contacted
//
    xl = (tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS) >> MAPBLOCKSHIFT;
    xh = (tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS) >> MAPBLOCKSHIFT;
    yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS) >> MAPBLOCKSHIFT;
    yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS) >> MAPBLOCKSHIFT;

    for (bx = xl; bx <= xh; bx++)
        for (by = yl; by <= yh; by++)
            if (!P_BlockThingsIterator(bx, by, PIT_StompThing))
                return false;

//
// the move is ok, so link the thing into its new position
//      
    P_UnsetThingPosition(thing);

    thing->floorz = tmfloorz;
    thing->ceilingz = tmceilingz;
    thing->x = x;
    thing->y = y;

    P_SetThingPosition(thing);

    return true;
}
Exemple #3
0
// You never thought you needed this, did you? >=D
// Yes, this has the specific purpose of completely screwing you up
// to see if the consistency restoration code can fix you.
// Don't enable this for normal builds...
void Command_CauseCfail_f(void)
{
	if (consoleplayer == serverplayer)
	{
		CONS_Printf("Your reality is everyone's reality. Therefore, you should not use this command.\n");
		return;
	}

	P_UnsetThingPosition(players[consoleplayer].mo);
	P_Random();
	P_Random();
	P_Random();
	players[consoleplayer].mo->x = 0;
	players[consoleplayer].mo->y = 123311; //cfail cansuled kthxbye
	players[consoleplayer].mo->z = 123311;
	players[consoleplayer].score = 1337;
	players[consoleplayer].health = 1337;
	players[consoleplayer].mo->destscale = 25;
	P_SetThingPosition(players[consoleplayer].mo);

	// CTF consistency test
	if (gametype == GT_CTF)
	{
		if (blueflag)
			P_SetMobjState(blueflag, S_DISS);
		if (redflag)
		{
			redflag->x = 423423;
			redflag->y = 666;
			redflag->z = 123311;
		}
	}
}
Exemple #4
0
//
// P_UnArchiveThinkers
//
void P_UnArchiveThinkers (void)
{
    byte		tclass;
    thinker_t*		currentthinker;
    thinker_t*		next;
    mobj_t*		mobj;
    
    // remove all the current thinkers
    currentthinker = thinkercap.next;
    while (currentthinker != &thinkercap)
    {
	next = currentthinker->next;
	
	if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
	    P_RemoveMobj ((mobj_t *)currentthinker);
	else
	    Z_Free (currentthinker);

	currentthinker = next;
    }
    P_InitThinkers ();
	
    // read in saved thinkers
    while (1)
    {
	tclass = *save_p++;
	switch (tclass)
	{
	  case tc_end:
	    return; 	// end of list
			
	  case tc_mobj:
	    PADSAVEP();
	    mobj = (mobj_t*)Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL);
	    memcpy (mobj, save_p, sizeof(*mobj));
	    save_p += sizeof(*mobj);
	    mobj->state = &states[(int)mobj->state];
	    mobj->target = NULL;
	    if (mobj->player)
	    {
		mobj->player = &players[(int)mobj->player-1];
		mobj->player->mo = mobj;
	    }
	    P_SetThingPosition (mobj);
	    mobj->info = &mobjinfo[mobj->type];
	    mobj->floorz = mobj->subsector->sector->floorheight;
	    mobj->ceilingz = mobj->subsector->sector->ceilingheight;
	    mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker;
	    P_AddThinker (&mobj->thinker);
	    break;
			
	  default:
	    I_Error ("Unknown tclass %i in savegame",tclass);
	}
	
    }

}
Exemple #5
0
//
// P_UnArchiveThinkers
//
void P_UnArchiveThinkers (void)
{
    byte		tclass;
    thinker_t*		currentthinker;
    thinker_t*		next;
    mobj_t*		mobj;
    
    // remove all the current thinkers
    currentthinker = thinkercap.next;
    while (currentthinker != &thinkercap)
    {
	next = currentthinker->next;
	
	if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
	    P_RemoveMobj ((mobj_t *)currentthinker);
	else
	    Z_Free (currentthinker);

	currentthinker = next;
    }
    P_InitThinkers ();
    
    // read in saved thinkers
    while (1)
    {
	tclass = saveg_read8();
	switch (tclass)
	{
	  case tc_end:
	    return; 	// end of list
			
	  case tc_mobj:
	    saveg_read_pad();
	    mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL);
            saveg_read_mobj_t(mobj);

	    mobj->target = NULL;
            mobj->tracer = NULL;
	    P_SetThingPosition (mobj);
	    mobj->info = &mobjinfo[mobj->type];
	    mobj->floorz = mobj->subsector->sector->floorheight;
	    mobj->ceilingz = mobj->subsector->sector->ceilingheight;
	    mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker;
	    P_AddThinker (&mobj->thinker);
	    break;

	  default:
	    I_Error ("Unknown tclass %i in savegame",tclass);
	}
	
    }

}
Exemple #6
0
mobj_t *P_SpawnMobj (fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
{
    mobj_t		*mobj;
    state_t		*st;
    mobjinfo_t	*info;

    mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL);

    D_memset (mobj, 0, sizeof (*mobj));
    info = &mobjinfo[type];

    mobj->type = type;
    mobj->info = info;
    mobj->x = x;
    mobj->y = y;
    mobj->radius = info->radius;
    mobj->height = info->height;
    mobj->flags = info->flags;
    mobj->health = info->spawnhealth;
    mobj->reactiontime = info->reactiontime;

    /* do not set the state with P_SetMobjState, because action routines can't */
    /* be called yet */
    st = &states[info->spawnstate];

    mobj->state = st;
    mobj->tics = st->tics;
    mobj->sprite = st->sprite;
    mobj->frame = st->frame;

    /* set subsector and/or block links */
    P_SetThingPosition (mobj);

    mobj->floorz = mobj->subsector->sector->floorheight;
    mobj->ceilingz = mobj->subsector->sector->ceilingheight;
    if (z == ONFLOORZ)
        mobj->z = mobj->floorz;
    else if (z == ONCEILINGZ)
        mobj->z = mobj->ceilingz - mobj->info->height;
    else
        mobj->z = z;

    /* */
    /* link into the mobj list */
    /* */
    mobjhead.prev->next = mobj;
    mobj->next = &mobjhead;
    mobj->prev = mobjhead.prev;
    mobjhead.prev = mobj;

    return mobj;
}
Exemple #7
0
void P_RepositionMace(mobj_t *mo)
{
	int     spot;
	subsector_t *ss;

	P_UnsetThingPosition(mo);
	spot = P_Random() % MaceSpotCount;
	mo->x = MaceSpots[spot].x;
	mo->y = MaceSpots[spot].y;
	ss = R_PointInSubsector(mo->x, mo->y);
	mo->z = mo->floorz = ss->sector->floorheight;
	mo->ceilingz = ss->sector->ceilingheight;
	P_SetThingPosition(mo);
}
Exemple #8
0
//
// Attempt to move to a new position, crossing special lines unless MF_TELEPORT
// is set.
//
void P_TryMove2(void)
{
   trymove2 = false;
   floatok  = false;

   oldx = tmthing->x;
   oldy = tmthing->y;

   PM_CheckPosition();

   if(checkposonly)
   {
      checkposonly = false;
      return;
   }

   if(!trymove2)
      return;

   if(!(tmthing->flags & MF_NOCLIP))
   {
      trymove2 = false;

      if(tmceilingz - tmfloorz < tmthing->height)
         return; // doesn't fit
      floatok = true;
      if(!(tmthing->flags & MF_TELEPORT) && tmceilingz - tmthing->z < tmthing->height)
         return; // mobj must lower itself to fit
      if(!(tmthing->flags & MF_TELEPORT) && tmfloorz - tmthing->z > 24*FRACUNIT)
         return; // too big a step up
      if(!(tmthing->flags & (MF_DROPOFF|MF_FLOAT)) && tmfloorz - tmdropoffz > 24*FRACUNIT)
         return; // don't stand over a dropoff
   }

   // the move is ok, so link the thing into its new position.
   P_UnsetThingPosition(tmthing);
   tmthing->floorz   = tmfloorz;
   tmthing->ceilingz = tmceilingz;
   tmthing->x        = tmx;
   tmthing->y        = tmy;
   P_SetThingPosition(tmthing);

   trymove2 = true;
}
Exemple #9
0
void P_UnArchiveMobjs(void) {
    mobj_t* current;
    mobj_t* next;
    mobj_t* mobj;
    int     i;

    // remove all the current thinkers
    current = mobjhead.next;
    while(current != &mobjhead) {
        next = current->next;
        P_RemoveMobj(current);

        current = next;
    }

    saveg_setup_mobjread();
    mobjhead.next = mobjhead.prev = &mobjhead;

    for(i = 0; i < savegmobjnum; i++) {
        mobj = savegmobj[i].mobj;

        saveg_read_pad();
        saveg_read_mobj_t(mobj);

        if(!saveg_read_marker(SAVEGAME_MOBJ))
            I_Error("P_UnArchiveMobjs: Mobj read is inconsistent\nfile offset: %i\nmobj count: %i",
                    save_offset, savegmobjnum);

        P_SetThingPosition(mobj);
        P_LinkMobj(mobj);

        mobj->info = &mobjinfo[mobj->type];
    }

    saveg_read_pad();
}
Exemple #10
0
static int mobj_set(lua_State *L)
{
	mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
	enum mobj_e field = Lua_optoption(L, 2, mobj_opt[0], mobj_opt);
	lua_settop(L, 3);

	if (!mo)
		return LUA_ErrInvalid(L, "mobj_t");

	if (hud_running)
		return luaL_error(L, "Do not alter mobj_t in HUD rendering code!");

	switch(field)
	{
	case mobj_valid:
		return NOSET;
	case mobj_x:
		return NOSETPOS;
	case mobj_y:
		return NOSETPOS;
	case mobj_z:
	{
		// z doesn't cross sector bounds so it's okay.
		mobj_t *ptmthing = tmthing;
		mo->z = (fixed_t)luaL_checkinteger(L, 3);
		P_CheckPosition(mo, mo->x, mo->y);
		mo->floorz = tmfloorz;
		mo->ceilingz = tmceilingz;
		P_SetTarget(&tmthing, ptmthing);
		break;
	}
	case mobj_snext:
		return NOSETPOS;
	case mobj_sprev:
		return UNIMPLEMENTED;
	case mobj_angle:
		mo->angle = (angle_t)luaL_checkinteger(L, 3);
		if (mo->player == &players[displayplayer])
			localangle = mo->angle;
		else if (mo->player == &players[secondarydisplayplayer])
			localangle2 = mo->angle;
		break;
	case mobj_sprite:
		mo->sprite = luaL_checkinteger(L, 3);
		break;
	case mobj_frame:
		mo->frame = (UINT32)luaL_checkinteger(L, 3);
		break;
	case mobj_touching_sectorlist:
		return UNIMPLEMENTED;
	case mobj_subsector:
		return NOSETPOS;
	case mobj_floorz:
		return NOSETPOS;
	case mobj_ceilingz:
		return NOSETPOS;
	case mobj_radius:
	{
		mobj_t *ptmthing = tmthing;
		mo->radius = (fixed_t)luaL_checkinteger(L, 3);
		if (mo->radius < 0)
			mo->radius = 0;
		P_CheckPosition(mo, mo->x, mo->y);
		mo->floorz = tmfloorz;
		mo->ceilingz = tmceilingz;
		P_SetTarget(&tmthing, ptmthing);
		break;
	}
	case mobj_height:
	{
		mobj_t *ptmthing = tmthing;
		mo->height = (fixed_t)luaL_checkinteger(L, 3);
		if (mo->height < 0)
			mo->height = 0;
		P_CheckPosition(mo, mo->x, mo->y);
		mo->floorz = tmfloorz;
		mo->ceilingz = tmceilingz;
		P_SetTarget(&tmthing, ptmthing);
		break;
	}
	case mobj_momx:
		mo->momx = (fixed_t)luaL_checkinteger(L, 3);
		break;
	case mobj_momy:
		mo->momy = (fixed_t)luaL_checkinteger(L, 3);
		break;
	case mobj_momz:
		mo->momz = (fixed_t)luaL_checkinteger(L, 3);
		break;
	case mobj_pmomz:
		mo->pmomz = (fixed_t)luaL_checkinteger(L, 3);
		break;
	case mobj_tics:
		mo->tics = luaL_checkinteger(L, 3);
		break;
	case mobj_state: // set state by enum
		if (mo->player)
			P_SetPlayerMobjState(mo, luaL_checkinteger(L, 3));
		else
			P_SetMobjState(mo, luaL_checkinteger(L, 3));
		break;
	case mobj_flags: // special handling for MF_NOBLOCKMAP and MF_NOSECTOR
	{
		UINT32 flags = luaL_checkinteger(L, 3);
		if ((flags & (MF_NOBLOCKMAP|MF_NOSECTOR)) != (mo->flags & (MF_NOBLOCKMAP|MF_NOSECTOR)))
		{
			P_UnsetThingPosition(mo);
			mo->flags = flags;
			if (flags & MF_NOSECTOR && sector_list)
			{
				P_DelSeclist(sector_list);
				sector_list = NULL;
			}
			mo->snext = NULL, mo->sprev = NULL;
			mo->bnext = NULL, mo->bprev = NULL;
			P_SetThingPosition(mo);
		}
		else
			mo->flags = flags;
		break;
	}
	case mobj_flags2:
		mo->flags2 = (UINT32)luaL_checkinteger(L, 3);
		break;
	case mobj_eflags:
		mo->eflags = (UINT32)luaL_checkinteger(L, 3);
		break;
	case mobj_skin: // set skin by name
	{
		INT32 i;
		char skin[SKINNAMESIZE+1]; // all skin names are limited to this length
		strlcpy(skin, luaL_checkstring(L, 3), sizeof skin);
		strlwr(skin); // all skin names are lowercase
		for (i = 0; i < numskins; i++)
			if (fastcmp(skins[i].name, skin))
			{
				mo->skin = &skins[i];
				return 0;
			}
		return luaL_error(L, "mobj.skin '%s' not found!", skin);
	}
	case mobj_color:
		mo->color = ((UINT8)luaL_checkinteger(L, 3)) % MAXSKINCOLORS;
		break;
	case mobj_bnext:
		return NOSETPOS;
	case mobj_bprev:
		return UNIMPLEMENTED;
	case mobj_hnext:
		mo->hnext = luaL_checkudata(L, 3, META_MOBJ);
		break;
	case mobj_hprev:
		mo->hprev = luaL_checkudata(L, 3, META_MOBJ);
		break;
	case mobj_type: // yeah sure, we'll let you change the mobj's type.
	{
		mobjtype_t newtype = luaL_checkinteger(L, 3);
		if (newtype > MT_LASTFREESLOT)
			return luaL_error(L, "mobj.type %u is out of bounds.", newtype);
		mo->type = newtype;
		mo->info = &mobjinfo[newtype];
		P_SetScale(mo, mo->scale);
		break;
	}
	case mobj_info:
		return NOSET;
	case mobj_health:
		mo->health = luaL_checkinteger(L, 3);
		break;
	case mobj_movedir:
		mo->movedir = (angle_t)luaL_checkinteger(L, 3);
		break;
	case mobj_movecount:
		mo->movecount = luaL_checkinteger(L, 3);
		break;
	case mobj_target:
		if (lua_isnil(L, 3))
			P_SetTarget(&mo->target, NULL);
		else
		{
			mobj_t *target = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
			P_SetTarget(&mo->target, target);
		}
		break;
	case mobj_reactiontime:
		mo->reactiontime = luaL_checkinteger(L, 3);
		break;
	case mobj_threshold:
		mo->threshold = luaL_checkinteger(L, 3);
		break;
	case mobj_player:
		return NOSET;
	case mobj_lastlook:
		mo->lastlook = luaL_checkinteger(L, 3);
		break;
	case mobj_spawnpoint:
		if (lua_isnil(L, 3))
			mo->spawnpoint = NULL;
		else
		{
			mapthing_t *spawnpoint = *((mapthing_t **)luaL_checkudata(L, 3, META_MAPTHING));
			mo->spawnpoint = spawnpoint;
		}
		break;
	case mobj_tracer:
		if (lua_isnil(L, 3))
			P_SetTarget(&mo->tracer, NULL);
		else
		{
			mobj_t *tracer = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
			P_SetTarget(&mo->tracer, tracer);
		}
		break;
	case mobj_friction:
		mo->friction = (fixed_t)luaL_checkinteger(L, 3);
		break;
	case mobj_movefactor:
		mo->movefactor = (fixed_t)luaL_checkinteger(L, 3);
		break;
	case mobj_fuse:
		mo->fuse = luaL_checkinteger(L, 3);
		break;
	case mobj_watertop:
		mo->watertop = (fixed_t)luaL_checkinteger(L, 3);
		break;
	case mobj_waterbottom:
		mo->waterbottom = (fixed_t)luaL_checkinteger(L, 3);
		break;
	case mobj_mobjnum:
		return UNIMPLEMENTED;
	case mobj_scale:
	{
		fixed_t scale = (fixed_t)luaL_checkinteger(L, 3);
		if (scale < FRACUNIT/100)
			scale = FRACUNIT/100;
		mo->destscale = scale;
		P_SetScale(mo, scale);
		break;
	}
	case mobj_destscale:
	{
		fixed_t scale = (fixed_t)luaL_checkinteger(L, 3);
		if (scale < FRACUNIT/100)
			scale = FRACUNIT/100;
		mo->destscale = scale;
		break;
	}
	case mobj_scalespeed:
		mo->scalespeed = (fixed_t)luaL_checkinteger(L, 3);
		break;
	case mobj_extravalue1:
		mo->extravalue1 = luaL_checkinteger(L, 3);
		break;
	case mobj_extravalue2:
		mo->extravalue2 = luaL_checkinteger(L, 3);
		break;
	case mobj_cusval:
		mo->cusval = luaL_checkinteger(L, 3);
		break;
	case mobj_cvmem:
		mo->cvmem = luaL_checkinteger(L, 3);
		break;
	default:
		lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
		I_Assert(lua_istable(L, -1));
		lua_pushlightuserdata(L, mo);
		lua_rawget(L, -2);
		if (lua_isnil(L, -1)) {
			// This index doesn't have a table for extra values yet, let's make one.
			lua_pop(L, 1);
			CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; adding it as Lua data.\n"), "mobj_t", lua_tostring(L, 2));
			lua_newtable(L);
			lua_pushlightuserdata(L, mo);
			lua_pushvalue(L, -2); // ext value table
			lua_rawset(L, -4); // LREG_EXTVARS table
		}
		lua_pushvalue(L, 2); // key
		lua_pushvalue(L, 3); // value to store
		lua_settable(L, -3);
		lua_pop(L, 2);
		break;
	}
	return 0;
}
Exemple #11
0
//
// P_UnArchiveThinkers
//
void P_UnArchiveThinkers(void)
{
    thinker_t   *currentthinker = thinkers[th_all].next;

    // remove all the current thinkers
    while (currentthinker != &thinkers[th_all])
    {
        thinker_t   *next = currentthinker->next;

        if (currentthinker->function == P_MobjThinker || currentthinker->function == MusInfoThinker)
        {
            P_RemoveMobj((mobj_t *)currentthinker);
            P_RemoveThinkerDelayed(currentthinker);
        }
        else
            Z_Free(currentthinker);

        currentthinker = next;
    }

    P_InitThinkers();

    // remove all bloodsplats
    for (int i = 0; i < numsectors; i++)
    {
        bloodsplat_t    *splat = sectors[i].splatlist;

        while (splat)
        {
            bloodsplat_t    *next = splat->snext;

            P_UnsetBloodSplatPosition(splat);
            splat = next;
        }
    }

    r_bloodsplats_total = 0;
    thingindex = 0;

    // read in saved thinkers
    while (true)
    {
        byte    tclass = saveg_read8();

        switch (tclass)
        {
            case tc_end:
                return;         // end of list

            case tc_mobj:
            {
                mobj_t  *mobj = Z_Calloc(1, sizeof(*mobj), PU_LEVEL, NULL);

                saveg_read_pad();
                saveg_read_mobj_t(mobj);

                mobj->info = &mobjinfo[mobj->type];
                P_SetThingPosition(mobj);

                mobj->thinker.function = (mobj->type == MT_MUSICSOURCE ? MusInfoThinker : P_MobjThinker);
                P_AddThinker(&mobj->thinker);
                mobj->colfunc = mobj->info->colfunc;
                mobj->altcolfunc = mobj->info->altcolfunc;
                P_SetShadowColumnFunction(mobj);
                thingindex = MIN(thingindex + 1, TARGETLIMIT - 1);
                break;
            }

            case tc_bloodsplat:
            {
                bloodsplat_t    *splat = calloc(1, sizeof(*splat));

                saveg_read_pad();
                saveg_read_bloodsplat_t(splat);

                if (r_bloodsplats_total < r_bloodsplats_max)
                {
                    splat->width = spritewidth[splat->patch];
                    splat->sector = R_PointInSubsector(splat->x, splat->y)->sector;
                    P_SetBloodSplatPosition(splat);
                    splat->colfunc = (splat->blood == FUZZYBLOOD ? fuzzcolfunc : bloodsplatcolfunc);
                    r_bloodsplats_total++;
                }

                break;
            }

            default:
                I_Error("This savegame is invalid.");
        }
    }
}
Exemple #12
0
void P_UnArchiveThinkers (void)
{
  thinker_t *th;
  mobj_t    **mobj_p;    // killough 2/14/98: Translation table
  size_t    size;        // killough 2/14/98: size of or index into table

  totallive = 0;
  // killough 3/26/98: Load boss brain state
  memcpy(&brain, save_p, sizeof brain);
  save_p += sizeof brain;

  // remove all the current thinkers
  for (th = thinkercap.next; th != &thinkercap; )
    {
      thinker_t *next = th->next;
      if (th->function == P_MobjThinker)
      {
        P_RemoveMobj ((mobj_t *) th);
        P_RemoveThinkerDelayed(th); // fix mobj leak
      }
      else
        Z_Free (th);
      th = next;
    }
  P_InitThinkers ();

  // killough 2/14/98: count number of thinkers by skipping through them
  {
    byte *sp = save_p;     // save pointer and skip header
    for (size = 1; *save_p++ == tc_mobj; size++)  // killough 2/14/98
      {                     // skip all entries, adding up count
        PADSAVEP();
        save_p += sizeof(mobj_t);//e6y
      }

    if (*--save_p != tc_end)
      I_Error ("P_UnArchiveThinkers: Unknown tclass %i in savegame", *save_p);

    // first table entry special: 0 maps to NULL
    *(mobj_p = malloc(size * sizeof *mobj_p)) = 0;   // table of pointers
    save_p = sp;           // restore save pointer
  }

  // read in saved thinkers
  for (size = 1; *save_p++ == tc_mobj; size++)    // killough 2/14/98
    {
      mobj_t *mobj = Z_Malloc(sizeof(mobj_t), PU_LEVEL, NULL);

      // killough 2/14/98 -- insert pointers to thinkers into table, in order:
      mobj_p[size] = mobj;

      PADSAVEP();

      memcpy (mobj, save_p, sizeof(mobj_t));
      save_p += sizeof(mobj_t);

      mobj->state = states + (int) mobj->state;

      if (mobj->player)
        (mobj->player = &players[(int) mobj->player - 1]) -> mo = mobj;

      P_SetThingPosition (mobj);
      mobj->info = &mobjinfo[mobj->type];

      // killough 2/28/98:
      // Fix for falling down into a wall after savegame loaded:
      //      mobj->floorz = mobj->subsector->sector->floorheight;
      //      mobj->ceilingz = mobj->subsector->sector->ceilingheight;

      mobj->thinker.function = P_MobjThinker;
      P_AddThinker (&mobj->thinker);

      if (!((mobj->flags ^ MF_COUNTKILL) & (MF_FRIEND | MF_COUNTKILL | MF_CORPSE)))
        totallive++;
    }

  // killough 2/14/98: adjust target and tracer fields, plus
  // lastenemy field, to correctly point to mobj thinkers.
  // NULL entries automatically handled by first table entry.
  //
  // killough 11/98: use P_SetNewTarget() to set fields

  for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
    {
      P_SetNewTarget(&((mobj_t *) th)->target,
        mobj_p[P_GetMobj(((mobj_t *)th)->target,size)]);

      P_SetNewTarget(&((mobj_t *) th)->tracer,
        mobj_p[P_GetMobj(((mobj_t *)th)->tracer,size)]);

      P_SetNewTarget(&((mobj_t *) th)->lastenemy,
        mobj_p[P_GetMobj(((mobj_t *)th)->lastenemy,size)]);
    }

  {  // killough 9/14/98: restore soundtargets
    int i;
    for (i = 0; i < numsectors; i++)
    {
      mobj_t *target;
      memcpy(&target, save_p, sizeof target);
      save_p += sizeof target;
      // Must verify soundtarget. See P_ArchiveThinkers.
      P_SetNewTarget(&sectors[i].soundtarget, mobj_p[P_GetMobj(target,size)]);
    }
  }

  free(mobj_p);    // free translation table

  // killough 3/26/98: Spawn icon landings:
  if (gamemode == commercial)
  {
    // P_SpawnBrainTargets overwrites brain.targeton and brain.easy with zero.
    struct brain_s brain_tmp = brain; // saving

    P_SpawnBrainTargets();

    // old demos with save/load tics should not be affected by this fix
    if (!prboom_comp[PC_RESET_MONSTERSPAWNER_PARAMS_AFTER_LOADING].state)
    {
      brain = brain_tmp; // restoring
    }
  }
}
Exemple #13
0
void P_UnArchiveThinkers (void)
{
  thinker_t *th;
  mobj_t    **mobj_p;    // killough 2/14/98: Translation table
  size_t    size;        // killough 2/14/98: size of or index into table

  totallive = 0;
  // killough 3/26/98: Load boss brain state
  memcpy(&brain, save_p, sizeof brain);
  save_p += sizeof brain;

  // remove all the current thinkers
  for (th = thinkercap.next; th != &thinkercap; )
    {
      thinker_t *next = th->next;
      if (th->function == P_MobjThinker)
      {
        P_RemoveMobj ((mobj_t *) th);
        P_RemoveThinkerDelayed(th); // fix mobj leak
      }
      else
        Z_Free (th);
      th = next;
    }
  P_InitThinkers ();

  // killough 2/14/98: count number of thinkers by skipping through them
  {
    byte *sp = save_p;     // save pointer and skip header
    for (size = 1; *save_p++ == tc_mobj; size++)  // killough 2/14/98
      {                     // skip all entries, adding up count
        PADSAVEP();
	/* cph 2006/07/30 - see comment below for change in layout of mobj_t */
        save_p += sizeof(mobj_t)+3*sizeof(void*)-4*sizeof(fixed_t);
      }

    if (*--save_p != tc_end)
      I_Error ("P_UnArchiveThinkers: Unknown tclass %i in savegame", *save_p);

    // first table entry special: 0 maps to NULL
    *(mobj_p = malloc(size * sizeof *mobj_p)) = 0;   // table of pointers
    save_p = sp;           // restore save pointer
  }

  // read in saved thinkers
  for (size = 1; *save_p++ == tc_mobj; size++)    // killough 2/14/98
    {
      mobj_t *mobj = Z_Malloc(sizeof(mobj_t), PU_LEVEL, NULL);

      // killough 2/14/98 -- insert pointers to thinkers into table, in order:
      mobj_p[size] = mobj;

      PADSAVEP();
      /* cph 2006/07/30 - 
       * The end of mobj_t changed from
       *  boolean invisible;
       *  mobj_t* lastenemy;
       *  mobj_t* above_monster;
       *  mobj_t* below_monster;
       *  void* touching_sectorlist;
       * to
       *  mobj_t* lastenemy;
       *  void* touching_sectorlist;
       *  fixed_t PrevX, PrevY, PrevZ;
       * at prboom 2.4.4. There is code here to preserve the savegame format.
       *
       * touching_sectorlist is reconstructed anyway, so we now read in all 
       * but the last 5 words from the savegame (filling all but the last 2
       * fields of our current mobj_t. We then pull lastenemy from the 2nd of
       * the 5 leftover words, and skip the others.
       */
      memcpy (mobj, save_p, sizeof(mobj_t)-2*sizeof(void*)-4*sizeof(fixed_t));
      save_p += sizeof(mobj_t)-sizeof(void*)-4*sizeof(fixed_t);
      memcpy (&(mobj->lastenemy), save_p, sizeof(void*));
      save_p += 4*sizeof(void*);
      mobj->state = states + (int) mobj->state;

      if (mobj->player)
        (mobj->player = &players[(int) mobj->player - 1]) -> mo = mobj;

      P_SetThingPosition (mobj);
      mobj->info = &mobjinfo[mobj->type];

      // killough 2/28/98:
      // Fix for falling down into a wall after savegame loaded:
      //      mobj->floorz = mobj->subsector->sector->floorheight;
      //      mobj->ceilingz = mobj->subsector->sector->ceilingheight;

      mobj->thinker.function = P_MobjThinker;
      P_AddThinker (&mobj->thinker);

      if (!((mobj->flags ^ MF_COUNTKILL) & (MF_FRIEND | MF_COUNTKILL | MF_CORPSE)))
        totallive++;
    }

  // killough 2/14/98: adjust target and tracer fields, plus
  // lastenemy field, to correctly point to mobj thinkers.
  // NULL entries automatically handled by first table entry.
  //
  // killough 11/98: use P_SetNewTarget() to set fields

  for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
    {
      P_SetNewTarget(&((mobj_t *) th)->target,
        mobj_p[P_GetMobj(((mobj_t *)th)->target,size)]);

      P_SetNewTarget(&((mobj_t *) th)->tracer,
        mobj_p[P_GetMobj(((mobj_t *)th)->tracer,size)]);

      P_SetNewTarget(&((mobj_t *) th)->lastenemy,
        mobj_p[P_GetMobj(((mobj_t *)th)->lastenemy,size)]);
    }

  {  // killough 9/14/98: restore soundtargets
    int i;
    for (i = 0; i < numsectors; i++)
    {
      mobj_t *target;
      memcpy(&target, save_p, sizeof target);
      save_p += sizeof target;
      // Must verify soundtarget. See P_ArchiveThinkers.
      P_SetNewTarget(&sectors[i].soundtarget, mobj_p[P_GetMobj(target,size)]);
    }
  }

  free(mobj_p);    // free translation table

  // killough 3/26/98: Spawn icon landings:
  if (gamemode == commercial)
    P_SpawnBrainTargets();
}
Exemple #14
0
//
// P_TeleportMove
//
boolean P_TeleportMove (mobj_t* thing, fixed_t x, fixed_t y, fixed_t z, boolean boss)
{
    int		xl;
    int		xh;
    int		yl;
    int		yh;
    int		bx;
    int		by;
    subsector_t*	newsubsec;

    // monsters don't stomp things except on boss level (30)
    if ((boss)
     || (thing->player)
     || (G_Access_MapInfoTab (gameepisode, gamemap) -> allow_monster_telefrags))
      telefrag = true;
    else
      telefrag = false;

    // kill anything occupying the position
    tmthing = thing;
    tmflags = thing->flags;

    tmx = x;
    tmy = y;
    tmz = z;

    tmbbox[BOXTOP] = y + tmthing->radius;
    tmbbox[BOXBOTTOM] = y - tmthing->radius;
    tmbbox[BOXRIGHT] = x + tmthing->radius;
    tmbbox[BOXLEFT] = x - tmthing->radius;

    newsubsec = R_PointInSubsector (x,y);
    ceilingline = NULL;

    // The base floor/ceiling is from the subsector
    // that contains the point.
    // Any contacted lines the step closer together
    // will adjust them.
    tmfloorz = tmdropoffz = newsubsec->sector->floorheight;
    tmceilingz = newsubsec->sector->ceilingheight;

    validcount++;
    numspechit = 0;

    // stomp on any things contacted
    xl = (tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT;
    xh = (tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT;
    yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
    yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;

    for (bx=xl ; bx<=xh ; bx++)
	for (by=yl ; by<=yh ; by++)
	    if (!P_BlockThingsIterator(bx,by,PIT_StompThing))
		return false;

    // the move is ok,
    // so link the thing into its new position
    P_UnsetThingPosition (thing);

    thing->floorz = tmfloorz;
    thing->ceilingz = tmceilingz;
    thing->x = x;
    thing->y = y;

    P_SetThingPosition (thing);

    return true;
}
Exemple #15
0
//
// ACS_funcSetThingPosition
//
static void ACS_funcSetThingPosition(ACS_FUNCARG)
{
   int32_t tid = args[0];
   fixed_t x   = args[1];
   fixed_t y   = args[2];
   fixed_t z   = args[3];
   bool    fog = args[4] ? true : false;
   Mobj   *mo, *fogmo;

   if((mo = P_FindMobjFromTID(tid, NULL, thread->trigger)))
   {
      fixed_t oldx = mo->x;
      fixed_t oldy = mo->y;
      fixed_t oldz = mo->z;

      mo->z = z;

      if(P_CheckPositionExt(mo, x, y))
      {
         subsector_t *newsubsec;

         newsubsec = R_PointInSubsector(x, y);

         // Set new position.
         P_UnsetThingPosition(mo);

         mo->floorz = mo->dropoffz = newsubsec->sector->floorheight;
         mo->ceilingz = newsubsec->sector->ceilingheight;
         mo->passfloorz = mo->secfloorz = mo->floorz;
         mo->passceilz = mo->secceilz = mo->ceilingz;

         mo->x = x;
         mo->y = y;
         
         mo->backupPosition();
         P_SetThingPosition(mo);


         // Handle fog.
         if(fog)
         {
            // Teleport fog at source...
            fogmo = P_SpawnMobj(oldx, oldy, oldz + GameModeInfo->teleFogHeight,
                                E_SafeThingName(GameModeInfo->teleFogType));
            S_StartSound(fogmo, GameModeInfo->teleSound);

            // ... and destination.
            fogmo = P_SpawnMobj(x, y, z + GameModeInfo->teleFogHeight,
                                E_SafeThingName(GameModeInfo->teleFogType));
            S_StartSound(fogmo, GameModeInfo->teleSound);
         }

         *retn++ = 1;
      }
      else
      {
         mo->z = oldz;

         *retn++ = 0;
      }
   }
   else
      *retn++ = 0;
}
Exemple #16
0
//
// P_UnArchiveThinkers
//
void P_UnArchiveThinkers (void)
{
    byte                tclass;
    thinker_t*          currentthinker;
    thinker_t*          next;
    mobj_t*             mobj;
    
    // remove all the current thinkers
    currentthinker = thinkercap.next;
    while (currentthinker != &thinkercap)
    {
        next = currentthinker->next;

        if (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker)
            P_RemoveMobj ((mobj_t *)currentthinker);
        else
            Z_Free (currentthinker);

        currentthinker = next;
    }
    P_InitThinkers ();
    
    // read in saved thinkers
    while (1)
    {
        tclass = saveg_read8();
        switch (tclass)
        {
        case tc_end:
            return; 	// end of list

        case tc_mobj:
            saveg_read_pad();
            mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL);
            saveg_read_mobj_t(mobj);

            // haleyjd 09/29/10: Strife sets the targets of non-allied creatures
            // who had a non-NULL target at save time to players[0].mo so that
            // they won't fall back asleep.
            //
            // BUG: As the player may not have been spawned yet, we could be
            // setting monsters' targets to the mobj which was spawned by 
            // P_SetupLevel and then removed just above. Due to a subtle glitch
            // in the DOOM engine whereby all things removed in this function
            // are leaked until the next time P_SetupLevel is called, this is a
            // safe operation - the call to P_InitThinkers above stops any of
            // the objects removed, including the player's previous body, from
            // being passed to Z_Free. One glitch relying on another!

            if(mobj->target != NULL && (mobj->flags & MF_ALLY) != MF_ALLY)
                mobj->target = players[0].mo;
            else
                mobj->target = NULL;

            // WARNING! Strife does not seem to set tracer! I am leaving it be
            // for now because so far no crashes have been observed, and failing
            // to set this here will almost certainly crash Choco.
            mobj->tracer = NULL;
            P_SetThingPosition (mobj);
            mobj->info = &mobjinfo[mobj->type];
            // [STRIFE]: doesn't set these
            //mobj->floorz = mobj->subsector->sector->floorheight;
            //mobj->ceilingz = mobj->subsector->sector->ceilingheight;
            mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker;
            P_AddThinker (&mobj->thinker);
            break;

        default:
            I_Error ("Unknown tclass %i in savegame",tclass);
        }
    }
}
Exemple #17
0
void P_UnArchiveThinkers (void)
{
   thinker_t *th;
   mobj_t    **mobj_p;    // killough 2/14/98: Translation table
   size_t    size;        // killough 2/14/98: size of or index into table

   totallive = 0;
   // killough 3/26/98: Load boss brain state
   memcpy(&brain, save_p, sizeof brain);
   save_p += sizeof brain;

   // remove all the current thinkers
   for (th = thinkercap.next; th != &thinkercap; )
   {
      thinker_t *next = th->next;
      if (th->function == P_MobjThinker)
         P_RemoveMobj ((mobj_t *) th);
      else
         Z_Free (th);
      th = next;
   }
   P_InitThinkers ();

   // killough 2/14/98: count number of thinkers by skipping through them
   {
      byte *sp = save_p;     // save pointer and skip header
      for (size = 1; *save_p++ == tc_mobj; size++)  // killough 2/14/98
      {                     // skip all entries, adding up count
         PADSAVEP();
         save_p += sizeof(mobj_t);
      }

      if (*--save_p != tc_end)
         I_Error ("P_UnArchiveThinkers: Unknown tclass %i in savegame", *save_p);

      // first table entry special: 0 maps to NULL
      *(mobj_p = malloc(size * sizeof *mobj_p)) = 0;   // table of pointers
      save_p = sp;           // restore save pointer
   }

   // read in saved thinkers
   for (size = 1; *save_p++ == tc_mobj; size++)    // killough 2/14/98
   {
      mobj_t *mobj = Z_Malloc(sizeof(mobj_t), PU_LEVEL, NULL);

      // killough 2/14/98 -- insert pointers to thinkers into table, in order:
      mobj_p[size] = mobj;

      PADSAVEP();
      memcpy (mobj, save_p, sizeof(mobj_t));
      save_p += sizeof(mobj_t);
      mobj->state = states + (unsigned long) mobj->state;

      if (mobj->player)
         (mobj->player = &players[(unsigned long) mobj->player - 1]) -> mo = mobj;

      P_SetThingPosition (mobj);
      mobj->info = &mobjinfo[mobj->type];

      // killough 2/28/98:
      // Fix for falling down into a wall after savegame loaded:
      //      mobj->floorz = mobj->subsector->sector->floorheight;
      //      mobj->ceilingz = mobj->subsector->sector->ceilingheight;

      mobj->thinker.function = P_MobjThinker;
      P_AddThinker (&mobj->thinker);

      if (!((mobj->flags ^ MF_COUNTKILL) & (MF_FRIEND | MF_COUNTKILL | MF_CORPSE)))
         totallive++;
   }

   // killough 2/14/98: adjust target and tracer fields, plus
   // lastenemy field, to correctly point to mobj thinkers.
   // NULL entries automatically handled by first table entry.
   //
   // killough 11/98: use P_SetNewTarget() to set fields

   for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
   {
      P_SetNewTarget(&((mobj_t *) th)->target,
                     mobj_p[(size_t)((mobj_t *)th)->target]);

      P_SetNewTarget(&((mobj_t *) th)->tracer,
                     mobj_p[(size_t)((mobj_t *)th)->tracer]);

      P_SetNewTarget(&((mobj_t *) th)->lastenemy,
                     mobj_p[(size_t)((mobj_t *)th)->lastenemy]);

      // phares: added two new fields for Sprite Height problem

      P_SetNewTarget(&((mobj_t *) th)->above_thing,
                     mobj_p[(size_t)((mobj_t *)th)->above_thing]);

      P_SetNewTarget(&((mobj_t *) th)->below_thing,
                     mobj_p[(size_t)((mobj_t *)th)->below_thing]);
   }

   {  // killough 9/14/98: restore soundtargets
      int i;
      for (i = 0; i < numsectors; i++)
      {
         mobj_t *target;
         memcpy(&target, save_p, sizeof target);
         save_p += sizeof target;
         P_SetNewTarget(&sectors[i].soundtarget, mobj_p[(size_t) target]);
      }
   }

   free(mobj_p);    // free translation table

   // killough 3/26/98: Spawn icon landings:
   if (gamemode == commercial)
      P_SpawnBrainTargets();
}
Exemple #18
0
//
// P_UnArchiveThinkers
//
void P_v19_UnArchiveThinkers(void)
{
	byte    tclass;
	thinker_t *currentthinker;
	thinker_t *next;
	mobj_t *mobj;

	// remove all the current thinkers
	currentthinker = thinkercap.next;
	while(currentthinker != &thinkercap)
	{
		next = currentthinker->next;

		if(currentthinker->function == P_MobjThinker)
			P_RemoveMobj((mobj_t *) currentthinker);
		else
			Z_Free(currentthinker);

		currentthinker = next;
	}
	P_InitThinkers();

	// read in saved thinkers
	while(1)
	{
		tclass = *save_p++;
		switch (tclass)
		{
		case tc_end:
			return;				// end of list

		case tc_mobj:
			PADSAVEP();
			mobj = Z_Malloc(sizeof(*mobj), PU_LEVEL, NULL);
			memset(mobj, 0, sizeof(*mobj));
			//memcpy (mobj, save_p, sizeof(*mobj));
			//P_MobjConverter(mobj, (savemobj_t*) save_p, false);
			//memcpy(mobj, save_p, sizeof(*mobj));
			SV_ReadMobj(mobj);
			//save_p += sizeof(savemobj_t);
			mobj->state = &states[(int) mobj->state];
			mobj->target = NULL;
			if(mobj->player)
			{
				int     pnum = (int) mobj->player - 1;

				mobj->player = &players[pnum];
				mobj->dplayer = mobj->player->plr;
				mobj->dplayer->mo = mobj;
				mobj->dplayer->clAngle = mobj->angle;
				mobj->dplayer->clLookDir = 0;
			}
			P_SetThingPosition(mobj);
			mobj->info = &mobjinfo[mobj->type];
			mobj->floorz = mobj->subsector->sector->floorheight;
			mobj->ceilingz = mobj->subsector->sector->ceilingheight;
			mobj->thinker.function = P_MobjThinker;
			P_AddThinker(&mobj->thinker);
			break;

		default:
			Con_Error("Unknown tclass %i in savegame", tclass);
		}
	}
}