1425 lines
28 KiB
C++
1425 lines
28 KiB
C++
|
// Darci.cpp
|
||
|
// Guy Simmons, 4th January 1998
|
||
|
|
||
|
#include "Game.h"
|
||
|
#include "Darci.h"
|
||
|
#include "animate.h"
|
||
|
#include "combat.h"
|
||
|
#include "id.h"
|
||
|
//#include "c:\fallen\editor\headers\collide.hpp"
|
||
|
//#include "c:\fallen\editor\headers\map.h"
|
||
|
#include "statedef.h"
|
||
|
#include "enter.h"
|
||
|
#include "pap.h"
|
||
|
#include "supermap.h"
|
||
|
#include "ns.h"
|
||
|
#include "pcom.h"
|
||
|
#include "walkable.h"
|
||
|
#include "memory.h"
|
||
|
#include "sound.h"
|
||
|
#include "mav.h"
|
||
|
|
||
|
#ifdef TARGET_DC
|
||
|
#include "DIManager.h"
|
||
|
#endif
|
||
|
|
||
|
//---------------------------------------------------------------
|
||
|
// This is all temporary editor reliant stuff.
|
||
|
|
||
|
|
||
|
//#include "..\Editor\Headers\Thing.h"
|
||
|
//#include "..\Editor\Headers\engine.h"
|
||
|
|
||
|
//#include "c:\fallen\editor\headers\prim_draw.h"
|
||
|
/*
|
||
|
struct SVector
|
||
|
{
|
||
|
SLONG X,Y,Z;
|
||
|
};
|
||
|
*/
|
||
|
|
||
|
SLONG calc_height_at(SLONG x,SLONG z);
|
||
|
|
||
|
void fn_darci_init(Thing *t_thing);
|
||
|
|
||
|
#define GRAVITY ((4<<8))
|
||
|
|
||
|
//extern SLONG calc_height_on_face(SLONG x,SLONG z,SLONG face);
|
||
|
extern SLONG set_person_kick_off_wall(Thing *p_person,SLONG col,SLONG set_pos);
|
||
|
extern void add_damage_value_thing(Thing *p_thing,SLONG value);
|
||
|
extern void locked_anim_change(Thing *p_person,UWORD locked_object,UWORD anim,SLONG dangle=0);
|
||
|
|
||
|
|
||
|
/*
|
||
|
Tables we need
|
||
|
|
||
|
for each person id a chunk address
|
||
|
|
||
|
for each person, for each move a frame pointer or 0 if move not supported
|
||
|
|
||
|
Darci
|
||
|
Roper
|
||
|
Cop
|
||
|
|
||
|
Soldier
|
||
|
Rasters
|
||
|
triads
|
||
|
Mafia
|
||
|
Dockers
|
||
|
Unknown
|
||
|
Tramp
|
||
|
Fat Bloke Inside Buildings
|
||
|
Child
|
||
|
|
||
|
|
||
|
1. a table to find the anim number for a particular person
|
||
|
i.e ANIM_HIT1 is an index into anim_array but each
|
||
|
|
||
|
|
||
|
*/
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------
|
||
|
extern void fn_person_moveing(Thing *p_person);
|
||
|
extern void fn_person_idle(Thing *p_person);
|
||
|
|
||
|
StateFunction darci_states[] =
|
||
|
{
|
||
|
{ STATE_INIT, fn_darci_init },
|
||
|
{ STATE_NORMAL, NULL },
|
||
|
{ STATE_HIT, NULL },
|
||
|
{ STATE_ABOUT_TO_REMOVE, NULL },
|
||
|
{ STATE_REMOVE_ME, NULL },
|
||
|
{ STATE_MOVEING, fn_person_moveing},
|
||
|
{ STATE_IDLE, fn_person_idle }
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------
|
||
|
|
||
|
void fn_darci_init(Thing *t_thing)
|
||
|
{
|
||
|
|
||
|
//
|
||
|
// Angle set already when the person was created.
|
||
|
// OnFace set when person created too.
|
||
|
//
|
||
|
|
||
|
t_thing->DrawType = DT_ROT_MULTI;
|
||
|
t_thing->Draw.Tweened->Roll = 0;
|
||
|
t_thing->Draw.Tweened->Tilt = 0;
|
||
|
t_thing->Draw.Tweened->AnimTween = 0;
|
||
|
t_thing->Draw.Tweened->TweenStage = 0;
|
||
|
t_thing->Draw.Tweened->NextFrame = NULL;
|
||
|
t_thing->Draw.Tweened->QueuedFrame = NULL;
|
||
|
t_thing->Draw.Tweened->TheChunk = &game_chunk[0];
|
||
|
t_thing->Draw.Tweened->FrameIndex = 0;
|
||
|
t_thing->Draw.Tweened->Flags = FLAGS_DRAW_SHADOW;
|
||
|
// t_thing->Genus.Person->Health = 200;
|
||
|
|
||
|
set_anim(t_thing,ANIM_STAND_READY);
|
||
|
set_person_idle(t_thing);
|
||
|
add_thing_to_map(t_thing);
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------
|
||
|
void matrix_transformZMY(Matrix31* result, Matrix33* trans, Matrix31* mat2);
|
||
|
|
||
|
|
||
|
KeyFrame* advance_keyframe(KeyFrame *frame,SLONG count)
|
||
|
{
|
||
|
LogText(" advance to frame %d \n",count);
|
||
|
// return(frame);
|
||
|
while(count&&frame->NextFrame)
|
||
|
{
|
||
|
frame=frame->NextFrame;
|
||
|
count--;
|
||
|
}
|
||
|
return(frame);
|
||
|
}
|
||
|
|
||
|
#define DIR_FORWARD (1<<0)
|
||
|
#define DIR_BACKWARD (1<<1)
|
||
|
#define DIR_LEFT (1<<2)
|
||
|
#define DIR_RIGHT (1<<3)
|
||
|
|
||
|
|
||
|
ULONG move_thing(SLONG m_dx,SLONG m_dy,SLONG m_dz,struct MapThing *p_thing);
|
||
|
static SLONG air_walking=0;
|
||
|
|
||
|
static THING_INDEX history_thing[100];
|
||
|
static SWORD history=0;
|
||
|
|
||
|
|
||
|
SLONG do_floor_collide(Thing *p_thing,SWORD pelvis,SLONG *new_y,SLONG *foot_y,SLONG max_range)
|
||
|
{
|
||
|
SLONG x,y,z;
|
||
|
SLONG floor_y;
|
||
|
|
||
|
calc_sub_objects_position(p_thing,p_thing->Draw.Tweened->AnimTween,pelvis?0:3,&x,&y,&z);
|
||
|
*foot_y=y;
|
||
|
|
||
|
//
|
||
|
// So the feet don't poke through walls.
|
||
|
//
|
||
|
|
||
|
x >>= 2;
|
||
|
z >>= 2;
|
||
|
|
||
|
x+=(p_thing->WorldPos.X)>>8;
|
||
|
y+=(p_thing->WorldPos.Y)>>8;
|
||
|
z+=(p_thing->WorldPos.Z)>>8;
|
||
|
#if !defined(PSX) && !defined(TARGET_DC)
|
||
|
if (p_thing->Flags & FLAGS_IN_SEWERS)
|
||
|
{
|
||
|
floor_y = NS_calc_height_at(x,z);
|
||
|
}
|
||
|
else
|
||
|
#endif
|
||
|
{
|
||
|
floor_y = PAP_calc_height_at_thing(p_thing,x,z);
|
||
|
}
|
||
|
*new_y=floor_y;
|
||
|
|
||
|
if(y<=(floor_y+9) && (floor_y-y)<max_range)
|
||
|
{
|
||
|
MSG_add(" feet collide y %d floory %d\n",y,floor_y);
|
||
|
return(1);
|
||
|
}
|
||
|
else
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
SLONG predict_collision_with_floor(Thing *p_thing,SWORD pelvis,SLONG *new_y,SLONG *foot_y)
|
||
|
{
|
||
|
SLONG ret;
|
||
|
GameCoord temp_pos;
|
||
|
SLONG temp_velocity,temp_dy;
|
||
|
SLONG c0;
|
||
|
SLONG dx,dy,dz;
|
||
|
|
||
|
// MSG_add(" START COLLIDE dy %d posy %d ",p_thing->DY,p_thing->WorldPos.Y);
|
||
|
|
||
|
|
||
|
temp_pos=p_thing->WorldPos;
|
||
|
temp_velocity=p_thing->Velocity;
|
||
|
temp_dy=p_thing->DY;
|
||
|
ret=do_floor_collide(p_thing,pelvis,new_y,foot_y,10000);
|
||
|
if(ret)
|
||
|
return(ret);
|
||
|
|
||
|
// for(c0=0;c0<3;c0++)
|
||
|
// if(0)
|
||
|
{
|
||
|
SLONG dx,dy,dz;
|
||
|
dx = (SIN(p_thing->Draw.Tweened->Angle)*p_thing->Velocity)>>8; //was 16
|
||
|
dz = (COS(p_thing->Draw.Tweened->Angle)*p_thing->Velocity)>>8;
|
||
|
dy = p_thing->DY;
|
||
|
|
||
|
dx = (dx*TICK_RATIO)>>(TICK_SHIFT);
|
||
|
dy = (dy*TICK_RATIO)>>(TICK_SHIFT);
|
||
|
dz = (dz*TICK_RATIO)>>(TICK_SHIFT);
|
||
|
|
||
|
p_thing->Velocity+=p_thing->DeltaVelocity;
|
||
|
p_thing->DY-=(GRAVITY*TICK_RATIO)>>TICK_SHIFT; //gravity
|
||
|
if(p_thing->DY<-30000)
|
||
|
p_thing->DY=-30000;
|
||
|
|
||
|
// MSG_add(" dxyz %d %d %d \n",dx,dy,dz);
|
||
|
|
||
|
p_thing->WorldPos.X -= dx; //(SIN(p_thing->Draw.Tweened->Angle)*p_thing->Velocity)>>16;
|
||
|
p_thing->WorldPos.Z -= dz; //(COS(p_thing->Draw.Tweened->Angle)*p_thing->Velocity)>>16;
|
||
|
p_thing->WorldPos.Y += dy; //p_thing->DY;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
// if(MAV_HEIGHT(temp_pos.WorldPos.X>>16,temp_pos.WorldPos.Z>>16
|
||
|
ret=do_floor_collide(p_thing,pelvis,new_y,foot_y,128);
|
||
|
|
||
|
p_thing->Velocity=temp_velocity;
|
||
|
p_thing->DY=temp_dy;
|
||
|
p_thing->WorldPos=temp_pos;
|
||
|
return(ret);
|
||
|
}
|
||
|
|
||
|
extern SLONG find_face_near_y(MAPCO16 x,MAPCO16 y,MAPCO16 z, SLONG ignore_faces_of_this_building,Thing *p_person,SLONG neg_dy,SLONG pos_dy,SLONG *ret_y);
|
||
|
extern SLONG nearest_point_on_line_and_dist( SLONG x1, SLONG z1, SLONG x2, SLONG z2, SLONG a, SLONG b,SLONG *ret_x,SLONG *ret_z);
|
||
|
|
||
|
SLONG predict_collision_with_face(Thing *p_thing,SLONG wx,SLONG wy,SLONG wz,SWORD pelvis,SLONG *new_y,SLONG *foot_y)
|
||
|
{
|
||
|
SLONG ret;
|
||
|
GameCoord temp_pos;
|
||
|
SLONG temp_velocity,temp_dy;
|
||
|
SLONG c0;
|
||
|
|
||
|
SLONG dx,dy,dz,fx,fy,fz;
|
||
|
|
||
|
SLONG ignore_building;
|
||
|
if(p_thing->DY>0)
|
||
|
return(0);
|
||
|
|
||
|
//
|
||
|
// The thing index whose faces we ignore.
|
||
|
//
|
||
|
|
||
|
if (p_thing->Flags & FLAGS_IN_BUILDING)
|
||
|
{
|
||
|
ignore_building = INDOORS_DBUILDING;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ignore_building = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
calc_sub_objects_position(
|
||
|
p_thing,
|
||
|
255, //p_thing->Draw.Tweened->AnimTween,
|
||
|
pelvis?0:SUB_OBJECT_LEFT_FOOT,
|
||
|
&fx,
|
||
|
&fy,
|
||
|
&fz);
|
||
|
|
||
|
if(!pelvis)
|
||
|
{
|
||
|
//
|
||
|
// Get rid of the (x,z) offset of the foot. This fixes the bug where
|
||
|
// Darci falls through the ground if she is jumping and sliding against
|
||
|
// a wall. (Her foot was poking through the wall in front of her.)
|
||
|
//
|
||
|
|
||
|
fx = 0; // maybe shifting by 2 will be even better
|
||
|
fz = 0; // Remember to change the corresponding code in plant_feet()
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
*foot_y=fy;
|
||
|
//
|
||
|
// you can overshoot by your velocity or be 5 short of landing on it
|
||
|
//
|
||
|
|
||
|
//ret=find_face_near_y(wx+fx,wy+fy,wz+fz, ignore_building,p_thing,-(abs(p_thing->DY>>8)),5);
|
||
|
{
|
||
|
SLONG min_y,max_y;
|
||
|
max_y=abs(p_thing->DY>>9);
|
||
|
min_y=-max_y;
|
||
|
if(max_y<5)
|
||
|
max_y=5;
|
||
|
if(min_y>-100)
|
||
|
min_y=-100;
|
||
|
|
||
|
MSG_add(" vel>>1 %d min_y %d max-y %d \n",abs(p_thing->DY>>9),min_y,max_y);
|
||
|
|
||
|
|
||
|
ret=find_face_near_y(wx+fx,wy+fy,wz+fz, ignore_building,p_thing,min_y,max_y,new_y);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
if(ret==GRAB_FLOOR)
|
||
|
ret=0;
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// set person pos to be on face
|
||
|
//
|
||
|
|
||
|
|
||
|
}
|
||
|
/*
|
||
|
if(ret)
|
||
|
{
|
||
|
CBYTE str[100];
|
||
|
sprintf(str," FOUND face at %d y %d \n",ret,(*new_y));
|
||
|
CONSOLE_text(str);
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
// if(ret)
|
||
|
// break;
|
||
|
|
||
|
|
||
|
return(ret);
|
||
|
}
|
||
|
|
||
|
SLONG col_is_fence(SLONG col)
|
||
|
{
|
||
|
/*
|
||
|
SLONG face;
|
||
|
|
||
|
face=col_vects[col].Face;
|
||
|
if(face>0)
|
||
|
{
|
||
|
if(prim_faces4[face].Type==FACE_TYPE_FENCE)
|
||
|
return(1);
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
// if(col_vects[col].PrimType==STOREY_TYPE_FENCE || col_vects[col].PrimType==STOREY_TYPE_FENCE_FLAT)
|
||
|
// if(dfacets[col].FacetType==STOREY_TYPE_FENCE || dfacets[col].FacetType==STOREY_TYPE_FENCE_FLAT)
|
||
|
if(dfacets[col].FacetType==STOREY_TYPE_FENCE || dfacets[col].FacetType==STOREY_TYPE_FENCE_FLAT || dfacets[col].FacetType==STOREY_TYPE_FENCE_BRICK)
|
||
|
{
|
||
|
// MSG_add(" col vect %d is fence \n",col);
|
||
|
return(1);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
inline BOOL MagicFrameCheck(Thing *p_person, UBYTE frameindex) {
|
||
|
if (p_person->Draw.Tweened->FrameIndex>=frameindex) {
|
||
|
if (!(p_person->Genus.Person->Flags2&FLAG2_SYNC_SOUNDFX)) {
|
||
|
p_person->Genus.Person->Flags2|=FLAG2_SYNC_SOUNDFX;
|
||
|
return TRUE;
|
||
|
}
|
||
|
} else {
|
||
|
p_person->Genus.Person->Flags2&=~FLAG2_SYNC_SOUNDFX;
|
||
|
}
|
||
|
return FALSE;
|
||
|
|
||
|
}
|
||
|
|
||
|
void set_person_in_building_through_roof(Thing *p_person,SLONG face)
|
||
|
{
|
||
|
SLONG building,storey,wall,best_storey=0;
|
||
|
#ifdef POO
|
||
|
wall=prim_faces4[face].ThingIndex;
|
||
|
if(wall<0)
|
||
|
{
|
||
|
}
|
||
|
else
|
||
|
return;
|
||
|
|
||
|
storey=wall_list[-wall].StoreyHead;
|
||
|
while(storey_list[storey].Prev)
|
||
|
{
|
||
|
storey=storey_list[storey].Prev;
|
||
|
if(storey_list[storey].StoreyType==STOREY_TYPE_NORMAL)
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(storey_list[storey].StoreyType==STOREY_TYPE_NORMAL)
|
||
|
{
|
||
|
building=storey_list[storey].BuildingHead;
|
||
|
|
||
|
/*
|
||
|
storey=ENTER_get_ground_floor(building);
|
||
|
if(storey)
|
||
|
{
|
||
|
p_person->WorldPos.Y-=200<<8;
|
||
|
|
||
|
if (ENTER_setup(building, storey, TRUE))
|
||
|
{
|
||
|
p_person->Flags |= FLAGS_IN_BUILDING;
|
||
|
GAME_FLAGS |= GF_INDOORS;
|
||
|
|
||
|
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*/
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
SLONG damage_person_on_land(Thing *p_thing)
|
||
|
{
|
||
|
SLONG sound;
|
||
|
SLONG damage;
|
||
|
|
||
|
StopScreamFallSound(p_thing); // just in case
|
||
|
|
||
|
//
|
||
|
// When Darci lands she makes a sound depending on how
|
||
|
// hard she hit the ground.
|
||
|
//
|
||
|
|
||
|
if (p_thing->DY < -20000) {sound = PCOM_SOUND_DROP_BIG;}
|
||
|
else if (p_thing->DY < -10000) {sound = PCOM_SOUND_DROP_MED;}
|
||
|
else if (p_thing->DY < -5000) {sound = PCOM_SOUND_DROP;}
|
||
|
else {sound = NULL;}
|
||
|
|
||
|
if (sound)
|
||
|
{
|
||
|
PCOM_oscillate_tympanum(
|
||
|
sound,
|
||
|
p_thing,
|
||
|
p_thing->WorldPos.X >> 8,
|
||
|
p_thing->WorldPos.Y >> 8,
|
||
|
p_thing->WorldPos.Z >> 8);
|
||
|
|
||
|
//
|
||
|
// Actually do the sound...
|
||
|
//
|
||
|
|
||
|
// <GRUNT GRUNT GRUNT> :)
|
||
|
}
|
||
|
|
||
|
if (p_thing->Genus.Person->pcom_bent & PCOM_BENT_PLAYERKILL)
|
||
|
{
|
||
|
//
|
||
|
// Only the player can hurt this person.
|
||
|
//
|
||
|
}
|
||
|
else
|
||
|
if (p_thing->Genus.Person->Flags2 & FLAG2_PERSON_INVULNERABLE)
|
||
|
{
|
||
|
//
|
||
|
// Nothing hurts this person!
|
||
|
//
|
||
|
}
|
||
|
else
|
||
|
if (p_thing->Genus.Person->pcom_ai_state==PCOM_AI_STATE_FOLLOWING)
|
||
|
{
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (p_thing->DY <= -30000)
|
||
|
{
|
||
|
damage = 250; // Kill the person
|
||
|
StopScreamFallSound(p_thing);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
damage = -p_thing->DY - 20000;
|
||
|
|
||
|
if (damage < 0)
|
||
|
{
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
damage = damage / 100;
|
||
|
PainSound(p_thing);
|
||
|
}
|
||
|
|
||
|
p_thing->Genus.Person->Health -= damage;
|
||
|
#ifdef PSX
|
||
|
if (p_thing->Genus.Person->PlayerID)
|
||
|
{
|
||
|
PSX_SetShock(0,damage+48);
|
||
|
}
|
||
|
#endif
|
||
|
#ifdef TARGET_DC
|
||
|
if (p_thing->Genus.Person->PlayerID)
|
||
|
{
|
||
|
Vibrate ( 5, (float)(damage+48) * 0.01f, 0.0f );
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
// add_damage_value_thing(p_thing,damage>>1);
|
||
|
|
||
|
if (p_thing->Genus.Person->Health <= 0)
|
||
|
{
|
||
|
//
|
||
|
// sets us up in the right spot to change anim to dead
|
||
|
//
|
||
|
|
||
|
//void locked_anim_change(Thing *p_person,UWORD locked_object,UWORD anim);
|
||
|
|
||
|
//locked_anim_change(p_thing,SUB_OBJECT_LEFT_FOOT,ANIM_STAND_READY);
|
||
|
|
||
|
set_person_dead(
|
||
|
p_thing,
|
||
|
NULL,
|
||
|
PERSON_DEATH_TYPE_LAND,
|
||
|
FALSE,
|
||
|
0);
|
||
|
|
||
|
return(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(0);
|
||
|
}
|
||
|
|
||
|
|
||
|
extern SLONG actual_sliding;
|
||
|
extern SLONG last_slide_dist;
|
||
|
|
||
|
UBYTE just_started_falling_off_backwards;
|
||
|
|
||
|
SLONG projectile_move_thing(Thing *p_thing,SLONG flag)
|
||
|
{
|
||
|
GameCoord new_position;
|
||
|
DrawTween *draw_info;
|
||
|
SLONG face;
|
||
|
SLONG ret=0;
|
||
|
SLONG col=0;
|
||
|
|
||
|
SLONG dx,dy,dz;
|
||
|
|
||
|
LogText(" projectile\n");
|
||
|
|
||
|
draw_info = p_thing->Draw.Tweened;
|
||
|
new_position = p_thing->WorldPos;
|
||
|
|
||
|
dx = (SIN(p_thing->Draw.Tweened->Angle)*p_thing->Velocity)>>8;
|
||
|
dz = (COS(p_thing->Draw.Tweened->Angle)*p_thing->Velocity)>>8; //fixed 8
|
||
|
dy = p_thing->DY;
|
||
|
|
||
|
dx = (dx*TICK_RATIO)>>TICK_SHIFT;
|
||
|
dy = (dy*TICK_RATIO)>>TICK_SHIFT;
|
||
|
dz = (dz*TICK_RATIO)>>TICK_SHIFT;
|
||
|
|
||
|
|
||
|
if(p_thing->Genus.Person->Ware)
|
||
|
{
|
||
|
SLONG px,py,pz,wy;
|
||
|
//
|
||
|
// slide along warehouse roof
|
||
|
//
|
||
|
|
||
|
calc_sub_objects_position(p_thing,p_thing->Draw.Tweened->AnimTween,SUB_OBJECT_HEAD,&px,&py,&pz);
|
||
|
px+=(dx+p_thing->WorldPos.X)>>8;
|
||
|
py+=(dy+p_thing->WorldPos.Y)>>8;
|
||
|
pz+=(dz+p_thing->WorldPos.Z)>>8;
|
||
|
|
||
|
wy=MAVHEIGHT(px>>8,pz>>8)<<6;
|
||
|
if((py)+80 > wy)
|
||
|
dy-=((py)+80 - wy)<<8;
|
||
|
|
||
|
}
|
||
|
|
||
|
ASSERT(p_thing->Class == CLASS_PERSON);
|
||
|
|
||
|
p_thing->Genus.Person->SlideOdd = 0;
|
||
|
|
||
|
if (flag & (1|8)) // check for walls
|
||
|
{
|
||
|
SLONG x1,x2,y1,y2,z1,z2;
|
||
|
{
|
||
|
{
|
||
|
//
|
||
|
// Work out the position of the pelvis.
|
||
|
//
|
||
|
|
||
|
calc_sub_objects_position(p_thing,p_thing->Draw.Tweened->AnimTween,0,&x1,&y1,&z1);
|
||
|
|
||
|
x1 <<= 8;
|
||
|
y1 <<= 8;
|
||
|
z1 <<= 8;
|
||
|
|
||
|
x1 += p_thing->WorldPos.X;
|
||
|
y1 += p_thing->WorldPos.Y;
|
||
|
z1 += p_thing->WorldPos.Z;
|
||
|
|
||
|
//
|
||
|
// The end of our movement vector.
|
||
|
//
|
||
|
|
||
|
x2 = x1 - dx;
|
||
|
y2 = y1 + dy;
|
||
|
z2 = z1 - dz;
|
||
|
|
||
|
if(x2<0||(x2>>16)>127 || z2<0 || (z2>>16)>127)
|
||
|
return(0);
|
||
|
|
||
|
#if !defined(PSX) && !defined(TARGET_DC)
|
||
|
if (p_thing->Flags & FLAGS_IN_SEWERS)
|
||
|
{
|
||
|
//
|
||
|
// Slide along the walls of the sewer as you jump.
|
||
|
//
|
||
|
|
||
|
NS_slide_along(x1,y1,z1,&x2,&y2,&z2,50);
|
||
|
|
||
|
//
|
||
|
// Pretend you never collide.
|
||
|
//
|
||
|
|
||
|
col = 0; // This means we can't do any funcky kicks or anything
|
||
|
// in the sewers :o(
|
||
|
}
|
||
|
else
|
||
|
#endif
|
||
|
{
|
||
|
if (!(flag & 8))
|
||
|
{
|
||
|
//
|
||
|
// Collide with things.
|
||
|
//
|
||
|
|
||
|
collide_against_things(
|
||
|
p_thing,
|
||
|
50,
|
||
|
x1, y1, z1,
|
||
|
&x2, &y2, &z2);
|
||
|
|
||
|
if (p_thing->State == STATE_DYING)
|
||
|
{
|
||
|
//
|
||
|
// Darci died while colliding with things.
|
||
|
//
|
||
|
|
||
|
return 100;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Collision with OB_jects.
|
||
|
//
|
||
|
|
||
|
collide_against_objects(
|
||
|
p_thing,
|
||
|
30,
|
||
|
x1, y1, z1,
|
||
|
&x2, &y2, &z2);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Collision with walls.
|
||
|
//
|
||
|
#ifndef PSX
|
||
|
if (p_thing->Genus.Person->InsideIndex)
|
||
|
{
|
||
|
person_slide_inside(
|
||
|
p_thing->Genus.Person->InsideIndex,
|
||
|
x1, y1, z1,
|
||
|
&x2,
|
||
|
&y2,
|
||
|
&z2);
|
||
|
}
|
||
|
else
|
||
|
#endif
|
||
|
{
|
||
|
SLONG extra_wall_height = 0;
|
||
|
|
||
|
extra_wall_height = 0; //-p_thing->DY << 3;
|
||
|
|
||
|
SATURATE(extra_wall_height, 0, 128);
|
||
|
|
||
|
MSG_add(" extra wall height %d y1 %d y2 %d\n",extra_wall_height,y1,y2);
|
||
|
|
||
|
if (flag & 8)
|
||
|
{
|
||
|
just_started_falling_off_backwards = TRUE;
|
||
|
|
||
|
}
|
||
|
|
||
|
slide_along(
|
||
|
x1,y1,z1,
|
||
|
&x2,&y2,&z2,
|
||
|
extra_wall_height, // Stop Darci going through walls- the extra height added to a wall height.
|
||
|
50,SLIDE_ALONG_FLAG_JUMPING);
|
||
|
|
||
|
just_started_falling_off_backwards = FALSE;
|
||
|
|
||
|
//
|
||
|
// This next bit of code is probably redundant as we can no longer jump through doors, but It cant do any harm to leave it in (apart from code bloat)
|
||
|
//
|
||
|
extern SLONG slide_into_warehouse;
|
||
|
extern SLONG slide_outof_warehouse;
|
||
|
|
||
|
if (slide_into_warehouse)
|
||
|
{
|
||
|
p_thing->Genus.Person->Flags |= FLAG_PERSON_WAREHOUSE;
|
||
|
p_thing->Genus.Person->Ware = dbuildings[slide_into_warehouse].Ware;
|
||
|
}
|
||
|
|
||
|
if (slide_outof_warehouse)
|
||
|
{
|
||
|
p_thing->Genus.Person->Flags &= ~FLAG_PERSON_WAREHOUSE;
|
||
|
p_thing->Genus.Person->Ware = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// The collision vector we sliding over.
|
||
|
//
|
||
|
|
||
|
if(actual_sliding)
|
||
|
{
|
||
|
col = last_slide_colvect;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
col = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
dx = -(x2-x1);
|
||
|
dz = -(z2-z1);
|
||
|
}
|
||
|
|
||
|
if(col)
|
||
|
{
|
||
|
#if 0
|
||
|
|
||
|
//
|
||
|
// I hope we get this working one day...
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// Do special moves off a wall.
|
||
|
//
|
||
|
|
||
|
if ((p_thing->Genus.Person->Flags & FLAG_PERSON_REQUEST_KICK))
|
||
|
{
|
||
|
if(set_person_kick_off_wall(p_thing,col,1))
|
||
|
{
|
||
|
return(2);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
if((p_thing->Genus.Person->Flags&FLAG_PERSON_REQUEST_JUMP))
|
||
|
{
|
||
|
if(set_person_kick_off_wall(p_thing,col,1))
|
||
|
{
|
||
|
return(2);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
|
||
|
#endif
|
||
|
if(col_is_fence(col) || dfacets[col].FacetType == STOREY_TYPE_NORMAL)
|
||
|
{
|
||
|
//
|
||
|
// The person has hit a fence.
|
||
|
//
|
||
|
|
||
|
if (dfacets[col].FacetFlags & FACET_FLAG_UNCLIMBABLE)
|
||
|
{
|
||
|
//
|
||
|
// You can't land on this fence- so we'll just slide
|
||
|
// along it instead.
|
||
|
//
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
if(set_person_land_on_fence(p_thing,col,1))
|
||
|
{
|
||
|
return(2);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(col)
|
||
|
{
|
||
|
MSG_add(" HIT wall !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
new_position.X -= dx;
|
||
|
new_position.Z -= dz;
|
||
|
new_position.Y += dy;
|
||
|
|
||
|
if(new_position.X<0||(new_position.X>>16)>127 || new_position.Z<0 || (new_position.Z>>16)>127)
|
||
|
return(0);
|
||
|
|
||
|
SATURATE(new_position.X, 0, (PAP_SIZE_HI << 16) - 1);
|
||
|
SATURATE(new_position.Z, 0, (PAP_SIZE_HI << 16) - 1);
|
||
|
|
||
|
p_thing->Velocity+=p_thing->DeltaVelocity;
|
||
|
// p_thing->DY-=GRAVITY; //gravity
|
||
|
p_thing->DY-=(GRAVITY*TICK_RATIO)>>TICK_SHIFT; //gravity
|
||
|
|
||
|
|
||
|
if(p_thing->DY<-30000) {
|
||
|
p_thing->DY=-30000; // hit terminal velocity... must be scary... so...
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
if(p_thing->DY==-(40<<8) && p_thing->Velocity>10)
|
||
|
{
|
||
|
|
||
|
locked_anim_change(p_thing,0,ANIM_FALL_LONG);
|
||
|
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
LogText(" projectile move vel %d dy %d \n",p_thing->Velocity,p_thing->DY);
|
||
|
|
||
|
// if(p_thing->Timer1>3)
|
||
|
if(flag&(2|4)) // under feet
|
||
|
{
|
||
|
SLONG new_y,on_face,foot_y;
|
||
|
if(face=predict_collision_with_face(p_thing,new_position.X>>8,new_position.Y>>8,new_position.Z>>8,flag&4,&new_y,&foot_y))
|
||
|
{
|
||
|
//ASSERT(face>0);
|
||
|
|
||
|
{
|
||
|
#ifndef PSX
|
||
|
if(!(GAME_FLAGS & GF_INDOORS))
|
||
|
if(face>0 && prim_faces4[face].Type==FACE_TYPE_SKYLIGHT)
|
||
|
{
|
||
|
ASSERT(0);
|
||
|
//
|
||
|
// fall through skylight into building
|
||
|
//
|
||
|
|
||
|
set_person_in_building_through_roof(p_thing,face);
|
||
|
return(0);
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
if(flag&4) //falling with pelvis as lowest point
|
||
|
return(1);
|
||
|
//on_face=calc_height_on_face(new_position.X>>8,new_position.Z>>8,face,&new_y);
|
||
|
MSG_add(" projectile move hit face %d new y %d pelvis col %d\n",face,new_y,flag&4);
|
||
|
/*
|
||
|
if(!on_face)
|
||
|
{
|
||
|
ASSERT(0);
|
||
|
//new_y=p_thing->WorldPos.Y>>8; //use new_y anyway!!!
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
p_thing->OnFace=face;
|
||
|
|
||
|
p_thing->Flags&=~FLAGS_PROJECTILE_MOVEMENT;
|
||
|
|
||
|
if((flag&4)==0)
|
||
|
{
|
||
|
//
|
||
|
// foot collsion with face
|
||
|
//
|
||
|
new_position.Y=(new_y-foot_y+5)<<8;
|
||
|
|
||
|
if (p_thing->Draw.Tweened->CurrentAnim == ANIM_PLUNGE_START ||
|
||
|
p_thing->Draw.Tweened->CurrentAnim == ANIM_PLUNGE_FORWARDS)
|
||
|
{
|
||
|
//new_position.Y = PAP_calc_map_at_thing(p_thing,new_position.X>>8,new_position.Z>>8);
|
||
|
new_position.Y = PAP_calc_map_height_at(new_position.X>>8,new_position.Z>>8);
|
||
|
new_position.Y -= 0x50;
|
||
|
new_position.Y <<= 8;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// I've put this back in, because we were exiting and not finding ourselves on the face
|
||
|
//
|
||
|
move_thing_on_map(p_thing,&new_position);
|
||
|
}
|
||
|
|
||
|
// hurt person
|
||
|
if(damage_person_on_land(p_thing))
|
||
|
return(100);
|
||
|
|
||
|
return(1);
|
||
|
}
|
||
|
else
|
||
|
if(predict_collision_with_floor(p_thing,flag&4,&new_y,&foot_y))
|
||
|
{
|
||
|
if(flag&4)
|
||
|
return(1);
|
||
|
MSG_add(" predict collision with FLOOR");
|
||
|
|
||
|
ret=1;
|
||
|
|
||
|
#if !defined(PSX) && !defined(TARGET_DC)
|
||
|
if (p_thing->Flags & FLAGS_IN_SEWERS)
|
||
|
{
|
||
|
p_thing->WorldPos.Y = NS_calc_height_at(new_position.X>>8,new_position.Z>>8)<<8;
|
||
|
}
|
||
|
else
|
||
|
#endif
|
||
|
{
|
||
|
if((flag&4)==0)
|
||
|
{
|
||
|
//
|
||
|
// foot collsion with face
|
||
|
//
|
||
|
|
||
|
new_position.Y=(new_y-foot_y+5)<<8;
|
||
|
|
||
|
if (p_thing->Draw.Tweened->CurrentAnim == ANIM_PLUNGE_START ||
|
||
|
p_thing->Draw.Tweened->CurrentAnim == ANIM_PLUNGE_FORWARDS)
|
||
|
{
|
||
|
new_position.Y = PAP_calc_height_at_thing(p_thing,new_position.X>>8,new_position.Z>>8);
|
||
|
new_position.Y -= 0x50;
|
||
|
new_position.Y <<= 8;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// I've put this back in, because we were exiting and not finding ourselves on the face
|
||
|
//
|
||
|
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
new_position.Y=PAP_calc_height_at_thing(p_thing,new_position.X>>8,new_position.Z>>8)<<8;
|
||
|
new_position.X=p_thing->WorldPos.X;
|
||
|
new_position.Z=p_thing->WorldPos.Z;
|
||
|
}
|
||
|
/*
|
||
|
if(p_thing->WorldPos.Y>(new_position.Y+(32<<8)))
|
||
|
{
|
||
|
return(0);
|
||
|
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
//
|
||
|
// foot can collide roof top
|
||
|
//
|
||
|
|
||
|
move_thing_on_map(p_thing,&new_position);
|
||
|
}
|
||
|
p_thing->OnFace=0;
|
||
|
p_thing->Flags&=~FLAGS_PROJECTILE_MOVEMENT;
|
||
|
LogText(" projectile move hit floor new y %d \n",p_thing->WorldPos.Y);
|
||
|
if(damage_person_on_land(p_thing))
|
||
|
return(100);
|
||
|
return(ret);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Actually move the person.
|
||
|
//
|
||
|
|
||
|
move_thing_on_map(p_thing,&new_position);
|
||
|
|
||
|
//
|
||
|
// Hit some barrels.
|
||
|
//
|
||
|
|
||
|
BARREL_hit_with_sphere(
|
||
|
p_thing->WorldPos.X >> 8,
|
||
|
p_thing->WorldPos.Y >> 8,
|
||
|
p_thing->WorldPos.Z >> 8,
|
||
|
0x70);
|
||
|
|
||
|
//
|
||
|
// Is this person going to fall to his death?
|
||
|
//
|
||
|
|
||
|
SLONG death_check;
|
||
|
|
||
|
if (p_thing->Genus.Person->PlayerID)
|
||
|
{
|
||
|
death_check = -12000;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
death_check = -6000;
|
||
|
}
|
||
|
|
||
|
if (GAME_FLAGS & GF_NO_FLOOR)
|
||
|
{
|
||
|
if (p_thing->WorldPos.Y < 0x0 && p_thing->DY < -6000)
|
||
|
{
|
||
|
//
|
||
|
// Stop Roper popping back onto buildings by falling underneath them.
|
||
|
//
|
||
|
|
||
|
p_thing->Velocity = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (p_thing->DY < death_check)
|
||
|
{
|
||
|
if ((GAME_TURN & 0x3)==THING_NUMBER(p_thing))
|
||
|
{
|
||
|
if (p_thing->Draw.Tweened->CurrentAnim == ANIM_PLUNGE_START ||
|
||
|
p_thing->Draw.Tweened->CurrentAnim == ANIM_PLUNGE_FORWARDS)
|
||
|
{
|
||
|
//
|
||
|
// Already falling to your death...
|
||
|
//
|
||
|
if (MagicFrameCheck(p_thing,2))
|
||
|
{
|
||
|
ScreamFallSound(p_thing); // scream yer lungs out!
|
||
|
}
|
||
|
|
||
|
p_thing->Velocity = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SLONG i;
|
||
|
|
||
|
SLONG mx;
|
||
|
SLONG mz;
|
||
|
|
||
|
SLONG height;
|
||
|
|
||
|
//
|
||
|
// Is this person going to die?
|
||
|
//
|
||
|
|
||
|
for (i = 1; i < 4; i++)
|
||
|
{
|
||
|
mx = (p_thing->WorldPos.X >> 8) - (dx * i >> 5);
|
||
|
mz = (p_thing->WorldPos.Z >> 8) - (dz * i >> 5);
|
||
|
|
||
|
if (WITHIN(mx, 0, (PAP_SIZE_HI << 8) - 1) &&
|
||
|
WITHIN(mz, 0, (PAP_SIZE_HI << 8) - 1))
|
||
|
{
|
||
|
height = PAP_calc_map_height_at(mx,mz);
|
||
|
|
||
|
if (height >= (p_thing->WorldPos.Y >> 8) - 0x600)
|
||
|
{
|
||
|
//
|
||
|
// No death!
|
||
|
//
|
||
|
|
||
|
/*
|
||
|
|
||
|
AENG_world_line(
|
||
|
p_thing->WorldPos.X >> 8,
|
||
|
p_thing->WorldPos.Y >> 8,
|
||
|
p_thing->WorldPos.Z >> 8,
|
||
|
0x10,
|
||
|
0xffffff,
|
||
|
p_thing->WorldPos.X >> 8,
|
||
|
p_thing->WorldPos.Y + 0x10000 >> 8,
|
||
|
p_thing->WorldPos.Z >> 8,
|
||
|
0x0,
|
||
|
0xffeeee,
|
||
|
FALSE);
|
||
|
|
||
|
*/
|
||
|
|
||
|
goto no_death;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// This person is going to die!
|
||
|
//
|
||
|
|
||
|
/*
|
||
|
|
||
|
AENG_world_line(
|
||
|
p_thing->WorldPos.X >> 8,
|
||
|
p_thing->WorldPos.Y >> 8,
|
||
|
p_thing->WorldPos.Z >> 8,
|
||
|
0x10,
|
||
|
0xff0000,
|
||
|
p_thing->WorldPos.X >> 8,
|
||
|
p_thing->WorldPos.Y + 0x10000 >> 8,
|
||
|
p_thing->WorldPos.Z >> 8,
|
||
|
0x0,
|
||
|
0xaacc00,
|
||
|
FALSE);
|
||
|
|
||
|
*/
|
||
|
|
||
|
locked_anim_change(p_thing, SUB_OBJECT_PELVIS, ANIM_PLUNGE_START);
|
||
|
|
||
|
/* if (MagicFrameCheck(p_thing,0))
|
||
|
{
|
||
|
ScreamFallSound(p_thing); // scream yer lungs out!
|
||
|
}*/
|
||
|
|
||
|
no_death:;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return(ret);
|
||
|
|
||
|
}
|
||
|
|
||
|
//could be logarithmic/ linear/ stepped
|
||
|
void change_velocity_to(Thing *p_thing,SWORD velocity)
|
||
|
{
|
||
|
SLONG dv;
|
||
|
|
||
|
velocity=(velocity*3)>>2; // fps required , fps used when setting up these values
|
||
|
|
||
|
dv=velocity-p_thing->Velocity;
|
||
|
if(dv<0)
|
||
|
{
|
||
|
if(dv>-2)
|
||
|
p_thing->Velocity=velocity;
|
||
|
else
|
||
|
p_thing->Velocity+=(dv>>1);
|
||
|
|
||
|
}
|
||
|
else if(dv>0)
|
||
|
{
|
||
|
if(dv<2)
|
||
|
p_thing->Velocity=velocity;
|
||
|
else
|
||
|
p_thing->Velocity+=(dv>>1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void change_velocity_to_slow(Thing *p_thing,SWORD velocity)
|
||
|
{
|
||
|
SLONG dv;
|
||
|
|
||
|
velocity=(velocity*3)>>2; // fps required , fps used when setting up these values
|
||
|
|
||
|
dv=velocity-p_thing->Velocity;
|
||
|
if(dv<0)
|
||
|
{
|
||
|
if(dv>-2)
|
||
|
p_thing->Velocity=velocity;
|
||
|
else
|
||
|
p_thing->Velocity-=1;//(dv>>3);
|
||
|
|
||
|
}
|
||
|
else if(dv>0)
|
||
|
{
|
||
|
if(dv<2)
|
||
|
p_thing->Velocity=velocity;
|
||
|
else
|
||
|
p_thing->Velocity+=1; //(dv>>3);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void trickle_velocity_to(Thing *p_thing,SWORD velocity)
|
||
|
{
|
||
|
SLONG dv;
|
||
|
|
||
|
velocity=(velocity*3)>>2; // fps required , fps used when setting up these values
|
||
|
|
||
|
dv=velocity-p_thing->Velocity;
|
||
|
if(dv<0)
|
||
|
{
|
||
|
p_thing->Velocity--;
|
||
|
|
||
|
}
|
||
|
else if(dv>0)
|
||
|
{
|
||
|
p_thing->Velocity++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void set_thing_velocity(Thing *t_thing,SLONG vel)
|
||
|
{
|
||
|
vel=(vel*3)>>2; // fps required , fps used when setting up these values
|
||
|
|
||
|
t_thing->Velocity=vel;
|
||
|
}
|
||
|
|
||
|
|
||
|
#define REQUIRED_DIST_JUMP_GRAB 35
|
||
|
|
||
|
extern SLONG dist_to_line( SLONG x1, SLONG z1, SLONG x2, SLONG z2, SLONG a, SLONG b);
|
||
|
extern void nearest_point_on_line( SLONG x1, SLONG z1, SLONG x2, SLONG z2, SLONG a, SLONG b,SLONG *ret_x,SLONG *ret_z);
|
||
|
extern calc_things_height(struct MapThing *p_thing); //editor\collide.c
|
||
|
//extern struct CollisionVect col_vects[];
|
||
|
#ifdef DOG_POO
|
||
|
SLONG setup_person_for_jump_grab(Thing *p_thing)
|
||
|
{
|
||
|
SLONG col,dist;
|
||
|
SLONG x,z;
|
||
|
struct CollisionVect *p_vect;
|
||
|
GameCoord new_position;
|
||
|
SLONG m_dx,m_dy,m_dz;
|
||
|
new_position = p_thing->WorldPos;
|
||
|
|
||
|
|
||
|
m_dx=-((SIN(p_thing->Draw.Tweened->Angle)*REQUIRED_DIST_JUMP_GRAB)>>16);
|
||
|
m_dz=-((COS(p_thing->Draw.Tweened->Angle)*REQUIRED_DIST_JUMP_GRAB)>>16);
|
||
|
m_dy=0;
|
||
|
col=check_vect_vect(m_dx,m_dy,m_dz,p_thing,2);
|
||
|
// if(!col)
|
||
|
// col=check_vect_circle(0,0,0,p_thing,80);
|
||
|
// LogText(" set person for jump col_vect %d \n",col);
|
||
|
|
||
|
x=p_thing->WorldPos.X>>8;
|
||
|
z=p_thing->WorldPos.Z>>8;
|
||
|
|
||
|
if(col)
|
||
|
{
|
||
|
SLONG new_x,new_z,angle;
|
||
|
SLONG dx,dz;
|
||
|
|
||
|
angle=get_point_dist_from_col_vect(col,x,z,&new_x,&new_z,REQUIRED_DIST_JUMP_GRAB);
|
||
|
LogText(" move person was %d %d now becomes %d %d\n",x,z,new_x,new_z);
|
||
|
|
||
|
p_thing->Draw.Tweened->Angle=angle;
|
||
|
|
||
|
new_position.X=new_x<<8;
|
||
|
new_position.Z=new_z<<8;
|
||
|
|
||
|
move_thing_on_map(p_thing,&new_position);
|
||
|
|
||
|
return(1);
|
||
|
|
||
|
}
|
||
|
return(0);
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
extern void highlight_face(SLONG face);
|
||
|
extern void e_draw_3d_mapwho(SLONG x1,SLONG z1);
|
||
|
|
||
|
void show_walkable(SLONG mx,SLONG mz)
|
||
|
{
|
||
|
SLONG index;
|
||
|
SLONG check_face;
|
||
|
|
||
|
return;
|
||
|
/*
|
||
|
|
||
|
index=MAP[MAP_INDEX(mx,mz)].Walkable;
|
||
|
if(index)
|
||
|
e_draw_3d_mapwho(mx,mz);
|
||
|
|
||
|
while(index)
|
||
|
{
|
||
|
check_face=walk_links[index].Face;
|
||
|
if(check_face>0)
|
||
|
highlight_face(check_face);
|
||
|
|
||
|
index=walk_links[index].Next;
|
||
|
}
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------
|
||
|
|
||
|
/*
|
||
|
|
||
|
What Is players Input?
|
||
|
|
||
|
Direction + Punch/Kick/Action/Block/Jump/Crouch/Mode Change
|
||
|
|
||
|
Direction (Forwards/Backwards/Left/Right)
|
||
|
|
||
|
|
||
|
What is players current status?
|
||
|
|
||
|
(Fast Mode)Run/(Stealth Mode)Walk/(combat mode) fighting
|
||
|
|
||
|
Sub Status
|
||
|
Standing/Crouching/Jumping/Climbing/Vaulting/PullingUp/ Shooting/Swimming
|
||
|
|
||
|
What scenery is player able to interact with
|
||
|
|
||
|
(MOVEMENT FAST)
|
||
|
X to Jump Up and vault over all one move ( a high fence)
|
||
|
X to jump up grab swing onto and continue running
|
||
|
X to fault over (a small fence)
|
||
|
Edge to jump from (long Jump)
|
||
|
steps/slope to move up/down
|
||
|
Wall to step up and back flip off
|
||
|
Post to grab and swing arround
|
||
|
|
||
|
|
||
|
(MOVEMENT STEALTH)
|
||
|
X to pull up and stand on (1 storey building)
|
||
|
Wall to sidle along
|
||
|
Edge to drop down from (1 storey building)
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
Code For pull up onto Storey
|
||
|
|
||
|
1. Detect Wall, face to stand on at end
|
||
|
2. Face wall At correct angle for anim
|
||
|
3. Play Anim to take you up wall
|
||
|
4. At end of anim
|
||
|
a. Go to stand anim
|
||
|
b. Relocate players position so anim change leaves a foot in same place
|
||
|
c. Set player to be on face.
|
||
|
|
||
|
Code for pull up onto multi height storey
|
||
|
|
||
|
See 1& 2 above
|
||
|
3. Play jump anim, cut short or prolong until at correct position for hands to grasp ledge
|
||
|
see 4 above
|
||
|
|
||
|
|
||
|
Alternate Method for Pull Up Onto Storey
|
||
|
|
||
|
Break Movement into 3 parts
|
||
|
|
||
|
jump to dangle position,
|
||
|
|
||
|
from dangle to pull up onto knee
|
||
|
|
||
|
from knee to standing.
|
||
|
|
||
|
|
||
|
Dangle Options
|
||
|
Swing (If Available)
|
||
|
Pull Up Onto Knee
|
||
|
Drop back to Floor
|
||
|
|
||
|
|
||
|
Kneeling on Edge Options
|
||
|
Stand Up
|
||
|
Go Back To Dangle
|
||
|
Rush Forward
|
||
|
Roll Forward
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//to do
|
||
|
|
||
|
create a collision poly system that allows players to walk/jump/vault/pull up
|
||
|
onto faces
|
||
|
|
||
|
Fire escapes can be walked up onto
|
||
|
|
||
|
Ledges can be pulled up onto
|
||
|
|
||
|
Buildings can be jumped accross from one to the other
|
||
|
|
||
|
Code for detecting the existence of interactible scenery when interaction is requested
|
||
|
|
||
|
Code for performing the interaction
|
||
|
|
||
|
|
||
|
Kerbs/ Kerbs as roof tops
|
||
|
Floor Slopes/Floor Slopes as roof tops
|
||
|
|
||
|
|
||
|
Do we link existing poly's or do we build special collision polys
|
||
|
|
||
|
Point
|
||
|
{
|
||
|
UWORD x;
|
||
|
UWORD Y;
|
||
|
UWORD Z;
|
||
|
}; //6
|
||
|
|
||
|
PolyQuad
|
||
|
{
|
||
|
Point[4];
|
||
|
SWORD PrimFace;
|
||
|
UWORD Flags; //walkable, verticle, vaultable, high,med,flat,
|
||
|
|
||
|
}; //4*6=24+4 =28
|
||
|
|
||
|
PolyTri
|
||
|
{
|
||
|
Point[3];
|
||
|
SWORD PrimFace;
|
||
|
UWORD Flags; //walkable, verticle, vaultable, high,med,flat,
|
||
|
}; //3*6=18+4 =22
|
||
|
|
||
|
|
||
|
|
||
|
//jump2 at frame 6
|
||
|
|
||
|
//walk and run are now alligned
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
*/
|