⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 monster.cpp

📁 quake 游戏原代码
💻 CPP
字号:
#include "ray.h"
#include "globals.h"
#include "rayspr.h"
#include "sprfunc.h"
#include "sfvars.h"
#include "sprinter.h"
#include "fixed.h"
#include "rayfile.h"
#include "message.h"
#include "classes.h"
#include "defobj.h"
#include "getangle.h"
#include "visible.h"
#include "abs.h"

#define MAX_TIME_TO_LOSE_INTEREST 500
#define GUN_SPEED 50
#define MIN_OBJ_DIS (15*ONE)
#define ANIM_SPEED 31
#define ANIM_SHIFT 4
#define GUN_HEIGHT (cur_object->type->eye_height-10)
typedef struct MONSTER_DATA * pmonster_data;
typedef struct MONSTER_DATA {
   pobject cur_target;
   pvector2 patrol;
   short patrol_count;
   short time_to_lose_interest;
   short time_to_bullet;
   BOOL need_new_point;
   short cur_point;
} monster_data;

void Monster_Create(pobject cur_object, long extra_data_offset);
void Monster_Update(pobject cur_object, long update_num);
ULONG Monster_Message(pobject send_obj, pobject receive_obj, ULONG message, pdata extra_data);

void Init_Monsters(func_index index) {
   update_funcs[index]=Monster_Update;
   load_extra_funcs[index]=Monster_Create;
   message_funcs[index]=Monster_Message;
}

void Monster_Create(pobject cur_object, long extra_data_offset)
{
   pmonster_data new_data;               
   new_data=(pmonster_data)NewPtr(sizeof(monster_data));
 
   if (extra_data_offset==BAD_LOAD_OFFSET) {
      new_data->patrol_count=0;
      new_data->patrol=NULL;
   } else {                
      F_Seek(extra_data_offset);
      F_Get_Short(new_data->patrol_count);
      new_data->patrol=(pvector2)NewPtr(new_data->patrol_count * sizeof(vector2));
      for (short cur_point=0; cur_point<new_data->patrol_count; cur_point++) {
         F_Get_Long(new_data->patrol[cur_point].x);
         F_Get_Long(new_data->patrol[cur_point].y);
      } /* endfor */
   }

   new_data->cur_point=0;
   new_data->need_new_point=TRUE;
   new_data->cur_target=NULL;
   cur_object->extra_data=(pdata)new_data;
}

void Monster_Update(pobject cur_object, long update_num) {
   vector2 move_vec;
   pmonster_data obj_data=(pmonster_data)cur_object->extra_data;

   if (obj_data->cur_target!=NULL) {
      cur_object->angle=Get_Angle_Towards(obj_data->cur_target->x-cur_object->x,
                                                                obj_data->cur_target->y-cur_object->y);
      if (obj_data->time_to_bullet==0) {
         Create_Object(cur_object->x, cur_object->y, GUN_HEIGHT, 
            cur_object->angle, BULLET_TYPE, cur_object, cur_object->team);
         obj_data->time_to_bullet=GUN_SPEED;
      } else {
         obj_data->time_to_bullet--;
      }                          

      if ( (ABS(obj_data->cur_target->x-cur_object->x) > MIN_OBJ_DIS) ||
           (ABS(obj_data->cur_target->y-cur_object->y) > MIN_OBJ_DIS) ) {
         move_vec.x=cur_object->type->stats.base_speed*rcos_table[cur_object->angle];
         move_vec.y=cur_object->type->stats.base_speed*rsin_table[cur_object->angle];
         Move_Object_Vec(cur_object, &move_vec);
         cur_object->cur_frame=(update_num & ANIM_SPEED)>>ANIM_SHIFT;
      }

      if ((obj_data->time_to_bullet<4) || (obj_data->time_to_bullet>(GUN_SPEED-4)) ) {
         cur_object->cur_frame=4;
      }

      if (--obj_data->time_to_lose_interest==0) {
         Release_Object_Messages(obj_data->cur_target, cur_object);
         obj_data->cur_target=NULL;
      }
   } else {

      if (obj_data->patrol_count!=0) {
                          
      if (obj_data->need_new_point) {
         if ((++obj_data->cur_point)>=obj_data->patrol_count) {
            obj_data->cur_point=0;
         }
                                 
         cur_object->angle=Get_Angle_Towards(obj_data->patrol[obj_data->cur_point].x-
                cur_object->x, obj_data->patrol[obj_data->cur_point].y-cur_object->y);
         obj_data->need_new_point=FALSE;
         }

      move_vec.x=cur_object->type->stats.base_speed*rsin_table[cur_object->angle];
      move_vec.y=cur_object->type->stats.base_speed*rcos_table[cur_object->angle];
      
      if ((obj_data->patrol[obj_data->cur_point].x-cur_object->x)<=move_vec.x) {
         move_vec.x=obj_data->patrol[obj_data->cur_point].x-cur_object->x;
         move_vec.y=obj_data->patrol[obj_data->cur_point].y-cur_object->y;
         obj_data->need_new_point=TRUE;
      } /* endif */

      if (Move_Object_Vec(cur_object, &move_vec)) {
         obj_data->need_new_point=TRUE;
      }

      cur_object->cur_frame=(update_num & ANIM_SPEED)>>ANIM_SHIFT;

      }

      obj_data->cur_target=Check_For_Visible_Enemies(cur_object);
      if (obj_data->cur_target!=NULL) {
         obj_data->time_to_bullet=GUN_SPEED;
         obj_data->time_to_lose_interest=MAX_TIME_TO_LOSE_INTEREST;
         Request_Object_Messages(obj_data->cur_target, cur_object);
      }
   }
}

ULONG Monster_Message(pobject send_obj, pobject receive_obj, ULONG message, pdata extra_data) {
   pmonster_data obj_data=(pmonster_data)receive_obj->extra_data;

   switch (message) {
      case KILLED_MESSAGE:
         if (send_obj==(obj_data->cur_target))
            obj_data->cur_target=NULL;
         return NORMAL_MESSAGE;
      case HIT_OBJ:
      case HIT_BY_OBJ:
         if ((send_obj->type->obj_class==BULLET_CLASS)&&(send_obj->owner!=NULL)) {
            if (obj_data->cur_target!=NULL)
               Release_Object_Messages(obj_data->cur_target, receive_obj);
            Request_Object_Messages(send_obj->owner, receive_obj);
            obj_data->time_to_bullet=GUN_SPEED;
            obj_data->time_to_lose_interest=MAX_TIME_TO_LOSE_INTEREST;
            obj_data->cur_target=send_obj->owner;
            return NORMAL_MESSAGE;
         }
         break;
      default: 
         return Default_Message(send_obj, receive_obj, message, extra_data);
   } /* end switch */
return Default_Message(send_obj, receive_obj, message, extra_data);  
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -