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

📄 player.cpp

📁 quake 游戏原代码
💻 CPP
字号:
#include "ray.h"
#include "globals.h"
#include "rayspr.h"
#include "rayfile.h"
#include "sprfunc.h"
#include "sfvars.h"
#include "defobj.h"
#include "playint.h"
#include "keyinfo.h"
#include "sprtypes.h"
#include "voxinter.h"
#include "message.h"
#include "classes.h"
#include "quit.h"
#include "inventor.h"
#include "tags.h"
#include "shot.h"

#define GUN_HEIGHT cur_obj->type->eye_height-20
#define MAX_TIME_TO_GUN 5
#define MAX_FALL_PER_UPDATE 8
#define NO_INPUT 0

short default_input[MAX_TRACKED_INPUTS]={0,0,0,0,0,0,0};
PSHORT cur_input_buffer=default_input;

typedef struct PLAYER_INFO * pplayer_info;
typedef struct PLAYER_INFO {
   PSHORT input_buffer;
   SHORT tracked_inputs[MAX_TRACKED_INPUTS];
   BOOL fly_mode;
   MYFIXED base_fixed_z, cur_fixed_z;
   angle_type z_move_angle;
   SHORT dis_to_fall;
   LONG time_to_gun;
   angle_type vert_angle;
   pobject_node inventory;
} player_info;

void Setup_Player_Inputs(pplayer_info cur_extra);
void Player_Update(pobject cur_obj, long update_num);
void Player_Update_Z(pobject cur_obj, psector new_sec);
void Player_Load(pobject cur_obj, long offset);
void Z_Correct_Move(pobject cur_obj);
void Reset_Player_Z(pplayer_info cur_extra);
pobject Scan_Inventory(pobject_node inventory, ULONG search_class);
ULONG Player_Message(pobject send_obj, pobject receive_obj, ULONG message, pdata extra_data);

void Init_Player_Obj(func_index index)
{
update_funcs[index]=Player_Update;
update_z_funcs[index]=Player_Update_Z;
load_extra_funcs[index]=Player_Load;
message_funcs[index]=Player_Message;
}

void Player_Load(pobject cur_obj, long offset)
{

   pplayer_info new_info;
   new_info=(pplayer_info)NewPtr(sizeof(player_info));

   for (short cur_input=0; cur_input < MAX_TRACKED_INPUTS; cur_input++) {
      new_info->tracked_inputs[cur_input]=0;
   }
   new_info->fly_mode=FALSE;
   new_info->base_fixed_z=cur_obj->z << SHIFT;
   new_info->cur_fixed_z=new_info->base_fixed_z;
   new_info->z_move_angle=ANGLE_0;
   new_info->dis_to_fall=0;
   new_info->input_buffer=cur_input_buffer;
   new_info->vert_angle=ANGLE_0;
   new_info->inventory=NULL;
   cur_obj->extra_data=new_info;
 
}

void Player_Update_Z(pobject cur_obj, psector new_sec)
{
   pplayer_info cur_extra=(pplayer_info)cur_obj->extra_data;
   short height_dif;

   if (!(new_sec->flags & VOXEL_SECTOR)) {
      height_dif=cur_obj->cur_sec->floor_height-new_sec->floor_height;
   } else {
      height_dif=cur_obj->cur_sec->floor_height-
        Get_Voxel_Alt((PUCHAR)new_sec->extra_data, cur_obj->x, cur_obj->y);
   }

   // if in fly mode, changing sectors has no effect on overall z, so we must alter
   // z for difference in floor height
   if (cur_extra->fly_mode) {
      cur_obj->z+=height_dif;
      cur_extra->base_fixed_z=cur_obj->z<<SHIFT;
      cur_extra->cur_fixed_z=cur_extra->base_fixed_z;
   } else {
      if (height_dif>0) {
         cur_obj->z+=height_dif;
         cur_extra->base_fixed_z+=(height_dif<<SHIFT);
         cur_extra->cur_fixed_z+=(height_dif<<SHIFT);
         cur_extra->dis_to_fall+=height_dif;
      } else {
         if (cur_extra->dis_to_fall>0) {
           cur_obj->z-=cur_extra->dis_to_fall;
           cur_extra->base_fixed_z-=(cur_extra->dis_to_fall << SHIFT);
           cur_extra->cur_fixed_z-=(cur_extra->dis_to_fall << SHIFT);
           cur_extra->dis_to_fall=0;
         }
      }
   } /* endif */
}

void Player_Update(pobject cur_obj, long update_num) {
     MYFIXED dx, dy;
     vector2 delta_vec;
     SHORT amount_up, amount_down, amount_left, amount_right, amount_look_up, 
        amount_look_down, raw_input, gun_shot;

     pplayer_info cur_extra=(pplayer_info)cur_obj->extra_data;
     Setup_Player_Inputs(cur_extra);     
     amount_up=cur_extra->tracked_inputs[INDEX_UP];
     amount_down=cur_extra->tracked_inputs[INDEX_DOWN];
     amount_left=cur_extra->tracked_inputs[INDEX_LEFT];
     amount_right=cur_extra->tracked_inputs[INDEX_RIGHT];
     amount_look_up=cur_extra->tracked_inputs[LOOK_UP];
     amount_look_down=cur_extra->tracked_inputs[LOOK_DOWN];
     gun_shot=cur_extra->tracked_inputs[INDEX_GUN];
     raw_input=cur_extra->tracked_inputs[RAW_INPUT];

     cur_extra->time_to_gun--;
     // do gravity for sector change
     if (cur_extra->dis_to_fall>0) {
        if (cur_extra->dis_to_fall>MAX_FALL_PER_UPDATE) {
           cur_extra->dis_to_fall-=MAX_FALL_PER_UPDATE;
           cur_obj->z-=MAX_FALL_PER_UPDATE;
           cur_extra->base_fixed_z-=(MAX_FALL_PER_UPDATE << SHIFT);
           cur_extra->cur_fixed_z-=(MAX_FALL_PER_UPDATE << SHIFT);
        } else {
           cur_obj->z-=cur_extra->dis_to_fall;
           cur_extra->base_fixed_z-=(cur_extra->dis_to_fall << SHIFT);
           cur_extra->cur_fixed_z-=(cur_extra->dis_to_fall << SHIFT);
           cur_extra->dis_to_fall=0;
        }
     }

        // reset deltas

        dx=dy=0;

        // what is user doing

        if (amount_right)
           {
           // rotate player right

           cur_obj->angle=Get_Angle_Difference(cur_obj->angle, amount_right);

           } // end if right
        else
        if (amount_left)
           {
           // rotate player to left

           cur_obj->angle=Get_Angle_Sum(cur_obj->angle, amount_left);

           } // end if left

        if (amount_up)
           {
           // move player along view vector foward

           dx=(rcos_table[cur_obj->angle] * amount_up);
           dy=(rsin_table[cur_obj->angle] * amount_up);

           if (cur_extra->fly_mode) {

              // move player z based on vertical view angle

              cur_extra->base_fixed_z+=(tan_table[cur_extra->vert_angle]*amount_up);
              cur_extra->cur_fixed_z=cur_extra->base_fixed_z;

              Z_Correct_Move(cur_obj);
           } else {

              if (cur_obj->cur_sec->flags & VOXEL_SECTOR) {
                 if (!cur_extra->fly_mode) {
                    Reset_Player_Z(cur_extra);
                 }
              } else {

                 // Adjust player z position along a sin wave to simulate walking motion

                 cur_extra->z_move_angle=Get_Angle_Sum(cur_extra->z_move_angle, Z_ANGLE_INC);     
                 cur_extra->cur_fixed_z=(cur_extra->base_fixed_z+(rsin_table[cur_extra->z_move_angle]*Z_MOVE_MAX));

              } /* endif */

           } /* endif */

           } // end if up
        else
        if (amount_down)
           {
           // move player along view vector backward

            dx=(-rcos_table[cur_obj->angle]* amount_down);
            dy=(-rsin_table[cur_obj->angle] * amount_down);

            if (cur_extra->fly_mode) {

               // Move player z base on his vertical view angle

               cur_extra->base_fixed_z-=(tan_table[cur_extra->vert_angle]* amount_down);
               cur_extra->cur_fixed_z=cur_extra->base_fixed_z;

               Z_Correct_Move(cur_obj);
            } else {

              if (cur_obj->cur_sec->flags & VOXEL_SECTOR) {
                 if (!cur_extra->fly_mode) {
                    Reset_Player_Z(cur_extra);
                 }
              } else {

                 // Adjust player z position along a sin wave to simulate walking motion

                 cur_extra->z_move_angle=Get_Angle_Difference(cur_extra->z_move_angle, Z_ANGLE_INC);     
                 cur_extra->cur_fixed_z=(cur_extra->base_fixed_z+(rsin_table[cur_extra->z_move_angle]*Z_MOVE_MAX));

              } /* endif */

            } /* endif */

           } // end if down
       else
          {
             if (!cur_extra->fly_mode) {
                Reset_Player_Z(cur_extra);
             }
          }

        if (gun_shot) {
           if (cur_extra->time_to_gun<=0) {
           Create_Object(cur_obj->x, cur_obj->y, GUN_HEIGHT+cur_obj->z, cur_obj->angle, BULLET_TYPE, cur_obj, cur_obj->team);
           cur_extra->time_to_gun=MAX_TIME_TO_GUN;
           }
        }

        // move player
        delta_vec.x=dx;
        delta_vec.y=dy;
        Move_Object_Vec(cur_obj, &delta_vec);

        // check change in vertical angle
        cur_extra->vert_angle=Get_Angle_Sum(cur_extra->vert_angle, amount_look_up);
        cur_extra->vert_angle=Get_Angle_Difference(cur_extra->vert_angle, amount_look_down);

        switch (raw_input) {
        case U_KEY:
           cur_extra->base_fixed_z+=ONE;
           cur_extra->cur_fixed_z+=ONE;
           Z_Correct_Move(cur_obj);
           break;
        case D_KEY:
           cur_extra->base_fixed_z-=ONE;
           cur_extra->cur_fixed_z-=ONE;
           Z_Correct_Move(cur_obj);
           break;
        case F_KEY:
           cur_extra->fly_mode=(cur_extra->fly_mode == TRUE ? FALSE : TRUE);
           cur_extra->z_move_angle=ANGLE_0;
           cur_extra->cur_fixed_z=cur_extra->base_fixed_z;
           break;
        default: 
           break;
        }
        
        // test non-motion keys

if ( (cur_obj->cur_sec->tag == (HOME_SECTOR+cur_obj->team)) && 
      (Scan_Inventory(cur_extra->inventory, FLAG_CLASS)!=NULL) ) {
         Post_Quit(WINNING_GAME);

}

cur_obj->z=cur_extra->cur_fixed_z>>SHIFT;
}

void Reset_Player_Z(pplayer_info cur_extra)
{
   // reset player z if they aren't moving
   if ((cur_extra->z_move_angle % ANGLE_180) >= Z_ANGLE_DELTA) {

      if (cur_extra->z_move_angle % ANGLE_180 < ANGLE_90) {

         cur_extra->z_move_angle=
            Get_Angle_Difference(cur_extra->z_move_angle, Z_ANGLE_INC);

      } else {

         cur_extra->z_move_angle=
            Get_Angle_Sum(cur_extra->z_move_angle, Z_ANGLE_INC);

      } /* endif */

      cur_extra->cur_fixed_z=(cur_extra->base_fixed_z+
         (rsin_table[cur_extra->z_move_angle]*Z_MOVE_MAX));

   } /* endif */
}

void Z_Correct_Move(pobject cur_obj)
{
  pplayer_info cur_extra=(pplayer_info)cur_obj->extra_data;
  if (cur_extra->base_fixed_z < (STEP_LENGTH<<SHIFT) ) {
    cur_extra->base_fixed_z=STEP_LENGTH<<SHIFT;
    cur_extra->cur_fixed_z=cur_extra->base_fixed_z;
    }
  long sec_height=cur_obj->cur_sec->ceil_height-cur_obj->cur_sec->floor_height;
  MYFIXED max_height=(sec_height-STEP_LENGTH)<<SHIFT;
  if (cur_extra->base_fixed_z > max_height) {
     cur_extra->base_fixed_z=max_height;
     cur_extra->cur_fixed_z=cur_extra->base_fixed_z;
  }
}

void Setup_Player_Inputs(pplayer_info cur_extra)
{
memcpy(cur_extra->tracked_inputs, cur_extra->input_buffer, MAX_TRACKED_INPUTS * sizeof(short));
}

void Set_Player_Input_Buffer(PSHORT input_buffer)
{
  cur_input_buffer=input_buffer;
}

angle_type Get_Player_Vert_Angle(pobject cur_obj)
{
   return ((pplayer_info)cur_obj->extra_data)->vert_angle;
}

BOOL Is_Flying(pobject test_obj) {
   return ((pplayer_info)test_obj->extra_data)->fly_mode;
}

ULONG Player_Message(pobject send_obj, pobject receive_obj, ULONG message, pdata extra_data) {

   pplayer_info player_data=(pplayer_info)receive_obj->extra_data;

   switch (message) {
   case HIT_OBJ:
   case HIT_BY_OBJ:
         if ((send_obj->type->obj_class==FLAG_CLASS)&&(send_obj->team!=receive_obj->team)) {
            pobject_node new_node=(pobject_node)NewPtr(sizeof(object_node));
            new_node->data=send_obj;
            new_node->back=NULL;
            new_node->front=NULL;
            OL_Push_Node(new_node, player_data->inventory);
            Create_Inventory_Object(send_obj, receive_obj);
            Do_Shot("flag.pcx", "groovy.wav", 20, TRUE);
         }
         break;
   default: 
      break;
   } /* endswitch */
   return Default_Message(send_obj, receive_obj, message, extra_data);
}

pobject Scan_Inventory(pobject_node inventory, ULONG search_class) {
   pobject_node cur_node;
   cur_node=inventory;
   while (!OL_Empty_Node(cur_node)) {
      if ( ((pinventory_data)cur_node->data->extra_data)->old_type->obj_class==search_class) {
         return cur_node->data;
      }
      cur_node=OL_Next_Node(cur_node);
   }
   return NULL;
}

⌨️ 快捷键说明

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