Пример #1
0
//==================================================================
//
//      P_SpawnLightFlash
//
//      After the map has been loaded, scan each sector for specials that spawn thinkers
//
//==================================================================
void P_SpawnStrobeFlash(sector_t * sector, int fastOrSlow, int inSync)
{
    strobe_t *flash;

    flash = Z_Malloc(sizeof(*flash), PU_LEVSPEC, 0);
    P_AddThinker(&flash->thinker);
    flash->sector = sector;
    flash->darktime = fastOrSlow;
    flash->brighttime = STROBEBRIGHT;
    flash->thinker.function = T_StrobeFlash;
    flash->maxlight = sector->lightlevel;
    flash->minlight = P_FindMinSurroundingLight(sector, sector->lightlevel);

    if (flash->minlight == flash->maxlight)
        flash->minlight = 0;
    sector->special = 0;        // nothing special about it during gameplay

    if (!inSync)
        flash->count = (P_Random() & 7) + 1;
    else
        flash->count = 1;
}
Пример #2
0
//
// A_SPosAttack
//
// Sergeant attack.
//
void A_SPosAttack(actionargs_t *actionargs)
{
   Mobj *actor = actionargs->actor;
   int i, bangle, slope;
   
   if (!actor->target)
      return;
   
   S_StartSound(actor, sfx_shotgn);
   A_FaceTarget(actionargs);
   
   bangle = actor->angle;
   slope = P_AimLineAttack(actor, bangle, MISSILERANGE, 0); // killough 8/2/98
   
   for(i = 0; i < 3; ++i)
   {  
      // haleyjd 08/05/04: use new function
      int angle = bangle + (P_SubRandom(pr_sposattack) << 20);
      int damage = ((P_Random(pr_sposattack) % 5) + 1) * 3;
      P_LineAttack(actor, angle, MISSILERANGE, slope, damage);
   }
}
Пример #3
0
//
// A_Punch
//
void A_Punch (AActor *mo)
{
	angle_t 	angle;
	int 		damage;
	int 		slope;

    player_t *player = mo->player;

	damage = (P_Random (player->mo)%10+1)<<1;

	if (player->powers[pw_strength])
		damage *= 10;

	angle = player->mo->angle;
	angle += P_RandomDiff(player->mo) << 18;

	// [SL] 2011-07-12 - Move players and sectors back to their positions when
	// this player hit the fire button clientside.
	Unlag::getInstance().reconcile(player->id);

	slope = P_AimLineAttack (player->mo, angle, MELEERANGE);
	P_LineAttack (player->mo, angle, MELEERANGE, slope, damage);

	// [SL] 2011-07-12 - Restore players and sectors to their current position
	// according to the server.
	Unlag::getInstance().restore(player->id);

	// turn to face target
	if (linetarget)
	{
		A_FireSound (player, "player/male/fist");
		//S_Sound (player->mo, CHAN_VOICE, "*fist", 1, ATTN_NORM);
		player->mo->angle = P_PointToAngle (player->mo->x,
											player->mo->y,
											linetarget->x,
											linetarget->y);
	}
}
Пример #4
0
void G_DeathMatchSpawnPlayer (int playernum) 
{ 
	int             i,j; 
	int				selections;
	
	selections = deathmatch_p - deathmatchstarts;
	if (selections < 4)
		I_Error ("Only %i deathmatch spots, 4 required", selections);
		
	for (j=0 ; j<20 ; j++) 
	{ 
		i = P_Random()%selections;
		if (G_CheckSpot (playernum, &deathmatchstarts[i]) ) 
		{ 
			deathmatchstarts[i].type = playernum+1; 
			P_SpawnPlayer (&deathmatchstarts[i]); 
			return; 
		} 
	} 
 
/* no good spot, so the player will probably get stuck  */
	P_SpawnPlayer (&playerstarts[playernum]); 
} 
Пример #5
0
//
// A_TroopAttack
//
// Imp attack.
//
void A_TroopAttack(actionargs_t *actionargs)
{
   Mobj *actor = actionargs->actor;

   if(!actor->target)
      return;

   A_FaceTarget(actionargs);
   
   if(P_CheckMeleeRange(actor))
   {
      int damage;
      S_StartSound(actor, sfx_claw);
      damage = (P_Random(pr_troopattack)%8+1)*3;
      P_DamageMobj(actor->target, actor, actor, damage, MOD_HIT);
   }
   else
   {
      // launch a missile
      P_SpawnMissile(actor, actor->target, E_SafeThingType(MT_TROOPSHOT),
                     actor->z + DEFAULTMISSILEZ);
   }
}
Пример #6
0
void A_BFGSpray(mobj_t* mo)
{
    int         i;
    int         j;
    int         damage;
    angle_t     an;
    
    // offset angles from its attack angle
    for(i = 0; i < 40; i++)
    {
        an = mo->angle - ANG90/2 + ANG90/40*i;
        
        // mo->target is the originator (player) of the missile
        
        //
        // [kex] add 1 to distance so autoaim can be forced
        //
        P_AimLineAttack(mo->target, an, 0, ATTACKRANGE + 1);
        
        if(!linetarget)
            continue;
        
        //
        // [d64] shift linetarget height by 1 instead of 2
        //
        P_SpawnMobj(linetarget->x, linetarget->y,
            linetarget->z + (linetarget->height >> 1), MT_BFGSPREAD);
        
        damage = 0;
        for(j = 0; j < 15; j++)
            damage += (P_Random() & 7) + 1;
        
        P_DamageMobj(linetarget, mo->target, mo->target, damage);
    }
    
    A_FadeAlpha(mo);
}
Пример #7
0
//
// EV_FlickerLight
//
// haleyjd 01/16/07:
// Parameterized flickering light effect. Changes between maxval and minval
// at a randomized time period between 0.2 and 1.8 seconds (7 to 64 tics).
// Uses the normal lightflash thinker.
//
int EV_FlickerLight(line_t *line, int tag, int maxval, int minval)
{
   LightFlashThinker *flash;
   int i, rtn = 0;
   bool backside = false;

   if(line && tag == 0)
   {
      if(!line->backsector)
         return rtn;
      i = line->backsector - sectors;
      backside = true;
      goto dobackside;
   }
   
   for(i = -1; (i = P_FindSectorFromTag(tag, i)) >= 0;)
   {
dobackside:
      rtn = 1;
      flash = new LightFlashThinker;
      flash->addThinker();
      
      flash->sector   = &sectors[i];
      flash->maxlight = maxval;
      flash->minlight = minval;
      flash->maxtime  = 64;
      flash->mintime  = 7;
      flash->count    = (P_Random(pr_lights) & flash->maxtime) + 1;

      flash->sector->lightlevel = flash->maxlight;

      if(backside)
         return rtn;
   }

   return rtn;
}
Пример #8
0
//
// P_SpawnStrobeFlash
//
// Spawns a blinking light thinker
//
// Passed the sector that spawned the thinker, speed of blinking
// and whether blinking is to by syncrhonous with other sectors
//
// Returns nothing
//
void P_SpawnStrobeFlash(sector_t *sector, int fastOrSlow, int inSync)
{
   StrobeThinker *flash;
   
   flash = new StrobeThinker;
   flash->addThinker();
   
   flash->sector = sector;
   flash->darktime = fastOrSlow;
   flash->brighttime = STROBEBRIGHT;
   flash->maxlight = sector->lightlevel;
   flash->minlight = P_FindMinSurroundingLight(sector, sector->lightlevel);
   
   if(flash->minlight == flash->maxlight)
      flash->minlight = 0;
   
   // nothing special about it during gameplay
   sector->special &= ~31; //jff 3/14/98 clear non-generalized sector type
   
   if(!inSync)
      flash->count = (P_Random(pr_lights)&7)+1;
   else
      flash->count = 1;
}
Пример #9
0
//
// EV_DoPlat
//
// Handle Plat linedef types
//
// Passed the linedef that activated the plat, the type of plat action,
// and for some plat types, an amount to raise
// Returns true if a thinker is started, or restarted from stasis
//
int EV_DoPlat
( line_t*       line,
  plattype_e    type,
  int           amount )
{
    plat_t* plat;
    int             secnum;
    int             rtn;
    sector_t*       sec;

    secnum = -1;
    rtn = 0;


    // Activate all <type> plats that are in_stasis
    switch(type)
    {
    case perpetualRaise:
        P_ActivateInStasis(line->tag);
        break;

    case toggleUpDn:
        P_ActivateInStasis(line->tag);
        rtn=1;
        break;

    default:
        break;
    }

    // act on all sectors tagged the same as the activating linedef
    while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
    {
        sec = &sectors[secnum];

        // don't start a second floor function if already moving
        if (P_SectorActive(floor_special,sec)) //jff 2/23/98 multiple thinkers
            continue;

        // Create a thinker
        rtn = 1;
        plat = Z_Malloc( sizeof(*plat), PU_LEVSPEC, 0);
        memset(plat, 0, sizeof(*plat));
        P_AddThinker(&plat->thinker);

        plat->type = type;
        plat->sector = sec;
        plat->sector->floordata = plat; //jff 2/23/98 multiple thinkers
        plat->thinker.function = T_PlatRaise;
        plat->crush = false;
        plat->tag = line->tag;

        //jff 1/26/98 Avoid raise plat bouncing a head off a ceiling and then
        //going down forever -- default low to plat height when triggered
        plat->low = sec->floorheight;

        // set up plat according to type
        switch(type)
        {
        case raiseToNearestAndChange:
            plat->speed = PLATSPEED/2;
            sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
            plat->high = P_FindNextHighestFloor(sec,sec->floorheight);
            plat->wait = 0;
            plat->status = up;
            sec->special = 0;
            //jff 3/14/98 clear old field as well
            sec->oldspecial = 0;

            S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov);
            break;

        case raiseAndChange:
            plat->speed = PLATSPEED/2;
            sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
            plat->high = sec->floorheight + amount*FRACUNIT;
            plat->wait = 0;
            plat->status = up;

            S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov);
            break;

        case downWaitUpStay:
            plat->speed = PLATSPEED * 4;
            plat->low = P_FindLowestFloorSurrounding(sec);

            if (plat->low > sec->floorheight)
                plat->low = sec->floorheight;

            plat->high = sec->floorheight;
            plat->wait = 35*PLATWAIT;
            plat->status = down;
            S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
            break;

        case blazeDWUS:
            plat->speed = PLATSPEED * 8;
            plat->low = P_FindLowestFloorSurrounding(sec);

            if (plat->low > sec->floorheight)
                plat->low = sec->floorheight;

            plat->high = sec->floorheight;
            plat->wait = 35*PLATWAIT;
            plat->status = down;
            S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
            break;

        case perpetualRaise:
            plat->speed = PLATSPEED;
            plat->low = P_FindLowestFloorSurrounding(sec);

            if (plat->low > sec->floorheight)
                plat->low = sec->floorheight;

            plat->high = P_FindHighestFloorSurrounding(sec);

            if (plat->high < sec->floorheight)
                plat->high = sec->floorheight;

            plat->wait = 35*PLATWAIT;
            plat->status = P_Random(pr_plats)&1;

            S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
            break;

        case toggleUpDn: //jff 3/14/98 add new type to support instant toggle
            plat->speed = PLATSPEED;  //not used
            plat->wait = 35*PLATWAIT; //not used
            plat->crush = true; //jff 3/14/98 crush anything in the way

            // set up toggling between ceiling, floor inclusive
            plat->low = sec->ceilingheight;
            plat->high = sec->floorheight;
            plat->status =  down;
            break;

        default:
            break;
        }
        P_AddActivePlat(plat);  // add plat to list of active plats
    }
    return rtn;
}
Пример #10
0
//
// A_WeaponSetCtr
//
// Sets the value of the indicated counter variable for the thing.
// Can perform numerous operations -- this is more like a virtual
// machine than a codepointer ;)
//
// args[0] : counter # to set
// args[1] : value to utilize
// args[2] : operation to perform
//
void A_WeaponSetCtr(Mobj *mo)
{
   int cnum;
   int value;
   int specialop;
   int *counter;
   player_t *player;
   pspdef_t *pspr;

   if(!(player = mo->player))
      return;

   pspr = &(player->psprites[player->curpsprite]);

   cnum      = E_ArgAsInt(pspr->state->args, 0, 0);
   value     = E_ArgAsInt(pspr->state->args, 1, 0);
   specialop = E_ArgAsKwd(pspr->state->args, 2, &weapsetkwds, 0);

   switch(cnum)
   {
   case 0:
   case 1:
   case 2:
      counter = &(player->weaponctrs[player->readyweapon][cnum]); break;
   default:
      return;
   }

   switch(specialop)
   {
   case CPOP_ASSIGN:
      *counter = value; break;
   case CPOP_ADD:
      *counter += value; break;
   case CPOP_SUB:
      *counter -= value; break;
   case CPOP_MUL:
      *counter *= value; break;
   case CPOP_DIV:
      if(value) // don't divide by zero
         *counter /= value;
      break;
   case CPOP_MOD:
      if(value > 0) // only allow modulus by positive values
         *counter %= value;
      break;
   case CPOP_AND:
      *counter &= value; break;
   case CPOP_ANDNOT:
      *counter &= ~value; break; // compound and-not operation
   case CPOP_OR:
      *counter |= value; break;
   case CPOP_XOR:
      *counter ^= value; break;
   case CPOP_RND:
      *counter = P_Random(pr_weapsetctr); break;
   case CPOP_RNDMOD:
      if(value > 0)
         *counter = P_Random(pr_weapsetctr) % value; break;
   case CPOP_SHIFTLEFT:
      *counter <<= value; break;
   case CPOP_SHIFTRIGHT:
      *counter >>= value; break;
   default:
      break;
   }
}
Пример #11
0
//
// A_WeaponCtrOp
//
// Sets the value of the indicated counter variable for the weapon
// using two (possibly the same) counters as operands.
//
// args[0] : counter operand #1
// args[1] : counter operand #2
// args[2] : counter destination
// args[3] : operation to perform
//
void A_WeaponCtrOp(Mobj *mo)
{
   player_t *player;
   pspdef_t *pspr;
   int c_oper1_num;
   int c_oper2_num;
   int c_dest_num;
   int specialop;

   int *c_oper1, *c_oper2, *c_dest;

   if(!(player = mo->player))
      return;

   pspr = &(player->psprites[player->curpsprite]);

   c_oper1_num = E_ArgAsInt(pspr->state->args, 0, 0);
   c_oper2_num = E_ArgAsInt(pspr->state->args, 1, 0);
   c_dest_num  = E_ArgAsInt(pspr->state->args, 2, 0);
   specialop   = E_ArgAsKwd(pspr->state->args, 3, &weapctropkwds, 0);

   switch(c_oper1_num)
   {
   case 0:
   case 1:
   case 2:
      c_oper1 = &(player->weaponctrs[player->readyweapon][c_oper1_num]);
      break;
   default:
      return;
   }

   switch(c_oper2_num)
   {
   case 0:
   case 1:
   case 2:
      c_oper2 = &(player->weaponctrs[player->readyweapon][c_oper2_num]);
      break;
   default:
      return;
   }

   switch(c_dest_num)
   {
   case 0:
   case 1:
   case 2:
      c_dest = &(player->weaponctrs[player->readyweapon][c_dest_num]); break;
   default:
      return;
   }

   switch(specialop)
   {
   case CPOP_ADD:
      *c_dest = *c_oper1 + *c_oper2; break;
   case CPOP_SUB:
      *c_dest = *c_oper1 - *c_oper2; break;
   case CPOP_MUL:
      *c_dest = *c_oper1 * *c_oper2; break;
   case CPOP_DIV:
      if(c_oper2) // don't divide by zero
         *c_dest = *c_oper1 / *c_oper2;
      break;
   case CPOP_MOD:
      if(*c_oper2 > 0) // only allow modulus by positive values
         *c_dest = *c_oper1 % *c_oper2;
      break;
   case CPOP_AND:
      *c_dest = *c_oper1 & *c_oper2; break;
   case CPOP_OR:
      *c_dest = *c_oper1 | *c_oper2; break;
   case CPOP_XOR:
      *c_dest = *c_oper1 ^ *c_oper2; break;
   case CPOP_DAMAGE:
      // do a HITDICE-style calculation
      if(*c_oper2 > 0) // the modulus must be positive
         *c_dest = *c_oper1 * ((P_Random(pr_weapsetctr) % *c_oper2) + 1);
      break;
   case CPOP_SHIFTLEFT:
      *c_dest = *c_oper1 << *c_oper2; break;
   case CPOP_SHIFTRIGHT:
      *c_dest = *c_oper1 >> *c_oper2; break;

      // unary operations (c_oper2 is unused for these)
   case CPOP_ABS:
      *c_dest = abs(*c_oper1); break;
   case CPOP_NEGATE:
      *c_dest = -(*c_oper1); break;
   case CPOP_NOT:
      *c_dest = !(*c_oper1); break;
   case CPOP_INVERT:
      *c_dest = ~(*c_oper1); break;
   default:
      break;
   }
}
Пример #12
0
/**
 * Damages both enemies and players.
 *
 * @param inflictor     Mobj that caused the damage creature or missile,
 *                      can be NULL (slime, etc)
 * @param source        Mobj to target after taking damage. Can be @c NULL
 *                      for barrel explosions and other environmental stuff.
 *                      Source and inflictor are the same for melee attacks.
 * @param skipNetworkCheck  Allow the damage to be done regardless of netgame status.
 *
 * @return              Actual amount of damage done.
 */
int P_DamageMobj2(mobj_t *target, mobj_t *inflictor, mobj_t *source,
                  int damageP, dd_bool stomping, dd_bool skipNetworkCheck)
{
    angle_t angle;
    int saved, originalHealth;
    player_t *player;
    int /*temp,*/ damage;

    if(!target)
        return 0; // Wha?

    originalHealth = target->health;

    // The actual damage (== damageP * netMobDamageModifier for any
    // non-player mobj).
    damage = damageP;

    if(!skipNetworkCheck)
    {
        if(IS_NETGAME && !stomping && D_NetDamageMobj(target, inflictor, source, damage))
        {   // We're done here.
            return 0;
        }
        // Clients can't harm anybody.
        if(IS_CLIENT)
            return 0;
    }

    if(!(target->flags & MF_SHOOTABLE))
        return 0; // Shouldn't happen...

    if(target->health <= 0)
        return 0;

    if(target->player)
    {   // Player specific.
        // Check if player-player damage is disabled.
        if(source && source->player && source->player != target->player)
        {
            // Co-op damage disabled?
            if(IS_NETGAME && !G_Ruleset_Deathmatch() && cfg.noCoopDamage)
                return 0;

            // Same color, no damage?
            if(cfg.noTeamDamage &&
               cfg.playerColor[target->player - players] ==
               cfg.playerColor[source->player - players])
                return 0;
        }
    }

    if(target->flags & MF_SKULLFLY)
    {
        target->mom[MX] = target->mom[MY] = target->mom[MZ] = 0;
    }

    player = target->player;
    if(player && G_Ruleset_Skill() == SM_BABY)
        damage /= 2; // Take half damage in trainer mode.

    // Use the cvar damage multiplier netMobDamageModifier only if the
    // inflictor is not a player.
    if(inflictor && !inflictor->player &&
       (!source || (source && !source->player)))
    {
        // damage = (int) ((float) damage * netMobDamageModifier);
        if(IS_NETGAME)
            damage *= cfg.netMobDamageModifier;
    }

    // Some close combat weapons should not inflict thrust and push the
    // victim out of reach, thus kick away unless using a melee weapon.
    if(inflictor && !(target->flags & MF_NOCLIP) &&
       (!source || !source->player ||
        source->player->readyWeapon != WT_EIGHTH) &&
       !(inflictor->flags2 & MF2_NODMGTHRUST))
    {
        uint an;
        coord_t thrust;

        angle = M_PointToAngle2(inflictor->origin, target->origin);
        thrust = FIX2FLT(damage * (FRACUNIT>>3) * 100 / target->info->mass);

        // Make fall forwards sometimes.
        if(damage < 40 && damage > target->health &&
           target->origin[VZ] - inflictor->origin[VZ] > 64 && (P_Random() & 1))
        {
            angle += ANG180;
            thrust *= 4;
        }

        an = angle >> ANGLETOFINESHIFT;
        target->mom[MX] += thrust * FIX2FLT(finecosine[an]);
        target->mom[MY] += thrust * FIX2FLT(finesine[an]);
        NetSv_PlayerMobjImpulse(target, thrust * FIX2FLT(finecosine[an]), thrust * FIX2FLT(finesine[an]), 0);

        // $dropoff_fix: thrust objects hanging off ledges.
        if((target->intFlags & MIF_FALLING) && target->gear >= MAXGEAR)
            target->gear = 0;
    }
Пример #13
0
//
// A_CounterOp
//
// Sets the value of the indicated counter variable for the thing
// using two (possibly the same) counters as operands.
//
// args[0] : counter operand #1
// args[1] : counter operand #2
// args[2] : counter destination
// args[3] : operation to perform
//
void A_CounterOp(Mobj *mo)
{
   int c_oper1_num, c_oper2_num, c_dest_num, specialop;
   int *c_oper1, *c_oper2, *c_dest;

   c_oper1_num = E_ArgAsInt(mo->state->args, 0, 0);
   c_oper2_num = E_ArgAsInt(mo->state->args, 1, 0);
   c_dest_num  = E_ArgAsInt(mo->state->args, 2, 0);   
   specialop   = E_ArgAsKwd(mo->state->args, 3, &cpopkwds, 0);

   if(c_oper1_num < 0 || c_oper1_num >= NUMMOBJCOUNTERS)
      return; // invalid

   c_oper1 = &(mo->counters[c_oper1_num]);

   if(c_oper2_num < 0 || c_oper2_num >= NUMMOBJCOUNTERS)
      return; // invalid

   c_oper2 = &(mo->counters[c_oper2_num]);

   if(c_dest_num < 0 || c_dest_num >= NUMMOBJCOUNTERS)
      return; // invalid

   c_dest = &(mo->counters[c_dest_num]);

   switch(specialop)
   {
   case CPOP_ADD:
      *c_dest = *c_oper1 + *c_oper2; break;
   case CPOP_SUB:
      *c_dest = *c_oper1 - *c_oper2; break;
   case CPOP_MUL:
      *c_dest = *c_oper1 * *c_oper2; break;
   case CPOP_DIV:
      if(c_oper2) // don't divide by zero
         *c_dest = *c_oper1 / *c_oper2;
      break;
   case CPOP_MOD:
      if(*c_oper2 > 0) // only allow modulus by positive values
         *c_dest = *c_oper1 % *c_oper2;
      break;
   case CPOP_AND:
      *c_dest = *c_oper1 & *c_oper2; break;
   case CPOP_OR:
      *c_dest = *c_oper1 | *c_oper2; break;
   case CPOP_XOR:
      *c_dest = *c_oper1 ^ *c_oper2; break;
   case CPOP_DAMAGE:
      // do a HITDICE-style calculation
      if(*c_oper2 > 0) // the modulus must be positive
         *c_dest = *c_oper1 * ((P_Random(pr_setcounter) % *c_oper2) + 1);
      break;
   case CPOP_SHIFTLEFT:
      *c_dest = *c_oper1 << *c_oper2; break;
   case CPOP_SHIFTRIGHT:
      *c_dest = *c_oper1 >> *c_oper2; break;

      // unary operations (c_oper2 is unused for these)
   case CPOP_ABS:
      *c_dest = abs(*c_oper1); break;
   case CPOP_NEGATE:
      *c_dest = -(*c_oper1); break;
   case CPOP_NOT:
      *c_dest = !(*c_oper1); break;
   case CPOP_INVERT:
      *c_dest = ~(*c_oper1); break;
   default:
      break;
   }
}
Пример #14
0
//
// Do Platforms
//	[RH] Changed amount to height and added delay,
//		 lip, change, tag, and speed parameters.
//
BOOL EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height,
				int speed, int delay, int lip, int change)
{
	DPlat *plat;
	int secnum;
	sector_t *sec;
	int rtn = false;
	BOOL manual = false;

	// [RH] If tag is zero, use the sector on the back side
	//		of the activating line (if any).
	if (!tag)
	{
		if (!line || !(sec = line->backsector))
			return false;
		secnum = sec - sectors;
		manual = true;
		goto manual_plat;
	}

	//	Activate all <type> plats that are in_stasis
	switch (type)
	{
	case DPlat::platToggle:
		rtn = true;
	case DPlat::platPerpetualRaise:
		P_ActivateInStasis (tag);
		break;
	
	default:
		break;
	}
		
	secnum = -1;
	while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
	{
		sec = &sectors[secnum];

manual_plat:
		if (sec->floordata)
			continue;
		
		// Find lowest & highest floors around sector
		rtn = true;
		plat = new DPlat (sec);

		plat->m_Type = type;
		plat->m_Crush = false;
		plat->m_Tag = tag;
		plat->m_Speed = speed;
		plat->m_Wait = delay;

		//jff 1/26/98 Avoid raise plat bouncing a head off a ceiling and then
		//going down forever -- default lower to plat height when triggered
		plat->m_Low = sec->floorheight;

		if (change)
		{
			if (line)
				sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
			if (change == 1)
				sec->special = 0;	// Stop damage and other stuff, if any
		}

		switch (type)
		{
		case DPlat::platRaiseAndStay:
			plat->m_High = P_FindNextHighestFloor (sec, sec->floorheight);
			plat->m_Status = DPlat::midup;
			plat->PlayPlatSound();
			break;

		case DPlat::platUpByValue:
		case DPlat::platUpByValueStay:
			plat->m_High = sec->floorheight + height;
			plat->m_Status = DPlat::midup;
			plat->PlayPlatSound();
			break;
		
		case DPlat::platDownByValue:
			plat->m_Low = sec->floorheight - height;
			plat->m_Status = DPlat::middown;
			plat->PlayPlatSound();
			break;

		case DPlat::platDownWaitUpStay:
			plat->m_Low = P_FindLowestFloorSurrounding (sec) + lip*FRACUNIT;

			if (plat->m_Low > sec->floorheight)
				plat->m_Low = sec->floorheight;

			plat->m_High = sec->floorheight;
			plat->m_Status = DPlat::down;
			plat->PlayPlatSound();
			break;
		
		case DPlat::platUpWaitDownStay:
			plat->m_High = P_FindHighestFloorSurrounding (sec);

			if (plat->m_High < sec->floorheight)
				plat->m_High = sec->floorheight;

			plat->m_Status = DPlat::up;
			plat->PlayPlatSound();
			break;

		case DPlat::platPerpetualRaise:
			plat->m_Low = P_FindLowestFloorSurrounding (sec) + lip*FRACUNIT;

			if (plat->m_Low > sec->floorheight)
				plat->m_Low = sec->floorheight;

			plat->m_High = P_FindHighestFloorSurrounding (sec);

			if (plat->m_High < sec->floorheight)
				plat->m_High = sec->floorheight;

			plat->m_Status = P_Random () & 1 ? DPlat::down : DPlat::up;

			plat->PlayPlatSound();
			break;

		case DPlat::platToggle:	//jff 3/14/98 add new type to support instant toggle
			plat->m_Crush = false;	//jff 3/14/98 crush anything in the way

			// set up toggling between ceiling, floor inclusive
			plat->m_Low = sec->ceilingheight;
			plat->m_High = sec->floorheight;
			plat->m_Status = DPlat::down;
// 			SN_StartSequence (sec, "Silence");
			break;

		case DPlat::platDownToNearestFloor:
			plat->m_Low = P_FindNextLowestFloor (sec, sec->floorheight) + lip*FRACUNIT;
			plat->m_Status = DPlat::down;
			plat->m_High = sec->floorheight;
			plat->PlayPlatSound();
			break;

		case DPlat::platDownToLowestCeiling:
		    plat->m_Low = P_FindLowestCeilingSurrounding (sec);
			plat->m_High = sec->floorheight;

			if (plat->m_Low > sec->floorheight)
				plat->m_Low = sec->floorheight;

			plat->m_Status = DPlat::down;
			plat->PlayPlatSound();
			break;

		default:
			break;
		}
		if (manual)
			return rtn;
	}
	return rtn;
}
Пример #15
0
//
// P_SubRandom
//
// haleyjd 08/05/04: This function eliminates the need to use
// temporary variables everywhere in order to subtract two random
// values without incurring order of evaluation problems.
//
int P_SubRandom(pr_class_t pr_class)
{
   int temp = P_Random(pr_class);

   return (temp - P_Random(pr_class));
}
Пример #16
0
void P_KillMobj(mobj_t *source, mobj_t *target, dd_bool stomping)
{
    mobjtype_t          item;
    mobj_t*             mo;
    unsigned int        an;
    angle_t             angle;

    if(!target)
        return; // Nothing to kill...

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

    if(target->type != MT_SKULL)
        target->flags &= ~MF_NOGRAVITY;

    target->flags |= MF_CORPSE | MF_DROPOFF;
    target->flags2 &= ~MF2_PASSMOBJ;
    target->corpseTics = 0;
    target->height /= 2*2;

    if(source && source->player)
    {
        // Count for intermission.
        if(target->flags & MF_COUNTKILL)
        {
            source->player->killCount++;
            source->player->update |= PSF_COUNTERS;
        }

        if(target->player)
        {
            source->player->frags[target->player - players]++;
            NetSv_FragsForAll(source->player);
            NetSv_KillMessage(source->player, target->player, stomping);
        }
    }
    else if(!IS_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 the player.
        if(!source)
        {
            target->player->frags[target->player - players]++;
            NetSv_FragsForAll(target->player);
            NetSv_KillMessage(target->player, target->player, stomping);
        }

        target->flags &= ~MF_SOLID;
        target->flags2 &= ~MF2_FLY;
        target->player->powers[PT_FLIGHT] = 0;
        target->player->playerState = PST_DEAD;
        target->player->rebornWait = PLAYER_REBORN_TICS;
        target->player->update |= PSF_STATE;
        target->player->plr->flags |= DDPF_DEAD;
        P_DropWeapon(target->player);

        // Don't die with the automap open.
        ST_AutomapOpen(target->player - players, false, false);
#if __JHERETIC__ || __JHEXEN__
        Hu_InventoryOpen(target->player - players, false);
#endif
    }

    if(target->health < -target->info->spawnHealth &&
       P_GetState(target->type, SN_XDEATH))
    {   // Extreme death.
        P_MobjChangeState(target, P_GetState(target->type, SN_XDEATH));
    }
    else
    {   // Normal death.
        P_MobjChangeState(target, P_GetState(target->type, SN_DEATH));
    }

    target->tics -= P_Random() & 3;

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

    // Enemies in Chex Quest don't drop stuff.
    if(gameMode == doom_chex)
        return;

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

    case MT_SHOTGUY:
        item = MT_SHOTGUN;
        break;

    case MT_CHAINGUY:
        item = MT_CHAINGUN;
        break;

    default:
        return;
    }

    // Don't drop at the exact same place, causes Z flickering with
    // 3D sprites.
    angle = P_Random() << 24;
    an = angle >> ANGLETOFINESHIFT;
    if((mo = P_SpawnMobjXYZ(item, target->origin[VX] + 3 * FIX2FLT(finecosine[an]),
                            target->origin[VY] + 3 * FIX2FLT(finesine[an]),
                            0, angle, MSF_Z_FLOOR)))
        mo->flags |= MF_DROPPED; // Special versions of items.
}
Пример #17
0
void C_DECL A_CorpseExplode(mobj_t* actor)
{
    int i, n;
    mobj_t* mo;

    for(i = (P_Random() & 3) + 3; i; i--)
    {
        if((mo = P_SpawnMobj(MT_CORPSEBIT, actor->origin, P_Random() << 24, 0)))
        {
            P_MobjChangeState(mo, P_GetState(mo->type, SN_SPAWN) + (P_Random() % 3));

            mo->mom[MZ] = FIX2FLT((P_Random() & 7) + 5) * .75f;
            mo->mom[MX] = FIX2FLT((P_Random() - P_Random()) << 10);
            mo->mom[MY] = FIX2FLT((P_Random() - P_Random()) << 10);
        }
    }

    // Spawn a skull.
    if((mo = P_SpawnMobj(MT_CORPSEBIT, actor->origin, P_Random() << 24, 0)))
    {
        P_MobjChangeState(mo, S_CORPSEBIT_4);

        n = (P_Random() & 7) + 5;
        mo->mom[MZ] = FIX2FLT(n) * .75f;
        mo->mom[MX] = FIX2FLT((P_Random() - P_Random()) << 10);
        mo->mom[MY] = FIX2FLT((P_Random() - P_Random()) << 10);
        S_StartSound(SFX_FIRED_DEATH, mo);
    }
    P_MobjRemove(actor, false);
}
Пример #18
0
static int doPlat(Line *line, int tag, plattype_e type, int amount)
#endif
{
#if !__JHEXEN__
    Sector *frontSector = (Sector *)P_GetPtrp(line, DMU_FRONT_SECTOR);
#endif

    iterlist_t *list = P_GetSectorIterListForTag(tag, false);
    if(!list) return 0;

    int rtn = 0;

    IterList_SetIteratorDirection(list, ITERLIST_FORWARD);
    IterList_RewindIterator(list);

    Sector *sec;
    while((sec = (Sector *)IterList_MoveIterator(list)))
    {
        xsector_t *xsec = P_ToXSector(sec);

        if(xsec->specialData)
            continue;

        // Find lowest & highest floors around sector
        rtn = 1;

        plat_t *plat = (plat_t *) Z_Calloc(sizeof(*plat), PU_MAP, 0);
        plat->thinker.function = T_PlatRaise;
        Thinker_Add(&plat->thinker);

        xsec->specialData = plat;

        plat->type   = type;
        plat->sector = sec;
        plat->crush  = false;
        plat->tag    = tag;
#if __JHEXEN__
        plat->speed  = (float) args[1] * (1.0 / 8);
#endif

        coord_t floorHeight = P_GetDoublep(sec, DMU_FLOOR_HEIGHT);

        switch(type)
        {
#if !__JHEXEN__
        case PT_RAISETONEARESTANDCHANGE:
            plat->speed = PLATSPEED * .5;

            P_SetPtrp(sec, DMU_FLOOR_MATERIAL,
                      P_GetPtrp(frontSector, DMU_FLOOR_MATERIAL));

            {
            coord_t nextFloor;
            if(P_FindSectorSurroundingNextHighestFloor(sec, floorHeight, &nextFloor))
                plat->high = nextFloor;
            else
                plat->high = floorHeight;
            }

            plat->wait = 0;
            plat->state = PS_UP;
            // No more damage if applicable.
            xsec->special = 0;
            S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMMOVE);
            break;

        case PT_RAISEANDCHANGE:
            plat->speed = PLATSPEED * .5;

            P_SetPtrp(sec, DMU_FLOOR_MATERIAL,
                      P_GetPtrp(frontSector, DMU_FLOOR_MATERIAL));

            plat->high = floorHeight + amount;
            plat->wait = 0;
            plat->state = PS_UP;
            S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMMOVE);
            break;
#endif
        case PT_DOWNWAITUPSTAY:
            P_FindSectorSurroundingLowestFloor(sec,
                P_GetDoublep(sec, DMU_FLOOR_HEIGHT), &plat->low);
#if __JHEXEN__
            plat->low += 8;
#else
            plat->speed = PLATSPEED * 4;
#endif
            if(plat->low > floorHeight)
                plat->low = floorHeight;

            plat->high = floorHeight;
            plat->state = PS_DOWN;
#if __JHEXEN__
            plat->wait = (int) args[2];
#else
            plat->wait = PLATWAIT * TICSPERSEC;
#endif
#if !__JHEXEN__
            S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMSTART);
#endif
            break;

#if __JDOOM64__ || __JHEXEN__
        case PT_UPWAITDOWNSTAY:
            P_FindSectorSurroundingHighestFloor(sec, -500, &plat->high);

            if(plat->high < floorHeight)
                plat->high = floorHeight;

            plat->low = floorHeight;
            plat->state = PS_UP;
# if __JHEXEN__
            plat->wait = (int) args[2];
# else
            plat->wait = PLATWAIT * TICSPERSEC;
# endif
# if __JDOOM64__
            plat->speed = PLATSPEED * 8;
            S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMSTART);
# endif
            break;
#endif
#if __JDOOM64__
        case PT_DOWNWAITUPDOOR: // jd64
            plat->speed = PLATSPEED * 8;
            P_FindSectorSurroundingLowestFloor(sec,
                P_GetDoublep(sec, DMU_FLOOR_HEIGHT), &plat->low);

            if(plat->low > floorHeight)
                plat->low = floorHeight;
            if(plat->low != floorHeight)
                plat->low += 6;

            plat->high = floorHeight;
            plat->wait = 50 * PLATWAIT;
            plat->state = PS_DOWN;
            break;
#endif
#if __JHEXEN__
       case PT_DOWNBYVALUEWAITUPSTAY:
            plat->low = floorHeight - (coord_t) args[3] * 8;
            if(plat->low > floorHeight)
                plat->low = floorHeight;
            plat->high = floorHeight;
            plat->wait = (int) args[2];
            plat->state = PS_DOWN;
            break;

        case PT_UPBYVALUEWAITDOWNSTAY:
            plat->high = floorHeight + (coord_t) args[3] * 8;
            if(plat->high < floorHeight)
                plat->high = floorHeight;
            plat->low = floorHeight;
            plat->wait = (int) args[2];
            plat->state = PS_UP;
            break;
#endif
#if __JDOOM__ || __JDOOM64__
        case PT_DOWNWAITUPSTAYBLAZE:
            plat->speed = PLATSPEED * 8;
            P_FindSectorSurroundingLowestFloor(sec,
                P_GetDoublep(sec, DMU_FLOOR_HEIGHT), &plat->low);

            if(plat->low > floorHeight)
                plat->low = floorHeight;

            plat->high = floorHeight;
            plat->wait = PLATWAIT * TICSPERSEC;
            plat->state = PS_DOWN;
            S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMSTART);
            break;
#endif
        case PT_PERPETUALRAISE:
            P_FindSectorSurroundingLowestFloor(sec,
                P_GetDoublep(sec, DMU_FLOOR_HEIGHT), &plat->low);
#if __JHEXEN__
            plat->low += 8;
#else
            plat->speed = PLATSPEED;
#endif
            if(plat->low > floorHeight)
                plat->low = floorHeight;

            P_FindSectorSurroundingHighestFloor(sec, -500, &plat->high);

            if(plat->high < floorHeight)
                plat->high = floorHeight;

            plat->state = platstate_e(P_Random() & 1);
#if __JHEXEN__
            plat->wait = (int) args[2];
#else
            plat->wait = PLATWAIT * TICSPERSEC;
#endif
#if !__JHEXEN__
            S_PlaneSound((Plane *)P_GetPtrp(sec, DMU_FLOOR_PLANE), SFX_PLATFORMSTART);
#endif
            break;

        default:
            break;
        }

#if __JHEXEN__
        SN_StartSequenceInSec(plat->sector, SEQ_PLATFORM);
#endif
    }

    return rtn;
}
Пример #19
0
static void P_LightningFlash(void)
{
    int i;
    sector_t *tempSec;
    bool foundSec;
    int flashLight;
    static PointThinker thunderSndOrigin;

    if(LightningFlash)
    {
        LightningFlash--;

        if(LightningFlash)
        {
            for(i = 0; i < numsectors; i++)
            {
                tempSec = &sectors[i];

                if(tempSec->intflags & SIF_SKY &&
                        tempSec->oldlightlevel < tempSec->lightlevel - 4)
                {
                    tempSec->lightlevel -= 4;
                }
            }
        }
        else
        {
            for(i = 0; i < numsectors; i++)
            {
                tempSec = &sectors[i];

                if(tempSec->intflags & SIF_SKY)
                    tempSec->lightlevel = tempSec->oldlightlevel;
            }

            if(LevelSky != -1 && LevelTempSky != -1)
                skytexture = LevelSky;
        }
    }
    else
    {
        LightningFlash = (P_Random(pr_lightning) & 7) + 8;
        flashLight     = 200 + (P_Random(pr_lightning) & 31);

        foundSec = false;

        for(i = 0; i < numsectors; i++)
        {
            tempSec = &sectors[i];

            if(tempSec->intflags & SIF_SKY)
            {
                tempSec->oldlightlevel = tempSec->lightlevel;
                tempSec->lightlevel    = flashLight;

                if(tempSec->lightlevel < tempSec->oldlightlevel)
                    tempSec->lightlevel = tempSec->oldlightlevel;

                foundSec = true;
            }
        }

        if(foundSec)
        {
            if(LevelSky != -1 && LevelTempSky != -1)
                skytexture = LevelTempSky;

            S_StartSoundAtVolume(&thunderSndOrigin, sfx_thundr,
                                 127, ATTN_NONE, CHAN_AUTO);
        }

        if(!NextLightningFlash)
        {
            if(M_Random() < 50)
                NextLightningFlash = (M_Random() & 15) + 16;
            else
            {
                if(M_Random() < 128 && !(leveltime & 32))
                    NextLightningFlash = ((M_Random() & 7) + 2) * 35;
                else
                    NextLightningFlash = ((M_Random() & 15) + 5) * 35;
            }
        }
    }
}
Пример #20
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;
			}
		}
	}
}
Пример #21
0
static cell AMX_NATIVE_CALL sm_random(AMX *amx, cell *params)
{
   return P_Random(pr_script);
}
Пример #22
0
//
// P_RangeRandom
//
// haleyjd 05/31/06: Returns a random number within a given range.
//
int P_RangeRandom(pr_class_t pr_class, int min, int max)
{
   return (P_Random(pr_class) % (max - min + 1)) + min;
}
Пример #23
0
void P_AmbientSound(void)
{
	afxcmd_t cmd;
	int sound;
	boolean done;

	if(!AmbSfxCount)
	{ // No ambient sound sequences on current level
		return;
	}
	if(--AmbSfxTics)
	{
		return;
	}
	done = false;
	do
	{
		cmd = *AmbSfxPtr++;
		switch(cmd)
		{
			case afxcmd_play:
				AmbSfxVolume = P_Random()>>2;
				S_StartSoundAtVolume(NULL, *AmbSfxPtr++, AmbSfxVolume);
				break;
			case afxcmd_playabsvol:
				sound = *AmbSfxPtr++;
				AmbSfxVolume = *AmbSfxPtr++;
				S_StartSoundAtVolume(NULL, sound, AmbSfxVolume);
				break;
			case afxcmd_playrelvol:
				sound = *AmbSfxPtr++;
				AmbSfxVolume += *AmbSfxPtr++;
				if(AmbSfxVolume < 0)
				{
					AmbSfxVolume = 0;
				}
				else if(AmbSfxVolume > 127)
				{
					AmbSfxVolume = 127;
				}			
				S_StartSoundAtVolume(NULL, sound, AmbSfxVolume);
				break;
			case afxcmd_delay:
				AmbSfxTics = *AmbSfxPtr++;
				done = true;
				break;
			case afxcmd_delayrand:
				AmbSfxTics = P_Random()&(*AmbSfxPtr++);
				done = true;
				break;
			case afxcmd_end:
				AmbSfxTics = 6*TICSPERSEC+P_Random();
				AmbSfxPtr = LevelAmbientSfx[P_Random()%AmbSfxCount];
				done = true;
				break;
			default:
				I_Error("P_AmbientSound: Unknown afxcmd %d", cmd);
				break;
		}
	} while(done == false);
}
Пример #24
0
void C_DECL A_PoisonShroom(mobj_t* actor)
{
    actor->tics = 128 + (P_Random() << 1);
}
Пример #25
0
//
// P_PlayerInSpecialSector
// Called every tic frame
//  that the player origin is in a special sector
//
void P_PlayerInSpecialSector (player_t* player)
{
    sector_t*	sector;
    extern int showMessages;
    player2_t  *player2 = p2fromp(player);
    static sector_t*	error;
	
    sector = player->mo->subsector->sector;

    // Falling, not all the way down yet?
    if (player->mo->z != sector->floorheight)
	return;	

    // Has hitten ground.
    switch (sector->special)
    {
      case 5:
	// HELLSLIME DAMAGE
	if (!player->powers[pw_ironfeet])
	    if (!(leveltime&0x1f))
		P_DamageMobj (player->mo, NULL, NULL, 10);
	break;
	
      case 7:
	// NUKAGE DAMAGE
	if (!player->powers[pw_ironfeet])
	    if (!(leveltime&0x1f))
		P_DamageMobj (player->mo, NULL, NULL, 5);
	break;
	
      case 16:
	// SUPER HELLSLIME DAMAGE
      case 4:
	// STROBE HURT
	if (!player->powers[pw_ironfeet]
	    || (P_Random()<5) )
	{
	    if (!(leveltime&0x1f))
		P_DamageMobj (player->mo, NULL, NULL, 20);
	}
	break;
			
      case 9:
	// SECRET SECTOR
	// [crispy] show centered "Secret Revealed!" message
	if (showMessages && crispy_secretmessage)
	{
	    player2->centermessage = HUSTR_SECRETFOUND;
	    if (player == &players[consoleplayer])
	        S_StartSound(NULL, sfx_itmbk);
	}
	player->secretcount++;
	sector->special = 0;
	break;
			
      case 11:
	// EXIT SUPER DAMAGE! (for E1M8 finale)
	player->cheats &= ~CF_GODMODE;

	if (!(leveltime&0x1f))
	    P_DamageMobj (player->mo, NULL, NULL, 20);

	if (player->health <= 10)
	    G_ExitLevel();
	break;
			
      default:
	// [crispy] ignore unknown special sectors
	if (error != sector)
	{
	error = sector;
	printf ("P_PlayerInSpecialSector: "
		 "unknown special %i\n",
		 sector->special);
	}
	break;
    };
}
Пример #26
0
int P_RandomShift(int shift)
{
    int rand = P_Random();
    return (rand - P_Random()) << shift;
}
Пример #27
0
// A_CentaurAttack2
//
void A_CentaurAttack2(Mobj *actor)
{
   // HEXEN_TODO
}

//
// P_TossEquipmentItem
//
// Throws an object away from the source.
//
static void P_TossEquipmentItem(Mobj *mo, angle_t angle, int momshift, 
                                fixed_t baseZMom)
{
   mo->momx = FixedMul(((P_Random(pr_dropequip) - 128) << momshift) + FRACUNIT,
                       finecosine[angle >> ANGLETOFINESHIFT]);

   mo->momy = FixedMul(((P_Random(pr_dropequip) - 128) << momshift) + FRACUNIT,
                       finesine[angle >> ANGLETOFINESHIFT]);
   
   mo->momz = baseZMom + (P_Random(pr_dropequip) << (momshift - 1));
}

//
// A_DropEquipment
//
// Note: was A_CentaurDropStuff in Hexen
// Parameters:
// * args[0] : thing type 1
// * args[1] : thing type 2
Пример #28
0
//
// P_PlayerInSpecialSector
// Called every tic frame
//  that the player origin is in a special sector
//
void P_PlayerInSpecialSector (player_t* player)
{
    sector_t*	sector;
	
    sector = player->mo->subsector->sector;

    // Falling, not all the way down yet?
    if (player->mo->z != sector->floorheight)
	return;	

    // Has hitten ground.
    switch (sector->special)
    {
      case 5:
	// HELLSLIME DAMAGE
	if (!player->powers[pw_ironfeet])
	    if (!(leveltime&0x1f))
		P_DamageMobj (player->mo, NULL, NULL, 10);
	break;
	
      case 7:
	// NUKAGE DAMAGE
	if (!player->powers[pw_ironfeet])
	    if (!(leveltime&0x1f))
		P_DamageMobj (player->mo, NULL, NULL, 5);
	break;
	
      case 16:
	// SUPER HELLSLIME DAMAGE
      case 4:
	// STROBE HURT
	if (!player->powers[pw_ironfeet]
	    || (P_Random()<5) )
	{
	    if (!(leveltime&0x1f))
		P_DamageMobj (player->mo, NULL, NULL, 20);
	}
	break;
			
      case 9:
	// SECRET SECTOR
	player->secretcount++;
	sector->special = 0;
	break;
			
      case 11:
	// EXIT SUPER DAMAGE! (for E1M8 finale)
	player->cheats &= ~CF_GODMODE;

	if (!(leveltime&0x1f))
	    P_DamageMobj (player->mo, NULL, NULL, 20);

	if (player->health <= 10)
	    G_ExitLevel();
	break;
			
      default:
	I_Error ("P_PlayerInSpecialSector: "
		 "unknown special %i",
		 sector->special);
	break;
    };
}
Пример #29
0
//==================================================================
//
//      Do Platforms
//      "amount" is only used for SOME platforms.
//
//==================================================================
int EV_DoPlat(line_t * line, plattype_e type, int amount)
{
    plat_t *plat;
    int secnum;
    int rtn;
    sector_t *sec;

    secnum = -1;
    rtn = 0;

    //
    //      Activate all <type> plats that are in_stasis
    //
    switch (type)
    {
        case perpetualRaise:
            P_ActivateInStasis(line->tag);
            break;
        default:
            break;
    }

    while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0)
    {
        sec = &sectors[secnum];
        if (sec->specialdata)
            continue;

        //
        // Find lowest & highest floors around sector
        //
        rtn = 1;
        plat = Z_Malloc(sizeof(*plat), PU_LEVSPEC, 0);
        P_AddThinker(&plat->thinker);

        plat->type = type;
        plat->sector = sec;
        plat->sector->specialdata = plat;
        plat->thinker.function = T_PlatRaise;
        plat->crush = false;
        plat->tag = line->tag;
        switch (type)
        {
            case raiseToNearestAndChange:
                plat->speed = PLATSPEED / 2;
                sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
                plat->high = P_FindNextHighestFloor(sec, sec->floorheight);
                plat->wait = 0;
                plat->status = up;
                sec->special = 0;       // NO MORE DAMAGE, IF APPLICABLE
                S_StartSound(&sec->soundorg, sfx_stnmov);
                break;
            case raiseAndChange:
                plat->speed = PLATSPEED / 2;
                sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
                plat->high = sec->floorheight + amount * FRACUNIT;
                plat->wait = 0;
                plat->status = up;
                S_StartSound(&sec->soundorg, sfx_stnmov);
                break;
            case downWaitUpStay:
                plat->speed = PLATSPEED * 4;
                plat->low = P_FindLowestFloorSurrounding(sec);
                if (plat->low > sec->floorheight)
                    plat->low = sec->floorheight;
                plat->high = sec->floorheight;
                plat->wait = 35 * PLATWAIT;
                plat->status = down;
                S_StartSound(&sec->soundorg, sfx_pstart);
                break;
            case perpetualRaise:
                plat->speed = PLATSPEED;
                plat->low = P_FindLowestFloorSurrounding(sec);
                if (plat->low > sec->floorheight)
                    plat->low = sec->floorheight;
                plat->high = P_FindHighestFloorSurrounding(sec);
                if (plat->high < sec->floorheight)
                    plat->high = sec->floorheight;
                plat->wait = 35 * PLATWAIT;
                plat->status = P_Random() & 1;
                S_StartSound(&sec->soundorg, sfx_pstart);
                break;
        }
        P_AddActivePlat(plat);
    }
    return rtn;
}
Пример #30
0
void C_DECL A_PotteryChooseBit(mobj_t* actor)
{
    P_MobjChangeState(actor, P_GetState(actor->type, SN_DEATH) + (P_Random() % 5) + 1);
    actor->tics = 256 + (P_Random() << 1);
}