亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? p_enemy.c

?? 游戲類程序源代碼---WinDoom 3D源程序.zip
?? C
?? 第 1 頁 / 共 3 頁
字號:
// Emacs style mode select   -*- C++ -*- 
//-----------------------------------------------------------------------------
//
// $Id:$
//
// Copyright (C) 1993-1996 by id Software, Inc.
//
// This source is available for distribution and/or modification
// only under the terms of the DOOM Source Code License as
// published by id Software. All rights reserved.
//
// The source is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
// for more details.
//
// $Log:$
//
// DESCRIPTION:
//	Enemy thinking, AI.
//	Action Pointer Functions
//	that are associated with states/frames. 
//
//-----------------------------------------------------------------------------

static const char
rcsid[] = "$Id: p_enemy.c,v 1.5 1997/02/03 22:45:11 b1 Exp $";

#include <stdlib.h>

#include "m_random.h"
#include "i_system.h"

#include "doomdef.h"
#include "p_local.h"

#include "s_sound.h"

#include "g_game.h"

// State.
#include "doomstat.h"
#include "r_state.h"

// Data.
#include "sounds.h"




typedef enum
{
    DI_EAST,
    DI_NORTHEAST,
    DI_NORTH,
    DI_NORTHWEST,
    DI_WEST,
    DI_SOUTHWEST,
    DI_SOUTH,
    DI_SOUTHEAST,
    DI_NODIR,
    NUMDIRS
    
} dirtype_t;


//
// P_NewChaseDir related LUT.
//
dirtype_t opposite[] =
{
  DI_WEST, DI_SOUTHWEST, DI_SOUTH, DI_SOUTHEAST,
  DI_EAST, DI_NORTHEAST, DI_NORTH, DI_NORTHWEST, DI_NODIR
};

dirtype_t diags[] =
{
    DI_NORTHWEST, DI_NORTHEAST, DI_SOUTHWEST, DI_SOUTHEAST
};





void A_Fall (mobj_t *actor);


//
// ENEMY THINKING
// Enemies are allways spawned
// with targetplayer = -1, threshold = 0
// Most monsters are spawned unaware of all players,
// but some can be made preaware
//


//
// Called by P_NoiseAlert.
// Recursively traverse adjacent sectors,
// sound blocking lines cut off traversal.
//

mobj_t*		soundtarget;

void
P_RecursiveSound
( sector_t*	sec,
  int		soundblocks )
{
    int		i;
    line_t*	check;
    sector_t*	other;
	
    // wake up all monsters in this sector
    if (sec->validcount == validcount
	&& sec->soundtraversed <= soundblocks+1)
    {
	return;		// already flooded
    }
    
    sec->validcount = validcount;
    sec->soundtraversed = soundblocks+1;
    sec->soundtarget = soundtarget;
	
    for (i=0 ;i<sec->linecount ; i++)
    {
	check = sec->lines[i];
	if (! (check->flags & ML_TWOSIDED) )
	    continue;
	
	P_LineOpening (check);

	if (openrange <= 0)
	    continue;	// closed door
	
	if ( sides[ check->sidenum[0] ].sector == sec)
	    other = sides[ check->sidenum[1] ] .sector;
	else
	    other = sides[ check->sidenum[0] ].sector;
	
	if (check->flags & ML_SOUNDBLOCK)
	{
	    if (!soundblocks)
		P_RecursiveSound (other, 1);
	}
	else
	    P_RecursiveSound (other, soundblocks);
    }
}



//
// P_NoiseAlert
// If a monster yells at a player,
// it will alert other monsters to the player.
//
void
P_NoiseAlert
( mobj_t*	target,
  mobj_t*	emmiter )
{
    soundtarget = target;
    validcount++;
    P_RecursiveSound (emmiter->subsector->sector, 0);
}




//
// P_CheckMeleeRange
//
boolean P_CheckMeleeRange (mobj_t*	actor)
{
    mobj_t*	pl;
    fixed_t	dist;
	
    if (!actor->target)
	return false;
		
    pl = actor->target;
    dist = P_AproxDistance (pl->x-actor->x, pl->y-actor->y);

    if (dist >= MELEERANGE-20*FRACUNIT+pl->info->radius)
	return false;
	
    if (! P_CheckSight (actor, actor->target) )
	return false;
							
    return true;		
}

//
// P_CheckMissileRange
//
boolean P_CheckMissileRange (mobj_t* actor)
{
    fixed_t	dist;
	
    if (! P_CheckSight (actor, actor->target) )
	return false;
	
    if ( actor->flags & MF_JUSTHIT )
    {
	// the target just hit the enemy,
	// so fight back!
	actor->flags &= ~MF_JUSTHIT;
	return true;
    }
	
    if (actor->reactiontime)
	return false;	// do not attack yet
		
    // OPTIMIZE: get this from a global checksight
    dist = P_AproxDistance ( actor->x-actor->target->x,
			     actor->y-actor->target->y) - 64*FRACUNIT;
    
    if (!actor->info->meleestate)
	dist -= 128*FRACUNIT;	// no melee attack, so fire more

    dist >>= 16;

    if (actor->type == MT_VILE)
    {
	if (dist > 14*64)	
	    return false;	// too far away
    }
	

    if (actor->type == MT_UNDEAD)
    {
	if (dist < 196)	
	    return false;	// close for fist attack
	dist >>= 1;
    }
	

    if (actor->type == MT_CYBORG
	|| actor->type == MT_SPIDER
	|| actor->type == MT_SKULL)
    {
	dist >>= 1;
    }
    
    if (dist > 200)
	dist = 200;
		
    if (actor->type == MT_CYBORG && dist > 160)
	dist = 160;
		
    if (P_Random () < dist)
	return false;
		
    return true;
}


//
// P_Move
// Move in the current direction,
// returns false if the move is blocked.
//
fixed_t	xspeed[8] = {FRACUNIT,47000,0,-47000,-FRACUNIT,-47000,0,47000};
fixed_t yspeed[8] = {0,47000,FRACUNIT,47000,0,-47000,-FRACUNIT,-47000};

#define MAXSPECIALCROSS	8

extern	line_t*	spechit[MAXSPECIALCROSS];
extern	int	numspechit;

boolean P_Move (mobj_t*	actor)
{
    fixed_t	tryx;
    fixed_t	tryy;
    
    line_t*	ld;
    
    // warning: 'catch', 'throw', and 'try'
    // are all C++ reserved words
    boolean	try_ok;
    boolean	good;
		
    if (actor->movedir == DI_NODIR)
	return false;
		
    if ((unsigned)actor->movedir >= 8)
	I_Error ("Weird actor->movedir!");
		
    tryx = actor->x + actor->info->speed*xspeed[actor->movedir];
    tryy = actor->y + actor->info->speed*yspeed[actor->movedir];

    try_ok = P_TryMove (actor, tryx, tryy);

    if (!try_ok)
    {
	// open any specials
	if (actor->flags & MF_FLOAT && floatok)
	{
	    // must adjust height
	    if (actor->z < tmfloorz)
		actor->z += FLOATSPEED;
	    else
		actor->z -= FLOATSPEED;

	    actor->flags |= MF_INFLOAT;
	    return true;
	}
		
	if (!numspechit)
	    return false;
			
	actor->movedir = DI_NODIR;
	good = false;
	while (numspechit--)
	{
	    ld = spechit[numspechit];
	    // if the special is not a door
	    // that can be opened,
	    // return false
	    if (P_UseSpecialLine (actor, ld,0))
		good = true;
	}
	return good;
    }
    else
    {
	actor->flags &= ~MF_INFLOAT;
    }
	
	
    if (! (actor->flags & MF_FLOAT) )	
	actor->z = actor->floorz;
    return true; 
}


//
// TryWalk
// Attempts to move actor on
// in its current (ob->moveangle) direction.
// If blocked by either a wall or an actor
// returns FALSE
// If move is either clear or blocked only by a door,
// returns TRUE and sets...
// If a door is in the way,
// an OpenDoor call is made to start it opening.
//
boolean P_TryWalk (mobj_t* actor)
{	
    if (!P_Move (actor))
    {
	return false;
    }

    actor->movecount = P_Random()&15;
    return true;
}




void P_NewChaseDir (mobj_t*	actor)
{
    fixed_t	deltax;
    fixed_t	deltay;
    
    dirtype_t	d[3];
    
    int		tdir;
    dirtype_t	olddir;
    
    dirtype_t	turnaround;

    if (!actor->target)
	I_Error ("P_NewChaseDir: called with no target");
		
    olddir = actor->movedir;
    turnaround=opposite[olddir];

    deltax = actor->target->x - actor->x;
    deltay = actor->target->y - actor->y;

    if (deltax>10*FRACUNIT)
	d[1]= DI_EAST;
    else if (deltax<-10*FRACUNIT)
	d[1]= DI_WEST;
    else
	d[1]=DI_NODIR;

    if (deltay<-10*FRACUNIT)
	d[2]= DI_SOUTH;
    else if (deltay>10*FRACUNIT)
	d[2]= DI_NORTH;
    else
	d[2]=DI_NODIR;

    // try direct route
    if (d[1] != DI_NODIR
	&& d[2] != DI_NODIR)
    {
	actor->movedir = diags[((deltay<0)<<1)+(deltax>0)];
	if (actor->movedir != turnaround && P_TryWalk(actor))
	    return;
    }

    // try other directions
    if (P_Random() > 200
	||  abs(deltay)>abs(deltax))
    {
	tdir=d[1];
	d[1]=d[2];
	d[2]=tdir;
    }

    if (d[1]==turnaround)
	d[1]=DI_NODIR;
    if (d[2]==turnaround)
	d[2]=DI_NODIR;
	
    if (d[1]!=DI_NODIR)
    {
	actor->movedir = d[1];
	if (P_TryWalk(actor))
	{
	    // either moved forward or attacked
	    return;
	}
    }

    if (d[2]!=DI_NODIR)
    {
	actor->movedir =d[2];

	if (P_TryWalk(actor))
	    return;
    }

    // there is no direct path to the player,
    // so pick another direction.
    if (olddir!=DI_NODIR)
    {
	actor->movedir =olddir;

	if (P_TryWalk(actor))
	    return;
    }

    // randomly determine direction of search
    if (P_Random()&1) 	
    {
	for ( tdir=DI_EAST;
	      tdir<=DI_SOUTHEAST;
	      tdir++ )
	{
	    if (tdir!=turnaround)
	    {
		actor->movedir =tdir;
		
		if ( P_TryWalk(actor) )
		    return;
	    }
	}
    }
    else
    {
	for ( tdir=DI_SOUTHEAST;
	      tdir != (DI_EAST-1);
	      tdir-- )
	{
	    if (tdir!=turnaround)
	    {
		actor->movedir =tdir;
		
		if ( P_TryWalk(actor) )
		    return;
	    }
	}
    }

    if (turnaround !=  DI_NODIR)
    {
	actor->movedir =turnaround;
	if ( P_TryWalk(actor) )
	    return;
    }

    actor->movedir = DI_NODIR;	// can not move
}



//
// P_LookForPlayers
// If allaround is false, only look 180 degrees in front.
// Returns true if a player is targeted.
//
boolean
P_LookForPlayers
( mobj_t*	actor,
  boolean	allaround )
{
    int		c;
    int		stop;
    player_t*	player;
    sector_t*	sector;
    angle_t	an;
    fixed_t	dist;
		
    sector = actor->subsector->sector;
	
    c = 0;
    stop = (actor->lastlook-1)&3;
	
    for ( ; ; actor->lastlook = (actor->lastlook+1)&3 )
    {
	if (!playeringame[actor->lastlook])
	    continue;
			
	if (c++ == 2
	    || actor->lastlook == stop)
	{
	    // done looking
	    return false;	
	}
	
	player = &players[actor->lastlook];

	if (player->health <= 0)
	    continue;		// dead

	if (!P_CheckSight (actor, player->mo))
	    continue;		// out of sight
			
	if (!allaround)
	{
	    an = R_PointToAngle2 (actor->x,
				  actor->y, 
				  player->mo->x,
				  player->mo->y)
		- actor->angle;
	    
	    if (an > ANG90 && an < ANG270)
	    {
		dist = P_AproxDistance (player->mo->x - actor->x,
					player->mo->y - actor->y);
		// if real close, react anyway
		if (dist > MELEERANGE)
		    continue;	// behind back
	    }
	}
		
	actor->target = player->mo;
	return true;
    }

    return false;
}


//
// A_KeenDie
// DOOM II special, map 32.
// Uses special tag 666.
//
void A_KeenDie (mobj_t* mo)
{
    thinker_t*	th;
    mobj_t*	mo2;
    line_t	junk;

    A_Fall (mo);
    
    // scan the remaining thinkers
    // to see if all Keens are dead
    for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
    {
	if (th->function.acp1 != (actionf_p1)P_MobjThinker)
	    continue;

	mo2 = (mobj_t *)th;
	if (mo2 != mo
	    && mo2->type == mo->type
	    && mo2->health > 0)
	{
	    // other Keen not dead
	    return;		
	}
    }

    junk.tag = 666;
    EV_DoDoor(&junk,open);
}


//
// ACTION ROUTINES
//

//
// A_Look
// Stay in state until a player is sighted.
//
void A_Look (mobj_t* actor)
{
    mobj_t*	targ;
	
    actor->threshold = 0;	// any shot will wake up
    targ = actor->subsector->sector->soundtarget;

    if (targ
	&& (targ->flags & MF_SHOOTABLE) )
    {
	actor->target = targ;

	if ( actor->flags & MF_AMBUSH )
	{
	    if (P_CheckSight (actor, actor->target))
		goto seeyou;
	}
	else
	    goto seeyou;
    }
	
	
    if (!P_LookForPlayers (actor, false) )
	return;
		
    // go into chase state
  seeyou:
    if (actor->info->seesound)
    {
	int		sound;
		
	switch (actor->info->seesound)
	{
	  case sfx_posit1:
	  case sfx_posit2:
	  case sfx_posit3:
	    sound = sfx_posit1+P_Random()%3;
	    break;

	  case sfx_bgsit1:
	  case sfx_bgsit2:
	    sound = sfx_bgsit1+P_Random()%2;
	    break;

	  default:
	    sound = actor->info->seesound;
	    break;
	}

	if (actor->type==MT_SPIDER
	    || actor->type == MT_CYBORG)
	{
	    // full volume
	    S_StartSound (NULL, sound);
	}
	else
	    S_StartSound (actor, sound);
    }

    P_SetMobjState (actor, actor->info->seestate);
}


//
// A_Chase
// Actor has a melee attack,
// so it tries to close as fast as possible

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产一区二区h| 欧美变态口味重另类| 欧美群妇大交群中文字幕| 日韩免费看的电影| 最新国产成人在线观看| 久久www免费人成看片高清| 日本电影欧美片| 日本一区二区三区四区| 青草国产精品久久久久久| 色呦呦日韩精品| 国产欧美日韩精品一区| 美日韩一区二区| 欧美在线短视频| 亚洲欧美区自拍先锋| 国产ts人妖一区二区| 欧美一二三四区在线| 一区二区三区四区在线播放| 国产美女精品人人做人人爽| 日韩一区二区三区观看| 亚洲午夜电影网| 色综合久久久久久久| 国产精品电影一区二区| 国产成人午夜99999| 欧美变态凌虐bdsm| 久久精品av麻豆的观看方式| 日韩一区二区高清| 奇米影视7777精品一区二区| 欧美老肥妇做.爰bbww| 午夜久久电影网| 欧美日韩国产精品成人| 亚洲国产精品综合小说图片区| 一本久久a久久免费精品不卡| 国产精品久久看| 成人免费看片app下载| 国产欧美日韩精品一区| 大桥未久av一区二区三区中文| 久久综合九色综合欧美98| 蜜臀久久99精品久久久久久9| 欧美日韩dvd在线观看| 日韩有码一区二区三区| 欧美一卡二卡三卡四卡| 免费成人av在线| 精品入口麻豆88视频| 国产一区二区三区最好精华液| 欧美电视剧免费观看| 国内外成人在线| 日本一区二区三区dvd视频在线| 国产91精品一区二区麻豆亚洲| 国产精品另类一区| 色噜噜狠狠色综合欧洲selulu| 一区二区视频在线看| 欧美在线观看18| 奇米精品一区二区三区在线观看| 欧美成人国产一区二区| 国产电影精品久久禁18| 亚洲毛片av在线| 日韩一区和二区| 国产不卡视频一区| 亚洲精品国产精品乱码不99| 在线成人高清不卡| 国产美女视频一区| 一区二区三区日韩欧美| 91麻豆精品国产无毒不卡在线观看| 精品在线亚洲视频| 中文字幕在线不卡| 欧美日韩国产一级片| 国产成人在线视频播放| 亚洲综合在线视频| 2021久久国产精品不只是精品| 不卡av电影在线播放| 日日嗨av一区二区三区四区| 国产人成一区二区三区影院| 欧美亚洲尤物久久| 激情久久五月天| 依依成人综合视频| 久久夜色精品国产欧美乱极品| 色婷婷狠狠综合| 国产一区二区导航在线播放| 亚洲综合丁香婷婷六月香| 精品国产成人系列| 欧美日韩三级一区| 成人动漫在线一区| 美国欧美日韩国产在线播放| 一区二区三区四区乱视频| 2023国产精华国产精品| 欧美人妖巨大在线| 色先锋久久av资源部| 成人小视频免费在线观看| 免费成人深夜小野草| 亚洲一区二区三区四区五区黄| 国产午夜精品一区二区三区视频| 欧美精品电影在线播放| 一本久久综合亚洲鲁鲁五月天| 国产麻豆精品久久一二三| 日本美女视频一区二区| 一区二区三区在线视频观看58| 国产欧美综合在线| 精品国产乱码久久久久久久久| 欧美人狂配大交3d怪物一区| 色婷婷av一区二区三区大白胸 | 国产高清亚洲一区| 视频一区视频二区中文| 亚洲国产另类精品专区| 亚洲视频精选在线| 国产精品久久二区二区| 国产欧美精品区一区二区三区 | 欧美老肥妇做.爰bbww视频| 99久久精品国产麻豆演员表| 丰满少妇在线播放bd日韩电影| 精品一区二区在线视频| 奇米影视7777精品一区二区| 日韩av二区在线播放| 午夜精品视频一区| 视频一区视频二区中文| 日韩精品亚洲一区| 人禽交欧美网站| 麻豆久久一区二区| 黄网站免费久久| 国产老妇另类xxxxx| 国产在线乱码一区二区三区| 国产另类ts人妖一区二区| 国产成人亚洲综合a∨婷婷| 成人黄色片在线观看| 97精品国产97久久久久久久久久久久 | 国产成人免费在线观看不卡| 粉嫩aⅴ一区二区三区四区| 国产精品1区2区| 91麻豆自制传媒国产之光| 91在线你懂得| 欧美日韩综合在线| 欧美一区在线视频| 久久久久久9999| 中文字幕在线播放不卡一区| 亚洲一区二区在线视频| 日韩中文字幕1| 国产在线视频不卡二| 99国产精品久| 91精品国产综合久久精品性色| 欧美sm极限捆绑bd| ...xxx性欧美| 日欧美一区二区| 成人免费观看视频| 欧美日韩亚洲国产综合| 久久先锋影音av鲁色资源网| 最新高清无码专区| 免费日本视频一区| av在线免费不卡| 欧美一区二区三区爱爱| 国产精品网站在线观看| 亚洲1区2区3区视频| 国产精品99久久久久久宅男| 色偷偷久久人人79超碰人人澡| 91麻豆精品国产自产在线| 国产精品美日韩| 日韩高清不卡一区| 岛国精品在线播放| 日韩三级中文字幕| 亚洲人精品午夜| 激情六月婷婷久久| 欧美色男人天堂| 国产日产欧美一区| 日韩二区在线观看| 色香蕉久久蜜桃| 日本一区二区高清| 青青草国产成人av片免费| 91丨porny丨国产入口| 久久综合av免费| 日韩高清中文字幕一区| 91蜜桃网址入口| 欧美极品xxx| 国模冰冰炮一区二区| 欧美男同性恋视频网站| 成人免费小视频| 国产在线不卡一区| 日韩一区二区三区三四区视频在线观看| 国产精品国产成人国产三级 | www.日韩在线| 2024国产精品视频| 强制捆绑调教一区二区| 在线观看免费视频综合| 最新国产の精品合集bt伙计| 国产一区二区主播在线| 欧美一二三区精品| 五月天激情综合| 欧美亚洲一区二区在线观看| 亚洲欧美aⅴ...| www.爱久久.com| 国产亚洲欧美激情| 国产中文字幕一区| 久久综合成人精品亚洲另类欧美| 日日夜夜一区二区| 在线播放一区二区三区| 亚洲一区二区三区爽爽爽爽爽 | 日韩欧美一区二区三区在线| 亚洲第一主播视频| 欧美自拍偷拍一区| 亚洲精品va在线观看| 一本大道久久a久久综合| 中文字幕一区二区视频| av电影在线观看不卡|