?? player.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 + -