Beispiel #1
0
void P_CloseWeapons(void)
{
	int     spot;

	if(!MaceSpotCount)
	{							// No maces placed
		return;
	}
	if(!deathmatch && P_Random() < 64)
	{							// Sometimes doesn't show up if not in deathmatch
		return;
	}
	spot = P_Random() % MaceSpotCount;
	P_SpawnMobj(MaceSpots[spot].x, MaceSpots[spot].y, ONFLOORZ, MT_WMACE);
}
Beispiel #2
0
void P_SpawnPuff (fixed_t x, fixed_t y, fixed_t z)
{
    mobj_t	*th;

    z += ((P_Random()-P_Random())<<10);
    th = P_SpawnMobj (x,y,z, MT_PUFF);
    th->momz = FRACUNIT;
    th->tics -= P_Random()&1;
    if (th->tics < 1)
        th->tics = 1;

    /* don't make punches spark on the wall */
    if (attackrange == MELEERANGE)
        P_SetMobjState (th, S_PUFF3);
}
Beispiel #3
0
void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, int damage)
{
    mobj_t	*th;

    z += ((P_Random()-P_Random())<<10);
    th = P_SpawnMobj (x,y,z, MT_BLOOD);
    th->momz = FRACUNIT*2;
    th->tics -= P_Random()&1;
    if (th->tics<1)
        th->tics = 1;
    if (damage <= 12 && damage >= 9)
        P_SetMobjState (th,S_BLOOD2);
    else if (damage < 9)
        P_SetMobjState (th,S_BLOOD3);
}
Beispiel #4
0
//
// P_GiveCard
//
static dboolean P_GiveCard(player_t* player, mobj_t *item, card_t card) {
    if(netgame && (item && item->flags & MF_TRIGTOUCH)) {
        P_SpawnMobj(item->x, item->y, item->z, item->type);
        return true;
    }

    if(player->cards[card]) {
        return false;
    }

    player->bonuscount = BONUSADD;
    player->cards[card] = 1;

    switch(card) {
    case it_bluecard:
        player->message = GOTBLUECARD;
        player->messagepic = 25;
        break;
    case it_yellowcard:
        player->message = GOTYELWCARD;
        player->messagepic = 26;
        break;
    case it_redcard:
        player->message = GOTREDCARD;
        player->messagepic = 27;
        break;
    case it_blueskull:
        player->message = GOTBLUESKUL;
        player->messagepic = 28;
        break;
    case it_yellowskull:
        player->message = GOTYELWSKUL;
        player->messagepic = 29;
        break;
    case it_redskull:
        player->message = GOTREDSKULL;
        player->messagepic = 30;
        break;
    }

    if(netgame) {
        return false;
    }

    return true;
}
Beispiel #5
0
void P_SpawnPlayer (mapthing_t *mthing)
{
    player_t	*p;
    fixed_t		x,y,z;
    mobj_t		*mobj;
    int	i;

    if (!playeringame[mthing->type-1])
        return;						/* not playing */

    p = &players[mthing->type-1];

    if (p->playerstate == PST_REBORN)
        G_PlayerReborn (mthing->type-1);

    x = mthing->x << FRACBITS;
    y = mthing->y << FRACBITS;
#if 0
    if (mthing->type==1)
    {
        x = 0xffb00000;
        y = 0xff500000;
    }
#endif
    z = ONFLOORZ;
    mobj = P_SpawnMobj (x,y,z, MT_PLAYER);

    mobj->angle = ANG45 * (mthing->angle/45);

    mobj->player = p;
    mobj->health = p->health;
    p->mo = mobj;
    p->playerstate = PST_LIVE;
    p->refire = 0;
    p->message = NULL;
    p->damagecount = 0;
    p->bonuscount = 0;
    p->extralight = 0;
    p->fixedcolormap = 0;
    p->viewheight = VIEWHEIGHT;
    P_SetupPsprites (p);		/* setup gun psprite	 */

    if (netgame == gt_deathmatch)
        for (i=0 ; i<NUMCARDS ; i++)
            p->cards[i] = true;		/* give all cards in death match mode			 */
}
Beispiel #6
0
void P_SpawnTelefog(mobj_t *mo, void * /*context*/)
{
#if __JDOOM__ || __JDOOM64__
    S_StartSound(SFX_ITMBK, mo);
#else
    S_StartSound(SFX_RESPAWN, mo);
#endif

# if __JDOOM64__
    mo->translucency = 255;
    mo->spawnFadeTics = 0;
    mo->intFlags |= MIF_FADE;
# elif __JDOOM__
    // Spawn the item teleport fog at the new spot.
    P_SpawnMobj(MT_IFOG, mo->origin, mo->angle, 0);
# endif
}
Beispiel #7
0
void C_DECL A_FogSpawn(mobj_t* actor)
{
    mobj_t*             mo = NULL;
    mobjtype_t          type = 0;
    angle_t             delta, angle;

    if(actor->special1-- > 0)
        return;

    actor->special1 = actor->args[2]; // Reset frequency count.

    switch(P_Random() % 3)
    {
    case 0:
        type = MT_FOGPATCHS;
        break;
    case 1:
        type = MT_FOGPATCHM;
        break;
    case 2:
        type = MT_FOGPATCHL;
        break;
    }

    delta = actor->args[1];
    if(delta == 0)
        delta = 1;

    angle = ((P_Random() % delta) - (delta / 2));
    angle <<= 24;

    if((mo = P_SpawnMobj(type, actor->origin, actor->angle + angle, 0)))
    {
        mo->target = actor;
        if(actor->args[0] < 1)
            actor->args[0] = 1;
        mo->args[0] = (P_Random() % (actor->args[0])) + 1; // Random speed.
        mo->args[3] = actor->args[3]; // Set lifetime.
        mo->args[4] = 1; // Set to moving.
        mo->special2 = P_Random() & 63;
    }
}
Beispiel #8
0
//
// ACS_spawn
//
static Mobj *ACS_spawn(mobjtype_t type, fixed_t x, fixed_t y, fixed_t z,
                       int tid, angle_t angle, bool forced)
{
   Mobj *mo;
   if(type != -1 && (mo = P_SpawnMobj(x, y, z, type)))
   {
      // If not forcing spawn, check that the position is OK.
      if(!forced && !P_CheckPositionExt(mo, mo->x, mo->y))
      {
         // And if not, unmake the Mobj.
         mo->state = NULL;
         mo->removeThinker();
         return NULL;
      }

      if(tid) P_AddThingTID(mo, tid);
      mo->angle = angle;
      return mo;
   }
   else
      return NULL;
}
Beispiel #9
0
boolean G_CheckSpot (int playernum, mapthing_t *mthing) 
{ 
	fixed_t         x,y; 
	subsector_t *ss; 
	int                     an; 
	mobj_t		*mo;
	
	x = mthing->x << FRACBITS; 
	y = mthing->y << FRACBITS; 
	 
	if (!P_CheckPosition (players[playernum].mo, x, y) ) 
		return false; 
 
	ss = R_PointInSubsector (x,y); 
	an = ( ANG45 * (mthing->angle/45) ) >> ANGLETOFINESHIFT; 
 
/* spawn a teleport fog  */
	mo = P_SpawnMobj (x+20*finecosine[an], y+20*finesine[an], ss->sector->floorheight 
	, MT_TFOG); 
	S_StartSound (mo, sfx_telept);
	
	return true; 
} 
Beispiel #10
0
static CMD(SpawnThing) {
    int id = 0;
    player_t *player;
    mobj_t *thing;
    fixed_t x, y, z;

    if(gamestate != GS_LEVEL) {
        return;
    }

    if(!param[0]) {
        return;
    }

    if(netgame) {
        return;
    }

    id = datoi(param[0]);
    if(id >= NUMMOBJTYPES || id < 0) {
        return;
    }

    player = &players[consoleplayer];
    x = player->mo->x + FixedMul(INT2F(64) + mobjinfo[id].radius, dcos(player->mo->angle));
    y = player->mo->y + FixedMul(INT2F(64) + mobjinfo[id].radius, dsin(player->mo->angle));
    z = player->mo->z;

    thing = P_SpawnMobj(x, y, z, id);

    if(thing->info->spawnstate == S_000) {
        P_RemoveMobj(thing);
        return;
    }

    thing->angle = player->mo->angle;
}
Beispiel #11
0
//
// TELEPORTATION
//
dboolean EV_Teleport(line_t *line, int side, mobj_t *thing)
{
    thinker_t   *thinker;
    int         i;

    // Don't teleport missiles.
    // Don't teleport if hit back of line, so you can get out of teleporter.
    if (side || (thing->flags & MF_MISSILE))
        return false;

    // killough 1/31/98: improve performance by using
    // P_FindSectorFromLineTag instead of simple linear search.
    for (i = -1; (i = P_FindSectorFromLineTag(line, i)) >= 0;)
        for (thinker = thinkerclasscap[th_mobj].cnext; thinker != &thinkerclasscap[th_mobj];
            thinker = thinker->cnext)
        {
            mobj_t  *m;

            if ((m = (mobj_t *)thinker)->type == MT_TELEPORTMAN
                && m->subsector->sector - sectors == i)
            {
                fixed_t     oldx = thing->x;
                fixed_t     oldy = thing->y;
                fixed_t     oldz = thing->z;
                player_t    *player = thing->player;

                // killough 5/12/98: exclude voodoo dolls:
                if (player && player->mo != thing)
                    player = NULL;

                if (P_TeleportMove(thing, m->x, m->y, m->z, false))     // killough 8/9/98
                {
                    mobj_t  *fog;
                    fixed_t newx = m->x;
                    fixed_t newy = m->y;

                    // spawn teleport fog at source
                    fog = P_SpawnMobj(oldx, oldy, oldz, MT_TFOG);
                    fog->angle = thing->angle;
                    S_StartSound(fog, sfx_telept);

                    // spawn teleport fog at destination
                    thing->z = thing->floorz;
                    if (player)
                    {
                        unsigned int    an = m->angle >> ANGLETOFINESHIFT;

                        newx += 20 * finecosine[an];
                        newy += 20 * finesine[an];
                        player->viewz = thing->z + player->viewheight;
                    }
                    fog = P_SpawnMobj(newx, newy, thing->z, MT_TFOG);
                    fog->angle = m->angle;
                    S_StartSound(fog, sfx_telept);

                    if (player)
                    {
                        // [BH] teleport can be drawn on automap
                        if (line->backsector)
                        {
                            int j;

                            for (j = 0; j < line->backsector->linecount; j++)
                                line->backsector->lines[j]->flags |= ML_TELEPORTTRIGGERED;
                        }

                        // don't move for a bit
                        thing->reactiontime = 18;

                        player->psprites[ps_weapon].sx = 0;
                        player->psprites[ps_weapon].sy = WEAPONTOP;

                        player->momx = player->momy = 0;
                    }

                    thing->angle = m->angle;

                    thing->momx = thing->momy = thing->momz = 0;

                    return true;
                }
            }
Beispiel #12
0
//
// TELEPORTATION
//
int
EV_Teleport
( line_t*	line,
  int		side,
  mobj_t*	thing )
{
    int		i;
    int		tag;
    mobj_t*	m;
    mobj_t*	fog;
    unsigned	an;
    thinker_t*	thinker;
    sector_t*	sector;
    fixed_t	oldx;
    fixed_t	oldy;
    fixed_t	oldz;

    // don't teleport missiles
    if (thing->flags & MF_MISSILE)
	return 0;		

    // Don't teleport if hit back of line,
    //  so you can get out of teleporter.
    if (side == 1)		
	return 0;	

    
    tag = line->tag;
    for (i = 0; i < numsectors; i++)
    {
	if (sectors[ i ].tag == tag )
	{
	    thinker = thinkercap.next;
	    for (thinker = thinkercap.next;
		 thinker != &thinkercap;
		 thinker = thinker->next)
	    {
		// not a mobj
		if (thinker->function.acp1 != (actionf_p1)P_MobjThinker)
		    continue;	

		m = (mobj_t *)thinker;
		
		// not a teleportman
		if (m->type != MT_TELEPORTMAN )
		    continue;		

		sector = m->subsector->sector;
		// wrong sector
		if (sector-sectors != i )
		    continue;	

		oldx = thing->x;
		oldy = thing->y;
		oldz = thing->z;
				
		if (!P_TeleportMove (thing, m->x, m->y))
		    return 0;

                // The first Final Doom executable does not set thing->z
                // when teleporting. This quirk is unique to this
                // particular version; the later version included in
                // some versions of the Id Anthology fixed this.

                if (gameversion != exe_final)
		    thing->z = thing->floorz;

		if (thing->player)
		    thing->player->viewz = thing->z+thing->player->viewheight;

		// spawn teleport fog at source and destination
		fog = P_SpawnMobj (oldx, oldy, oldz, MT_TFOG);
		S_StartSound (fog, sfx_telept);
		an = m->angle >> ANGLETOFINESHIFT;
		fog = P_SpawnMobj (m->x+20*finecosine[an], m->y+20*finesine[an]
				   , thing->z, MT_TFOG);

		// emit sound, where?
		S_StartSound (fog, sfx_telept);
		
		// don't move for a bit
		if (thing->player)
		    thing->reactiontime = 18;	

		thing->angle = m->angle;
		thing->momx = thing->momy = thing->momz = 0;
		return 1;
	    }	
	}
    }
Beispiel #13
0
void P_SetupLevel(int map, skill_t skill)
{
    int          i;
    static char  lumpname[16];
    int          lumpnum;
    mobj_t      *mobj;
    extern int   cy;

    M_ClearRandom();

    P_LoadingPlaque();

    D_printf("P_SetupLevel(%i,%i)\n", map, skill);

    totalkills = totalitems = totalsecret = 0;
    for(i = 0; i < MAXPLAYERS; i++)
        players[i].killcount = players[i].secretcount = players[i].itemcount = 0;

    Z_CheckHeap(mainzone);
    Z_CheckHeap(refzone);

    Z_FreeTags(mainzone);

    P_InitThinkers();

    //
    // look for a regular (development) map first
    //
    lumpname[0] = 'M';
    lumpname[1] = 'A';
    lumpname[2] = 'P';
    lumpname[3] = '0' + map / 10;
    lumpname[4] = '0' + map % 10;
    lumpname[5] = 0;

    lumpnum = W_GetNumForName(lumpname);

    // note: most of this ordering is important
    P_LoadBlockMap(lumpnum+ML_BLOCKMAP);
    P_LoadVertexes(lumpnum+ML_VERTEXES);
    P_LoadSectors(lumpnum+ML_SECTORS);
    P_LoadSideDefs(lumpnum+ML_SIDEDEFS);
    P_LoadLineDefs(lumpnum+ML_LINEDEFS);
    P_LoadSubsectors(lumpnum+ML_SSECTORS);
    P_LoadNodes(lumpnum+ML_NODES);
    P_LoadSegs(lumpnum+ML_SEGS);

    rejectmatrix = W_CacheLumpNum(lumpnum + ML_REJECT, PU_LEVEL);

    P_GroupLines();

    deathmatch_p = deathmatchstarts;
    P_LoadThings(lumpnum + ML_THINGS);

    //
    // if deathmatch, randomly spawn the active players
    //
    if(netgame == gt_deathmatch)
    {
        for(i = 0; i < MAXPLAYERS; i++)
        {
            if(playeringame[i])
            {
                // must give a player spot before deathmatchspawn
                mobj = P_SpawnMobj(deathmatchstarts[0].x << 16 ,deathmatchstarts[0].y << 16, 0, MT_PLAYER);
                players[i].mo = mobj;
                G_DeathMatchSpawnPlayer(i);
                P_RemoveMobj(mobj);
            }
        }
    }

    // set up world state
    P_SpawnSpecials();
    ST_InitEveryLevel();

    cy = 4;

    iquehead = iquetail = 0;
    gamepaused = false;
}
Beispiel #14
0
static void P_LightningFlash(void)
{
	int     i;
	sector_t *tempSec;
	int    *tempLight;
	boolean foundSec;
	int     flashLight;

	if(LightningFlash)
	{
		LightningFlash--;
		if(LightningFlash)
		{
			tempLight = LightningLightLevels;
			tempSec = sectors;
			for(i = 0; i < numsectors; i++, tempSec++)
			{
				if(tempSec->ceilingpic == skyflatnum ||
				   tempSec->special == LIGHTNING_SPECIAL ||
				   tempSec->special == LIGHTNING_SPECIAL2)
				{
					if(*tempLight < tempSec->lightlevel - 4)
					{
						tempSec->lightlevel -= 4;
					}
					tempLight++;
				}
			}
		}
		else
		{						// remove the alternate lightning flash special
			tempLight = LightningLightLevels;
			tempSec = sectors;
			for(i = 0; i < numsectors; i++, tempSec++)
			{
				if(tempSec->ceilingpic == skyflatnum ||
				   tempSec->special == LIGHTNING_SPECIAL ||
				   tempSec->special == LIGHTNING_SPECIAL2)
				{
					tempSec->lightlevel = *tempLight;
					tempLight++;
				}
			}
			Rend_SkyParams(1, DD_DISABLE, 0);
			Rend_SkyParams(0, DD_ENABLE, 0);
			//Sky1Texture = P_GetMapSky1Texture(gamemap);       
		}
		return;
	}
	LightningFlash = (P_Random() & 7) + 8;
	flashLight = 200 + (P_Random() & 31);
	tempSec = sectors;
	tempLight = LightningLightLevels;
	foundSec = false;
	for(i = 0; i < numsectors; i++, tempSec++)
	{
		if(tempSec->ceilingpic == skyflatnum ||
		   tempSec->special == LIGHTNING_SPECIAL ||
		   tempSec->special == LIGHTNING_SPECIAL2)
		{
			*tempLight = tempSec->lightlevel;
			if(tempSec->special == LIGHTNING_SPECIAL)
			{
				tempSec->lightlevel += 64;
				if(tempSec->lightlevel > flashLight)
				{
					tempSec->lightlevel = flashLight;
				}
			}
			else if(tempSec->special == LIGHTNING_SPECIAL2)
			{
				tempSec->lightlevel += 32;
				if(tempSec->lightlevel > flashLight)
				{
					tempSec->lightlevel = flashLight;
				}
			}
			else
			{
				tempSec->lightlevel = flashLight;
			}
			if(tempSec->lightlevel < *tempLight)
			{
				tempSec->lightlevel = *tempLight;
			}
			tempLight++;
			foundSec = true;
		}
	}
	if(foundSec)
	{
		mobj_t *plrmo = players[displayplayer].plr->mo;
		mobj_t *crashorigin = NULL;

		// Set the alternate (lightning) sky.
		Rend_SkyParams(0, DD_DISABLE, 0);
		Rend_SkyParams(1, DD_ENABLE, 0);
		// If 3D sounds are active, position the clap somewhere above
		// the player.
		if(cfg.snd_3D && plrmo)
		{
			// SpawnMobj calls P_Random, and we don't want that the 
			// random number generator gets out of sync.
			//P_SaveRandom(); 
			crashorigin =
				P_SpawnMobj(plrmo->x + (16 * (M_Random() - 127) << FRACBITS),
							plrmo->y + (16 * (M_Random() - 127) << FRACBITS),
							plrmo->z + (4000 << FRACBITS), MT_CAMERA);
			//P_RestoreRandom();
			crashorigin->tics = 5 * 35;	// Five seconds will do.
		}
		// Make it loud!
		S_StartSound(SFX_THUNDER_CRASH | DDSF_NO_ATTENUATION, crashorigin);
	}
	// Calculate the next lighting flash
	if(!NextLightningFlash)
	{
		if(P_Random() < 50)
		{						// Immediate Quick flash
			NextLightningFlash = (P_Random() & 15) + 16;
		}
		else
		{
			if(P_Random() < 128 && !(leveltime & 32))
			{
				NextLightningFlash = ((P_Random() & 7) + 2) * 35;
			}
			else
			{
				NextLightningFlash = ((P_Random() & 15) + 5) * 35;
			}
		}
	}
}
Beispiel #15
0
void P_SetupLevel(int episode, int map, int playermask, skill_t skill)
{
	int i;
	int parm;
	char lumpname[9];
	char auxName[128];
	int lumpnum;
	mobj_t *mobj;

	for(i = 0; i < MAXPLAYERS; i++)
	{
		players[i].killcount = players[i].secretcount
			= players[i].itemcount = 0;
	}
	players[consoleplayer].viewz = 1; // will be set by player think

#ifdef __WATCOMC__
	if(i_CDMusic == false)
	{
		S_StartSongName("chess", true); // Waiting-for-level-load song
	}
#endif

	Z_FreeTags(PU_LEVEL, PU_PURGELEVEL-1);

	P_InitThinkers();
	leveltime = 0;

	if(DevMaps)
	{
		sprintf(auxName, "%sMAP%02d.WAD", DevMapsDir, map);
		W_OpenAuxiliary(auxName);
	}
	sprintf(lumpname, "MAP%02d", map);
	lumpnum = W_GetNumForName(lumpname);
	//
	// Begin processing map lumps
	// Note: most of this ordering is important
	//
	P_LoadBlockMap(lumpnum+ML_BLOCKMAP);
	P_LoadVertexes(lumpnum+ML_VERTEXES);
	P_LoadSectors(lumpnum+ML_SECTORS);
	P_LoadSideDefs(lumpnum+ML_SIDEDEFS);
	P_LoadLineDefs(lumpnum+ML_LINEDEFS);
	P_LoadSubsectors(lumpnum+ML_SSECTORS);
	P_LoadNodes(lumpnum+ML_NODES);
	P_LoadSegs(lumpnum+ML_SEGS);
	rejectmatrix = W_CacheLumpNum(lumpnum+ML_REJECT, PU_LEVEL);
	P_GroupLines();
	bodyqueslot = 0;
	po_NumPolyobjs = 0;
	deathmatch_p = deathmatchstarts;
	P_LoadThings(lumpnum+ML_THINGS);
	PO_Init(lumpnum+ML_THINGS); // Initialize the polyobjs
	P_LoadACScripts(lumpnum+ML_BEHAVIOR); // ACS object code
	//
	// End of map lump processing
	//
	if(DevMaps)
	{
		// Close the auxiliary file, but don't free its loaded lumps.
		// The next call to W_OpenAuxiliary() will do a full shutdown
		// of the current auxiliary WAD (free lumps and info lists).
		W_CloseAuxiliaryFile();
		W_UsePrimary();
	}

	// If deathmatch, randomly spawn the active players
	TimerGame = 0;
	if(deathmatch)
	{
		for (i=0 ; i<MAXPLAYERS ; i++)
		{
			if (playeringame[i])
			{   // must give a player spot before deathmatchspawn
				mobj = P_SpawnMobj (playerstarts[0][i].x<<16,
					playerstarts[0][i].y<<16,0, MT_PLAYER_FIGHTER);
				players[i].mo = mobj;
				G_DeathMatchSpawnPlayer (i);
				P_RemoveMobj (mobj);
			}
		}
		parm = M_CheckParm("-timer");
		if(parm && parm < myargc-1)
		{
			TimerGame = atoi(myargv[parm+1])*35*60;
		}
	}

// set up world state
	P_SpawnSpecials ();

// build subsector connect matrix
//      P_ConnectSubsectors ();

// Load colormap and set the fullbright flag
	i = P_GetMapFadeTable(gamemap);
	W_ReadLump(i, colormaps);
	if(i == W_GetNumForName("COLORMAP"))
	{
		LevelUseFullBright = true;
	}
	else
	{ // Probably fog ... don't use fullbright sprites
		LevelUseFullBright = false;
	}

// preload graphics
	if (precache)
		R_PrecacheLevel ();

	// Check if the level is a lightning level
	P_InitLightning();

	S_StopAllSound();
	SN_StopAllSequences();
	S_StartSong(gamemap, true);

//printf ("free memory: 0x%x\n", Z_FreeMemory());

}
Beispiel #16
0
int EV_Teleport(Line* line, int side, mobj_t* mo, dd_bool spawnFog)
{
    mobj_t* dest;

    // Clients cannot teleport on their own.
    if(IS_CLIENT) return 0;

    if(mo->flags2 & MF2_NOTELEPORT) return 0;

    // Don't teleport if hit back of line, so you can get out of teleporter.
    if(side == 1) return 0;

    if((dest = getTeleportDestination(P_ToXLine(line)->tag)) != NULL)
    {
        // A suitable destination has been found.
        coord_t oldPos[3], aboveFloor;
        angle_t oldAngle;
        mobj_t* fog;
        uint an;

        memcpy(oldPos, mo->origin, sizeof(mo->origin));
        oldAngle = mo->angle;
        aboveFloor = mo->origin[VZ] - mo->floorZ;

        if(!P_TeleportMove(mo, dest->origin[VX], dest->origin[VY], false))
            return 0;

        mo->origin[VZ] = mo->floorZ;

        if(spawnFog)
        {
            // Spawn teleport fog at source and destination.
            if((fog = P_SpawnMobj(MT_TFOG, oldPos, oldAngle + ANG180, 0)))
                S_StartSound(SFX_TELEPT, fog);

            an = dest->angle >> ANGLETOFINESHIFT;
            if((fog = P_SpawnMobjXYZ(MT_TFOG, dest->origin[VX] + 20 * FIX2FLT(finecosine[an]),
                                              dest->origin[VY] + 20 * FIX2FLT(finesine[an]),
                                              mo->origin[VZ], dest->angle + ANG180, 0)))
            {
                // Emit sound, where?
                S_StartSound(SFX_TELEPT, fog);
            }
        }

        mo->angle = dest->angle;
        if(mo->flags2 & MF2_FLOORCLIP)
        {
            mo->floorClip = 0;

            if(FEQUAL(mo->origin[VZ], P_GetDoublep(Mobj_Sector(mo), DMU_FLOOR_HEIGHT)))
            {
                terraintype_t const *tt = P_MobjFloorTerrain(mo);
                if(tt->flags & TTF_FLOORCLIP)
                {
                    mo->floorClip = 10;
                }
            }
        }

        mo->mom[MX] = mo->mom[MY] = mo->mom[MZ] = 0;

        // $voodoodolls Must be the real player.
        if(mo->player && mo->player->plr->mo == mo)
        {
            mo->reactionTime = 18; // Don't move for a bit.
            if(mo->player->powers[PT_FLIGHT] && aboveFloor > 0)
            {
                mo->origin[VZ] = mo->floorZ + aboveFloor;
                if(mo->origin[VZ] + mo->height > mo->ceilingZ)
                {
                    mo->origin[VZ] = mo->ceilingZ - mo->height;
                }
            }
            else
            {
                //mo->dPlayer->clLookDir = 0; /* $unifiedangles */
                mo->dPlayer->lookDir = 0;
            }
            mo->player->viewHeight = (coord_t) cfg.common.plrViewHeight;
            mo->player->viewHeightDelta = 0;
            mo->player->viewZ = mo->origin[VZ] + mo->player->viewHeight;
            mo->player->viewOffset[VX] = mo->player->viewOffset[VY] = mo->player->viewOffset[VZ] = 0;
            mo->player->bob = 0;

            //mo->dPlayer->clAngle = mo->angle; /* $unifiedangles */
            mo->dPlayer->flags |= DDPF_FIXANGLES | DDPF_FIXORIGIN | DDPF_FIXMOM;
        }

        return 1;
    }
Beispiel #17
0
//===========================================================================
// P_CheckSpot
//  Returns false if the player cannot be respawned
//  at the given mapthing_t spot because something is occupying it 
//  FIXME: Quite a mess!
//===========================================================================
boolean P_CheckSpot(int playernum, mapthing_t * mthing, boolean doTeleSpark)
{
	fixed_t x;
	fixed_t y;
	unsigned an;
	mobj_t *mo;

#if __JDOOM__ || __JHEXEN__
	subsector_t *ss;
#endif
#if __JDOOM__
	int     i;
#endif
#if __JHERETIC__ || __JHEXEN__
	mapthing_t faraway;
	boolean using_dummy = false;
#endif

#if __JDOOM__
	if(!players[playernum].plr->mo)
	{
		// first spawn of level, before corpses
		for(i = 0; i < playernum; i++)
		{
			if(players[i].plr->mo &&
			   players[i].plr->mo->x == mthing->x << FRACBITS &&
			   players[i].plr->mo->y == mthing->y << FRACBITS)
				return false;
		}
		return true;
	}
#endif

	x = mthing->x << FRACBITS;
	y = mthing->y << FRACBITS;

#if __JHERETIC__ || __JHEXEN__
	if(!players[playernum].plr->mo)
	{
		// The player doesn't have a mobj. Let's create a dummy.
		faraway.x = faraway.y = DDMAXSHORT;
		P_SpawnPlayer(&faraway, playernum);
		using_dummy = true;
	}
	players[playernum].plr->mo->flags2 &= ~MF2_PASSMOBJ;
#endif

	if(!P_CheckPosition(players[playernum].plr->mo, x, y))
	{
#if __JHERETIC__ || __JHEXEN__
		players[playernum].plr->mo->flags2 |= MF2_PASSMOBJ;
		if(using_dummy)
		{
			P_RemoveMobj(players[playernum].plr->mo);
			players[playernum].plr->mo = NULL;
		}
#endif
		return false;
	}

#if __JHERETIC__
	players[playernum].plr->mo->flags2 |= MF2_PASSMOBJ;
#endif

#if __JHERETIC__ || __JHEXEN__
	if(using_dummy)
	{
		P_RemoveMobj(players[playernum].plr->mo);
		players[playernum].plr->mo = NULL;
	}
#endif

#if __JDOOM__
	G_QueueBody(players[playernum].plr->mo);
#endif

	if(doTeleSpark)
	{
		// spawn a teleport fog 
		an = (ANG45 * (mthing->angle / 45)) >> ANGLETOFINESHIFT;

#if __JDOOM__ || __JHEXEN__
		ss = R_PointInSubsector(x, y);
		mo = P_SpawnMobj(x + 20 * finecosine[an], y + 20 * finesine[an],
						 ss->sector->floorheight, MT_TFOG);
#else							// __JHERETIC__
		mo = P_SpawnTeleFog(x + 20 * finecosine[an], y + 20 * finesine[an]);
#endif

		// don't start sound on first frame
		if(players[consoleplayer].plr->viewz != 1)
		{
#ifdef __JHEXEN__
			S_StartSound(SFX_TELEPORT, mo);
#else
			S_StartSound(sfx_telept, mo);
#endif
		}
	}

	return true;
}
Beispiel #18
0
void A_FireLaser(player_t *player, pspdef_t *psp)
{
    angle_t         angleoffs;
    angle_t         spread;
    mobj_t          *mobj;
    int             lasercount;
    int             i;
    fixed_t         slope;
    fixed_t         x;
    fixed_t         y;
    fixed_t         z;
    byte            type;
    laser_t         *laser[3];
    laserthinker_t  *laserthinker[3];
    //fixed_t         laserfrac;
    
    mobj = player->mo;
    
    lasercount  = 0;
    spread      = 0;
    angleoffs   = 0;
    
    // the original used a lookup table with the values "0, 1, 1, 2, 1, 2, 2, 3"
    // this is an alternative to using that table
    type = (byte)(((player->artifacts & 3) != 0) +
        ((player->artifacts & 3) == 3) + ((player->artifacts & 4) != 0));
    
    // setup laser type
    switch(type)
    {
    case 1:		// Rapid fire / single shot
        psp->tics = 5;
        lasercount = 1;
        angleoffs = mobj->angle;
        break;
    case 2:		// Rapid fire / double shot
        psp->tics = 4;
        lasercount = 2;
        angleoffs = mobj->angle + 0xFF4A0000;
        spread = 0x16C0000;
        break;
    case 3:		// Spread shot
        psp->tics = 4;
        lasercount = 3;
        spread = 0x2220000 + (0x2220000 * (player->refire & 3));
        angleoffs = mobj->angle - spread;
        break;
    default:	// Normal shot
        lasercount = 1;
        angleoffs = mobj->angle;
        break;
    }
    
    if(lasercount <= 0)
        return;
    
    laserCells = lasercount;
    
    // setup laser beams
    for(i = 0; i < lasercount; i++)
    {
        int	hitdice = 0;
        int	damage = 0;

        slope = P_AimLineAttack(mobj, angleoffs, LASERAIMHEIGHT, LASERRANGE);
        
        player->ammo[weaponinfo[player->readyweapon].ammo]--;
        
        //
        // [kex] 1/2/12 the old code is just plain bad. the original behavior was
        // to simply call P_AimLineAttack and use the intercept fraction to
        // determine where the tail end of the laser will land. this is
        // optimal for consoles but leads to a lot of issues when working with
        // plane hit detection and auto aiming. P_LineAttack will be called normally
        // and instead of spawning puffs or blood, the xyz values are stored so the
        // tail end of the laser can be setup properly here
        //

        // (unused) adjust aim fraction which will be used to determine
        // the endpoint of the laser
        /*if(aimfrac)
            laserfrac = (aimfrac << (FRACBITS - 4)) - (4 << FRACBITS);
        else
            laserfrac = 0x800;*/
            
        hitdice = (P_Random() & 7);
        damage = (((hitdice << 2) + hitdice) << 1) + 10;

        P_LineAttack(mobj, angleoffs, LASERRANGE, slope, damage);
        
        // setup laser
        laser[i] = Z_Malloc(sizeof(*laser[i]), PU_LEVSPEC, 0);

        // setup laser head point
        laser[i]->x1 = mobj->x + FixedMul(LASERDISTANCE, dcos(mobj->angle));
        laser[i]->y1 = mobj->y + FixedMul(LASERDISTANCE, dsin(mobj->angle));
        laser[i]->z1 = (mobj->z + LASERAIMHEIGHT);

        // setup laser tail point
        /*
        laser[i]->x2 = (FixedMul(dcos(angleoffs), laserfrac) + mobj->x);
        laser[i]->y2 = (FixedMul(dsin(angleoffs), laserfrac) + mobj->y);
        laser[i]->z2 = (FixedMul(slope, laserfrac) + (mobj->z + LASERAIMHEIGHT));
        */
        laser[i]->x2 = laserhit_x;
        laser[i]->y2 = laserhit_y;
        laser[i]->z2 = laserhit_z;

        // setup movement slope
        laser[i]->slopex = (dcos(angleoffs) << 5);
        laser[i]->slopey = (dsin(angleoffs) << 5);
        laser[i]->slopez = slope ? (slope << 5) : 0;

        // setup distance info
        x = (laser[i]->x1 - laser[i]->x2) >> FRACBITS;
        y = (laser[i]->y1 - laser[i]->y2) >> FRACBITS;
        z = (laser[i]->z1 - laser[i]->z2) >> FRACBITS;

        laser[i]->dist = 0;
        laser[i]->distmax = (int)sqrt((x * x) + (y * y) + (z * z));

        laser[i]->next = NULL;
        laser[i]->marker = NULL;

        laser[i]->angle = angleoffs;

        x = laser[i]->x2;
        y = laser[i]->y2;
        z = laser[i]->z2;

        P_LaserCrossBSP(numnodes - 1, laser[i]);

        laserthinker[i] = Z_Malloc(sizeof(*laserthinker[i]), PU_LEVSPEC, 0);
        P_AddThinker(&laserthinker[i]->thinker);

        laserthinker[i]->thinker.function.acp1 = (actionf_p1)T_LaserThinker;
        laserthinker[i]->dest = P_SpawnMobj(x, y, z, MT_PROJ_LASER);
        laserthinker[i]->laser = laser[i];
        
        /*if(linetarget)
        {
            int	hitdice = 0;
            int	damage = 0;
            
            hitdice = (P_Random() & 7);
            damage = (((hitdice << 2) + hitdice) << 1) + 10;
            P_DamageMobj(linetarget, mobj, mobj, damage);
        }
        else
            angleoffs += spread;*/

        if(!linetarget)
            angleoffs += spread;
    }
    
    S_StartSound(player->mo, sfx_laser);
    P_SetMobjState(player->mo, S_007);
    P_SetPsprite(player, ps_flash, weaponinfo[player->readyweapon].flashstate);
}
Beispiel #19
0
static void P_LaserCrossBSP(int bspnum, laser_t* laser)
{
    node_t* node;
    int ds1;
    int ds2;
    int s1;
    int s2;
    int dist;
    int frac;
    mobj_t* marker;
    laser_t* childlaser = NULL;
    fixed_t x;
    fixed_t y;
    fixed_t z;

    while(!(bspnum & NF_SUBSECTOR))
    {
        node = &nodes[bspnum];

        // traverse nodes
        ds1 = P_LaserPointOnSide(laser->x1, laser->y1, node);
        ds2 = P_LaserPointOnSide(laser->x2, laser->y2, node);

        s1 = (ds1 < 0);
        s2 = (ds2 < 0);

        // did the two laser points cross the node?
        if(s1 == s2)
        {
            bspnum = node->children[s1];
            continue;
        }

        // allocate a new child laser
        childlaser = (laser_t*)Z_Calloc(sizeof(laser_t), PU_LEVSPEC, NULL);
        childlaser->x1 = laser->x1;
        childlaser->y1 = laser->y1;
        childlaser->z1 = laser->z1;
        childlaser->x2 = laser->x2;
        childlaser->y2 = laser->y2;
        childlaser->z2 = laser->z2;
        childlaser->slopex = laser->slopex;
        childlaser->slopey = laser->slopey;
        childlaser->slopez = laser->slopez;
        childlaser->distmax = laser->distmax;
        childlaser->next = laser->next;
        childlaser->angle = laser->angle;

        // get the intercepting point of the laser and node
        frac = FixedDiv(ds1, ds1 - ds2);

        x = (F2INT(laser->x2 - laser->x1) * frac) + laser->x1;
        y = (F2INT(laser->y2 - laser->y1) * frac) + laser->y1;
        z = (F2INT(laser->z2 - laser->z1) * frac) + laser->z1;

        // update endpoint of current laser to intercept point
        laser->x2 = x;
        laser->y2 = y;
        laser->z2 = z;

        // childlaser begins at intercept point
        childlaser->x1 = x;
        childlaser->y1 = y;
        childlaser->z1 = z;

        // update distmax
        dist = F2INT(laser->distmax * frac);

        childlaser->distmax = laser->distmax - dist;
        laser->distmax = dist;

        // point to child laser
        laser->next = childlaser;

        // traverse child nodes
        P_LaserCrossBSP(node->children[s1], laser);

        laser = childlaser;
        bspnum = node->children[s2];
    }

    // subsector was hit, spawn a marker between the two laser points
    x = (laser->x1 + laser->x2) >> 1;
    y = (laser->y1 + laser->y2) >> 1;
    z = (laser->z1 + laser->z2) >> 1;
    
    marker = P_SpawnMobj(x, y, z, MT_LASERMARKER);

    // have marker point to which laser it belongs to
    marker->extradata = (laser_t*)laser;
    laser->marker = marker;
}
Beispiel #20
0
boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, angle_t angle,
				   boolean useFog)
{
	fixed_t oldx;
	fixed_t oldy;
	fixed_t oldz;
	fixed_t aboveFloor;
	fixed_t fogDelta;
	player_t *player;
	unsigned an;
	mobj_t *fog;

	oldx = thing->x;
	oldy = thing->y;
	oldz = thing->z;
	aboveFloor = thing->z - thing->floorz;
	if(!P_TeleportMove(thing, x, y))
	{
		return false;
	}
	if(thing->player)
	{
		player = thing->player;
		player->plr->flags |= DDPF_FIXANGLES | DDPF_FIXPOS | DDPF_FIXMOM;
		if(player->powers[pw_flight] && aboveFloor)
		{
			thing->z = thing->floorz + aboveFloor;
			if(thing->z + thing->height > thing->ceilingz)
			{
				thing->z = thing->ceilingz - thing->height;
			}
			player->plr->viewz = thing->z + player->plr->viewheight;
		}
		else
		{
			thing->z = thing->floorz;
			player->plr->viewz = thing->z + player->plr->viewheight;
			if(useFog)
			{
				player->plr->lookdir = 0;
			}
		}
	}
	else if(thing->flags & MF_MISSILE)
	{
		thing->z = thing->floorz + aboveFloor;
		if(thing->z + thing->height > thing->ceilingz)
		{
			thing->z = thing->ceilingz - thing->height;
		}
	}
	else
	{
		thing->z = thing->floorz;
	}
	// Spawn teleport fog at source and destination
	if(useFog)
	{
		fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT;
		fog = P_SpawnMobj(oldx, oldy, oldz + fogDelta, MT_TFOG);
		S_StartSound(SFX_TELEPORT, fog);
		an = angle >> ANGLETOFINESHIFT;
		fog =
			P_SpawnMobj(x + 20 * finecosine[an], y + 20 * finesine[an],
						thing->z + fogDelta, MT_TFOG);
		S_StartSound(SFX_TELEPORT, fog);
		if(thing->player && !thing->player->powers[pw_speed])
		{						// Freeze player for about .5 sec
			thing->reactiontime = 18;
		}
		thing->angle = angle;
	}
	if(thing->flags2 & MF2_FLOORCLIP)
	{
		if(thing->z == thing->subsector->sector->floorheight &&
		   P_GetThingFloorType(thing) > FLOOR_SOLID)
		{
			thing->floorclip = 10 * FRACUNIT;
		}
		else
		{
			thing->floorclip = 0;
		}
	}
	if(thing->flags & MF_MISSILE)
	{
		angle >>= ANGLETOFINESHIFT;
		thing->momx = FixedMul(thing->info->speed, finecosine[angle]);
		thing->momy = FixedMul(thing->info->speed, finesine[angle]);
	}
Beispiel #21
0
//
// A_Tracer
//
// (Accidentally?) randomized homing missile maintenance.
// ioanch 20151230: fixed to be portal-aware
//
void A_Tracer(actionargs_t *actionargs)
{
   angle_t  exact;
   fixed_t  dist;
   fixed_t  slope;
   Mobj    *actor = actionargs->actor;
   Mobj    *dest;
   Mobj    *th;

   // killough 1/18/98: this is why some missiles do not have smoke
   // and some do. Also, internal demos start at random gametics, 
   // thus the bug in which revenants cause internal demos to go out 
   // of sync.
   //
   // killough 3/6/98: fix revenant internal demo bug by subtracting
   // levelstarttic from gametic.
   //
   // killough 9/29/98: use new "basetic" so that demos stay in sync
   // during pauses and menu activations, while retaining old demo 
   // sync.
   //
   // leveltime would have been better to use to start with in Doom, 
   // but since old demos were recorded using gametic, we must stick 
   // with it, and improvise around it (using leveltime causes desync 
   // across levels).

   if((gametic-basetic) & 3)
      return;

   // spawn a puff of smoke behind the rocket
   P_SpawnPuff(actor->x, actor->y, actor->z, 0, 3, false);
   
   th = P_SpawnMobj(actor->x - actor->momx,
                    actor->y - actor->momy,
                    actor->z, E_SafeThingType(MT_SMOKE));
  
   th->momz = FRACUNIT;
   th->tics -= P_Random(pr_tracer) & 3;
   if(th->tics < 1)
      th->tics = 1;
  
   // adjust direction
   dest = actor->tracer;
   
   if(!dest || dest->health <= 0)
      return;

   fixed_t dx = getThingX(actor, dest);
   fixed_t dy = getThingY(actor, dest);
   fixed_t dz = getThingZ(actor, dest);

   // change angle
   exact = P_PointToAngle(actor->x, actor->y, dx, dy);

   if(exact != actor->angle)
   {
      if(exact - actor->angle > 0x80000000)
      {
         actor->angle -= TRACEANGLE;
         if(exact - actor->angle < 0x80000000)
            actor->angle = exact;
      }
      else
      {
         actor->angle += TRACEANGLE;
         if(exact - actor->angle > 0x80000000)
            actor->angle = exact;
      }
   }

   exact = actor->angle>>ANGLETOFINESHIFT;
   actor->momx = FixedMul(actor->info->speed, finecosine[exact]);
   actor->momy = FixedMul(actor->info->speed, finesine[exact]);

   // change slope
   dist = P_AproxDistance(dx - actor->x, dy - actor->y);
   
   dist = dist / actor->info->speed;

   if(dist < 1)
      dist = 1;

   slope = (dz + 40*FRACUNIT - actor->z) / dist;
   
   if(slope < actor->momz)
      actor->momz -= FRACUNIT/8;
   else
      actor->momz += FRACUNIT/8;
}
Beispiel #22
0
//
// TELEPORTATION
//
int
EV_Teleport
( line_t*	line,
  int		side,
  mobj_t*	thing )
{
    int		i;
    int		tag;
    mobj_t*	m;
    mobj_t*	fog;
    unsigned	an;
    thinker_t*	thinker;
    sector_t*	sector;
    fixed_t	oldx;
    fixed_t	oldy;
    fixed_t	oldz;

    // don't teleport missiles
    if (thing->flags & MF_MISSILE)
	return 0;		

    // Don't teleport if hit back of line,
    //  so you can get out of teleporter.
    if (side == 1)		
	return 0;	

    
    tag = line->tag;
    for (i = 0; i < P_CountSectors(); i++)
    {
	if (P_GetSector(i)->tag == tag )
	{
	    for (thinker = P_FirstThinker();
		 thinker;
		 thinker = P_NextThinker(thinker))
	    {
		// not a mobj
		if (thinker->function.acp1 != (actionf_p1)P_MobjThinker)
		    continue;	

		m = (mobj_t *)thinker;
		
		// not a teleportman
		if (m->type != MT_TELEPORTMAN )
		    continue;		

		sector = m->subsector->sector;
		// wrong sector
		if (P_UngetSector(sector) != i )
		    continue;	

		oldx = thing->x;
		oldy = thing->y;
		oldz = thing->z;
				
		if (!P_TeleportMove (thing, m->x, m->y))
		    return 0;
		
		if (!B_CheckCompat(COMPAT_TELEPORTZ))
		{
			thing->z = thing->floorz;  //fixme: not needed?
		}
		if (thing->player)
		    thing->player->viewz = thing->z+thing->player->viewheight;
				
		// spawn teleport fog at source and destination
		fog = P_SpawnMobj (oldx, oldy, oldz, MT_TFOG);
		S_StartSound (fog, sfx_telept);
		an = m->angle >> ANGLETOFINESHIFT;
		fog = P_SpawnMobj (m->x+20*finecosine[an], m->y+20*finesine[an]
				   , thing->z, MT_TFOG);

		// emit sound, where?
		S_StartSound (fog, sfx_telept);
		
		// don't move for a bit
		if (thing->player)
		    thing->reactiontime = 18;	

		thing->angle = m->angle;
		thing->momx = thing->momy = thing->momz = 0;
		return 1;
	    }	
	}
    }
    return 0;
}
Beispiel #23
0
int EV_Teleport( line_t *line,mobj_t *thing )
{
   int      i;
   int      tag;
   boolean  flag;
   mobj_t   *m,*fog;
   unsigned int	an;
   sector_t *sector;
   fixed_t   oldx, oldy, oldz;
   int       side;
	
   side = !P_PointOnLineSide (thing->x, thing->y, line);

   if(thing->flags & MF_MISSILE)
      return 0; /* don't teleport missiles */

   if(side == 1) /* don't teleport if hit back of line, */
      return 0;  /* so you can get out of teleporter */
	
   tag = line->tag;
   for(i = 0; i < numsectors; i++)
   {
      if (sectors[ i ].tag == tag )
      {
         for(m = mobjhead.next; m != &mobjhead; m = m->next)
         {
            // CALICO: skip removed mobjs
            if(m->latecall == P_RemoveMobjDeferred)
               continue;

            if(m->type != MT_TELEPORTMAN)
               continue; // not a teleportman

            sector = m->subsector->sector;
            if(sector-sectors != i )
               continue; // wrong sector

            oldx = thing->x;
            oldy = thing->y;
            oldz = thing->z;
            thing->flags |= MF_TELEPORT;
            P_Telefrag(thing, m->x, m->y);
            flag = P_TryMove (thing, m->x, m->y);
            thing->flags &= ~MF_TELEPORT;
            if(!flag)
               return 0; /* move is blocked */
            thing->z = thing->floorz;
            
            /* spawn teleport fog at source and destination */
            fog = P_SpawnMobj (oldx, oldy, oldz, MT_TFOG);
            S_StartSound(fog, sfx_telept);
            an  = m->angle >> ANGLETOFINESHIFT;
            fog = P_SpawnMobj (m->x+20*finecosine[an], m->y+20*finesine[an], thing->z, MT_TFOG);
            S_StartSound(fog, sfx_telept);
            if(thing->player)
               thing->reactiontime = 18;	/* don't move for a bit */
            thing->angle = m->angle;
            thing->momx = thing->momy = thing->momz = 0;
            return 1;
         }	
      }
   }
   return 0;
}
Beispiel #24
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;
}
Beispiel #25
0
void P_KillMobj(mobj_t* source, mobj_t* target) {
    mobjtype_t  item;
    mobj_t*     mo;

    target->flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SKULLFLY);

    if(target->type != MT_SKULL && (!(target->flags & MF_GRAVITY))) {
        target->flags |= MF_GRAVITY;
    }

    target->flags |= MF_CORPSE|MF_DROPOFF;
    target->height >>= 2;

    if(source && source->player) {
        // count for intermission
        if(target->flags & MF_COUNTKILL) {
            source->player->killcount++;
        }

        if(target->player) {
            source->player->frags[target->player-players]++;
        }
    }
    else if(!netgame && (target->flags & MF_COUNTKILL)) {
        // count all monster deaths,
        // even those caused by other monsters
        players[0].killcount++;
    }

    if(target->player) {
        // count environment kills against you
        if(!source) {
            target->player->frags[target->player-players]++;
        }

        target->flags &= ~MF_SOLID;
        target->player->playerstate = PST_DEAD;
        P_DropWeapon(target->player);

        deathmocktics = gametic;

        if(target->player == &players[consoleplayer]
                && automapactive) {
            // don't die in auto map,
            // switch view prior to dying
            AM_Stop();
        }

        // 20120123 villsa - obituaries!
        if(netgame) {
            P_Obituary(source, target);
        }

    }

    if(target->health < -target->info->spawnhealth
            && target->info->xdeathstate) {
        P_SetMobjState(target, target->info->xdeathstate);
    }
    else {
        P_SetMobjState(target, target->info->deathstate);
    }
    target->tics -= P_Random(pr_killtics)&3;

    if(target->tics < 1) {
        target->tics = 1;
    }


    // Drop stuff.
    // This determines the kind of object spawned
    // during the death frame of a thing.
    switch(target->type) {
    case MT_POSSESSED1:
        item = MT_AMMO_CLIP;
        break;

    case MT_POSSESSED2:
        item = MT_WEAP_SHOTGUN;
        break;

    default:
        return;
    }

    mo = P_SpawnMobj(target->x,target->y,ONFLOORZ, item);
    mo->flags |= MF_DROPPED;    // special versions of items
}
Beispiel #26
0
void P_SpawnMapThing (mapthing_t *mthing)
{
    int			i, bit;
    mobj_t		*mobj;
    fixed_t		x,y,z;

    /* count deathmatch start positions */
    if (mthing->type == 11)
    {
        if (deathmatch_p < &deathmatchstarts[10])
            D_memcpy (deathmatch_p, mthing, sizeof(*mthing));
        deathmatch_p++;
        return;
    }

    /* check for players specially */

#if 0
    if (mthing->type > 4)
        return;	/*DEBUG */
#endif

    if (mthing->type <= 4)
    {
        /* save spots for respawning in network games */
        if (mthing->type <= MAXPLAYERS)
        {
            playerstarts[mthing->type-1] = *mthing;
            if (netgame != gt_deathmatch)
                P_SpawnPlayer (mthing);
        }
        return;
    }

    /* check for apropriate skill level */
    if ( (netgame != gt_deathmatch) && (mthing->options & 16) )
        return;

    if (gameskill == sk_baby)
        bit = 1;
    else if (gameskill == sk_nightmare)
        bit = 4;
    else
        bit = 1<<(gameskill-1);
    if (!(mthing->options & bit) )
        return;

#ifdef MARS
    /* hack player corpses into something else, because player graphics */
    /* aren't included */
    if (mthing->type == 10 || mthing->type == 12)	/* player corpse */
        mthing->type = 18;		/* possessed human corpse */
#endif


    /* find which type to spawn */
    for (i=0 ; i< NUMMOBJTYPES ; i++)
        if (mthing->type == mobjinfo[i].doomednum)
            break;

    if (i==NUMMOBJTYPES)
        I_Error ("P_SpawnMapThing: Unknown type %i at (%i, %i)",mthing->type
                 , mthing->x, mthing->y);



    /* don't spawn keycards and players in deathmatch */
    if (netgame == gt_deathmatch && mobjinfo[i].flags & (MF_NOTDMATCH|MF_COUNTKILL) )
        return;


    /* spawn it */

    x = mthing->x << FRACBITS;
    y = mthing->y << FRACBITS;
    if (mobjinfo[i].flags & MF_SPAWNCEILING)
        z = ONCEILINGZ;
    else
        z = ONFLOORZ;
    mobj = P_SpawnMobj (x,y,z, i);
    if (mobj->tics > 0)
        mobj->tics = 1 + (P_Random () % mobj->tics);
    if (mobj->flags & MF_COUNTKILL)
        totalkills++;
    if (mobj->flags & MF_COUNTITEM)
        totalitems++;

    mobj->angle = ANG45 * (mthing->angle/45);
    if (mthing->options & MTF_AMBUSH)
        mobj->flags |= MF_AMBUSH;

    mobj->spawnx = mthing->x;
    mobj->spawny = mthing->y;
    mobj->spawntype = mthing->type;
    mobj->spawnangle = mthing->angle;
}
Beispiel #27
0
//
// TELEPORTATION
//
int
EV_Teleport
( line_t*	line,
  int		side,
  mobj_t*	thing )
{
    int		i;
    int		tag;
    mobj_t*	m;
    mobj_t*	fog;
    unsigned	an;
    thinker_t*	thinker;
    sector_t*	sector;
    fixed_t	oldx;
    fixed_t	oldy;
    fixed_t	oldz;

    // don't teleport missiles
    if (thing->flags & MF_MISSILE)
	return 0;		

    // Don't teleport if hit back of line,
    //  so you can get out of teleporter.
    if (side == 1)		
	return 0;	

    
    tag = line->tag;
    for (i = 0; i < numsectors; i++)
    {
	if (sectors[ i ].tag == tag )
	{
	    thinker = thinkercap.next;
	    for (thinker = thinkercap.next;
		 thinker != &thinkercap;
		 thinker = thinker->next)
	    {
		// not a mobj
		if (thinker->function.acp1 != (actionf_p1)P_MobjThinker)
		    continue;	

		m = (mobj_t *)thinker;
		
		// not a teleportman
		if (m->type != MT_TELEPORTMAN )
		    continue;		

		sector = m->subsector->sector;
		// wrong sector
		if (sector-sectors != i )
		    continue;	

		oldx = thing->x;
		oldy = thing->y;
		oldz = thing->z;
				
		if (!P_TeleportMove (thing, m->x, m->y))
		    return 0;
		
                // fraggle: this was changed in final doom, 
                // problem between normal doom2 1.9 and final doom
                //
                // Note that although chex.exe is based on Final Doom,
                // it does not have this quirk.

                if (gameversion < exe_final || gameversion == exe_chex)
		    thing->z = thing->floorz;
                
		if (thing->player)
		    thing->player->viewz = thing->z+thing->player->viewheight;
				
		// spawn teleport fog at source and destination
		fog = P_SpawnMobj (oldx, oldy, oldz, MT_TFOG);
		S_StartSound (fog, sfx_telept);
		an = m->angle >> ANGLETOFINESHIFT;
		fog = P_SpawnMobj (m->x+20*finecosine[an], m->y+20*finesine[an]
				   , thing->z, MT_TFOG);

		// emit sound, where?
		S_StartSound (fog, sfx_telept);
		
		// don't move for a bit
		if (thing->player)
		    thing->reactiontime = 18;	

		thing->angle = m->angle;
		thing->momx = thing->momy = thing->momz = 0;
		return 1;
	    }	
	}
    }
Beispiel #28
0
//
// TELEPORTATION
//
int
EV_Teleport
( line_t*	line,
  int		side,
  mobj_t*	thing )
{
    int		i;
    int		tag;
    mobj_t*	m;
    mobj_t*	fog;
    unsigned	an;
    thinker_t*	thinker;
    sector_t*	sector;
    int	oldx;
    int	oldy;
    int	oldz;

    // don't teleport missiles
    if (thing->flags & MF_MISSILE)
	return 0;		

    // Don't teleport if hit back of line,
    //  so you can get out of teleporter.
    if (side == 1)		
	return 0;	

    
    tag = line->tag;
    for (i = 0; i < numsectors; i++)
    {
	if (sectors[ i ].tag == tag )
	{
	    thinker = thinkercap.next;
	    for (thinker = thinkercap.next;
		 thinker != &thinkercap;
		 thinker = thinker->next)
	    {
		// not a mobj
		if (thinker->function.acp1 != (actionf_p1)P_MobjThinker)
		    continue;	

		m = (mobj_t *)thinker;
		
		// not a teleportman
		if (m->type != MT_TELEPORTMAN )
		    continue;		

		sector = m->subsector->sector;
		// wrong sector
		if (sector-sectors != i )
		    continue;	

		oldx = thing->x;
		oldy = thing->y;
		oldz = thing->z;
				
		if (!P_TeleportMove (thing, m->x, m->y))
		    return 0;
		
		thing->z = thing->floorz;  //fixme: not needed?
		if (thing->player)
		    thing->player->viewz = thing->z+thing->player->viewheight;
				
		// spawn teleport fog at source and destination
		fog = P_SpawnMobj (oldx, oldy, oldz, MT_TFOG);
		I_Sound::getInstance()->startSound (fog, sfx_telept);
		an = m->angle >> ANGLETOFINESHIFT;
		fog = P_SpawnMobj (m->x+20*finecosine[an], m->y+20*finesine[an]
				   , thing->z, MT_TFOG);

		// emit sound, where?
		I_Sound::getInstance()->startSound (fog, sfx_telept);
		
		// don't move for a bit
		if (thing->player)
		    thing->reactiontime = 18;	

		thing->angle = m->angle;
		thing->momx = thing->momy = thing->momz = 0;
		return 1;
	    }	
	}
    }
Beispiel #29
0
void P_SetupLevel(int episode, int map, int playermask, skill_t skill)
{
    int i;
    int parm;
    char lumpname[9];
    int lumpnum;
    mobj_t *mobj;

    for (i = 0; i < MAXPLAYERS; i++)
    {
        players[i].killcount = players[i].secretcount
            = players[i].itemcount = 0;
    }
    players[consoleplayer].viewz = 1;   // will be set by player think

    // Waiting-for-level-load song; not played if playing music from CD
    // (the seek time will be so long it will just make loading take
    // longer)
    if (!cdmusic)
    {
        S_StartSongName("chess", true);
    }

    Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1);

    P_InitThinkers();
    leveltime = 0;

    sprintf(lumpname, "MAP%02d", map);
    lumpnum = W_GetNumForName(lumpname);
    //
    // Begin processing map lumps
    // Note: most of this ordering is important
    //
    P_LoadBlockMap(lumpnum + ML_BLOCKMAP);
    P_LoadVertexes(lumpnum + ML_VERTEXES);
    P_LoadSectors(lumpnum + ML_SECTORS);
    P_LoadSideDefs(lumpnum + ML_SIDEDEFS);
    P_LoadLineDefs(lumpnum + ML_LINEDEFS);
    P_LoadSubsectors(lumpnum + ML_SSECTORS);
    P_LoadNodes(lumpnum + ML_NODES);
    P_LoadSegs(lumpnum + ML_SEGS);
    rejectmatrix = W_CacheLumpNum(lumpnum + ML_REJECT, PU_LEVEL);
    P_GroupLines();
    bodyqueslot = 0;
    po_NumPolyobjs = 0;
    deathmatch_p = deathmatchstarts;
    P_LoadThings(lumpnum + ML_THINGS);
    PO_Init(lumpnum + ML_THINGS);       // Initialize the polyobjs
    P_LoadACScripts(lumpnum + ML_BEHAVIOR);     // ACS object code
    //
    // End of map lump processing
    //

    // If deathmatch, randomly spawn the active players
    TimerGame = 0;
    if (deathmatch)
    {
        for (i = 0; i < MAXPLAYERS; i++)
        {
            if (playeringame[i])
            {                   // must give a player spot before deathmatchspawn
                mobj = P_SpawnMobj(playerstarts[0][i].x << 16,
                                   playerstarts[0][i].y << 16, 0,
                                   MT_PLAYER_FIGHTER);
                players[i].mo = mobj;
                G_DeathMatchSpawnPlayer(i);
                P_RemoveMobj(mobj);
            }
        }

        //!
        // @arg <n>
        // @category net
        // @vanilla
        //
        // For multiplayer games: exit each level after n minutes.
        //

        parm = M_CheckParmWithArgs("-timer", 1);
        if (parm)
        {
            TimerGame = atoi(myargv[parm + 1]) * 35 * 60;
        }
    }

// set up world state
    P_SpawnSpecials();

// build subsector connect matrix
//      P_ConnectSubsectors ();

// Load colormap and set the fullbright flag
    i = P_GetMapFadeTable(gamemap);
    W_ReadLump(i, colormaps);
    if (i == W_GetNumForName("COLORMAP"))
    {
        LevelUseFullBright = true;
    }
    else
    {                           // Probably fog ... don't use fullbright sprites
        LevelUseFullBright = false;
    }

// preload graphics
    if (precache)
        R_PrecacheLevel();

    // Check if the level is a lightning level
    P_InitLightning();

    S_StopAllSound();
    SN_StopAllSequences();
    S_StartSong(gamemap, true);

//printf ("free memory: 0x%x\n", Z_FreeMemory());

}
Beispiel #30
0
mobj_t *P_SpawnTeleFog(int x, int y)
{
	subsector_t *ss = R_PointInSubsector(x, y);

	return P_SpawnMobj(x, y, ss->sector->floorheight + TELEFOGHEIGHT, MT_TFOG);
}