Skip to content

Commit

Permalink
HAMERS! Wait 33ms between each turn of a homing missile projectile, o…
Browse files Browse the repository at this point in the history
…nly scale turns if FPS are below 30
  • Loading branch information
zico committed Aug 7, 2013
1 parent 528d2e3 commit bbaa3c2
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 122 deletions.
3 changes: 1 addition & 2 deletions common/main/laser.h
Expand Up @@ -104,8 +104,6 @@ enum weapon_type_t
#define MUZZLE_QUEUE_MAX 8

// Constants governing homing missile behavior.
// MIN_TRACKABLE_DOT gets inversely scaled by FrameTime and stuffed in
// Min_trackable_dot
#if defined(DXX_BUILD_DESCENT_I)
#define HOMING_MAX_TRACKABLE_DOT (3*F1_0/4)
#elif defined(DXX_BUILD_DESCENT_II)
Expand All @@ -114,6 +112,7 @@ enum weapon_type_t
#define HOMING_MIN_TRACKABLE_DOT (3*(F1_0 - HOMING_MAX_TRACKABLE_DOT)/4 + HOMING_MAX_TRACKABLE_DOT)
#define HOMING_MAX_TRACKABLE_DIST (F1_0*250)
#define HOMING_FLY_STRAIGHT_TIME (F1_0/8)
#define HOMING_TURN_TIME (F1_0/30)

struct object;

Expand Down
2 changes: 1 addition & 1 deletion common/main/multi.h
Expand Up @@ -60,7 +60,7 @@ extern int multi_protocol; // set and determinate used protocol
#define MULTI_PROTO_UDP 1 // UDP protocol

// What version of the multiplayer protocol is this? Increment each time something drastic changes in Multiplayer without the version number changes. Can be reset to 0 each time the version of the game changes
#define MULTI_PROTO_VERSION 1
#define MULTI_PROTO_VERSION 2
// PROTOCOL VARIABLES AND DEFINES - END


Expand Down
1 change: 1 addition & 0 deletions common/main/object.h
Expand Up @@ -213,6 +213,7 @@ typedef struct laser_info {
ubyte hitobj_list[MAX_OBJECTS]; // list of all objects persistent weapon has already damaged (useful in case it's in contact with two objects at the same time)
short track_goal; // Object this object is tracking.
fix multiplier; // Power if this is a fusion bolt (or other super weapon to be added).
fix track_turn_time;
} __pack__ laser_info;

// Same as above but structure Savegames/Multiplayer objects expect
Expand Down
82 changes: 19 additions & 63 deletions d1x-rebirth/main/laser.c
Expand Up @@ -669,16 +669,9 @@ int find_homing_object_complete(vms_vector *curpos, object *tracker, int track_o
// else return object number of tracking object.
int track_track_goal(int track_goal, object *tracker, fix *dot)
{
#ifdef NEWHOMER
if (object_is_trackable(track_goal, tracker, dot)) {
return track_goal;
} else if ((((tracker-Objects) ^ d_tick_count) % 4) == 0)
#else
// Every 8 frames for each object, scan all objects.
if (object_is_trackable(track_goal, tracker, dot) && ((((tracker-Objects) ^ d_tick_count) % 8) != 0)) {
return track_goal;
} else if ((((tracker-Objects) ^ d_tick_count) % 4) == 0)
#endif
{
int rval = -2;

Expand Down Expand Up @@ -825,6 +818,7 @@ void Laser_player_fire_spread_delay(object *obj, int laser_type, int gun_num, fi
Objects[objnum].ctype.laser_info.track_goal = Network_laser_track;
}
#endif
Objects[objnum].ctype.laser_info.track_turn_time = HOMING_TURN_TIME;
}
}

Expand Down Expand Up @@ -889,14 +883,6 @@ void homing_missile_turn_towards_velocity(object *objp, vms_vector *norm_vel)
vm_vector_2_matrix(&objp->orient, &new_fvec, NULL, NULL);
}

#ifdef NEWHOMER
/*
* In the original game homers turned sharper in higher FPS-values. We do not want that so we need to scale vector_to_object to FrameTime.
* For each difficulty setting we have a base value the homers will align to. This we express in a FPS value representing the homers turn radius of the original game (i.e. "The homer will turn like on XXFPS").
*/
fix homing_turn_base[NDL] = { 22, 24, 26, 28, 30 };
#endif

//-------------------------------------------------------------------------------------------
//sequence this laser object for this _frame_ (underscores added here to aid MK in his searching!)
void Laser_do_weapon_sequence(object *obj)
Expand Down Expand Up @@ -956,48 +942,26 @@ void Laser_do_weapon_sequence(object *obj)

if (track_goal != -1) {
#ifdef NEWHOMER
vm_vec_sub(&vector_to_object, &Objects[track_goal].pos, &obj->pos);

// Scale vector to object to current FrameTime.
vm_vec_scale(&vector_to_object, F1_0/((float)(F1_0/homing_turn_base[Difficulty_level])/FrameTime));

vm_vec_normalize_quick(&vector_to_object);
temp_vec = obj->mtype.phys_info.velocity;
speed = vm_vec_normalize_quick(&temp_vec);
max_speed = Weapon_info[obj->id].speed[Difficulty_level];
if (speed+F1_0 < max_speed) {
speed += fixmul(max_speed, FrameTime/2);
if (speed > max_speed)
speed = max_speed;
// See if enough time (see HOMING_TURN_TIME) passed and if yes, allow a turn. If not, fly straight.
if (obj->ctype.laser_info.track_turn_time >= HOMING_TURN_TIME)
{
vm_vec_sub(&vector_to_object, &Objects[track_goal].pos, &obj->pos);
obj->ctype.laser_info.track_turn_time -= HOMING_TURN_TIME;
}

dot = vm_vec_dot(&temp_vec, &vector_to_object);

vm_vec_add2(&temp_vec, &vector_to_object);
// The boss' smart children track better...
if (Weapon_info[obj->id].render_type != WEAPON_RENDER_POLYMODEL)
vm_vec_add2(&temp_vec, &vector_to_object);
vm_vec_normalize_quick(&temp_vec);
vm_vec_scale(&temp_vec, speed);
obj->mtype.phys_info.velocity = temp_vec;

// Subtract off life proportional to amount turned.
// For hardest turn, it will lose 2 seconds per second.
else
{
fix lifelost, absdot;

absdot = abs(F1_0 - dot);

lifelost = fixmul(absdot*32, FrameTime);
obj->lifeleft -= lifelost;
vms_vector straight;
vm_vec_add(&straight, &obj->mtype.phys_info.velocity, &obj->pos);
vm_vec_sub(&vector_to_object, &straight, &obj->pos);
}
obj->ctype.laser_info.track_turn_time += FrameTime;

// Only polygon objects have visible orientation, so only they should turn.
if (Weapon_info[obj->id].render_type == WEAPON_RENDER_POLYMODEL)
homing_missile_turn_towards_velocity(obj, &temp_vec); // temp_vec is normalized velocity.
#else // OLD - ORIGINAL - MISSILE TRACKING CODE
// Scale vector to object to current FrameTime if we run really low
if (FrameTime > HOMING_TURN_TIME)
vm_vec_scale(&vector_to_object, F1_0/((float)HOMING_TURN_TIME/FrameTime));
#else
vm_vec_sub(&vector_to_object, &Objects[track_goal].pos, &obj->pos);

#endif
vm_vec_normalize_quick(&vector_to_object);
temp_vec = obj->mtype.phys_info.velocity;
speed = vm_vec_normalize_quick(&temp_vec);
Expand Down Expand Up @@ -1025,21 +989,13 @@ void Laser_do_weapon_sequence(object *obj)

absdot = abs(F1_0 - dot);

if (absdot > F1_0/8) {
if (absdot > F1_0/4)
absdot = F1_0/4;
lifelost = fixmul(absdot*16, FrameTime);
obj->lifeleft -= lifelost;
}
//added 8/14/98 by Victor Rachels to make homers lose life while going straight, too
obj->lifeleft -= fixmul(F1_0, FrameTime);
//end addition - Victor Rachels
lifelost = fixmul(absdot*32, FrameTime);
obj->lifeleft -= lifelost;
}

// Only polygon objects have visible orientation, so only they should turn.
if (Weapon_info[obj->id].render_type == WEAPON_RENDER_POLYMODEL)
homing_missile_turn_towards_velocity(obj, &temp_vec); // temp_vec is normalized velocity.
#endif
homing_missile_turn_towards_velocity(obj, &temp_vec); // temp_vec is normalized velocity.
}
}
}
Expand Down
1 change: 1 addition & 0 deletions d1x-rebirth/main/multi.c
Expand Up @@ -4042,6 +4042,7 @@ void multi_object_rw_to_object(object_rw *obj_rw, object *obj)
obj->ctype.laser_info.last_hitobj = obj_rw->ctype.laser_info.last_hitobj;
obj->ctype.laser_info.track_goal = obj_rw->ctype.laser_info.track_goal;
obj->ctype.laser_info.multiplier = obj_rw->ctype.laser_info.multiplier;
obj->ctype.laser_info.track_turn_time = HOMING_TURN_TIME;
break;

case CT_EXPLOSION:
Expand Down
76 changes: 20 additions & 56 deletions d2x-rebirth/main/laser.c
Expand Up @@ -1114,16 +1114,9 @@ int find_homing_object_complete(vms_vector *curpos, object *tracker, int track_o
// Computes and returns a fairly precise dot product.
int track_track_goal(int track_goal, object *tracker, fix *dot)
{
#ifdef NEWHOMER
if (object_is_trackable(track_goal, tracker, dot)) {
return track_goal;
} else if ((((tracker-Objects) ^ d_tick_count) % 4) == 0)
#else
// Every 8 frames for each object, scan all objects.
if (object_is_trackable(track_goal, tracker, dot)) {
return track_goal;
} else if ((((tracker-Objects) ^ d_tick_count) % 4) == 0)
#endif
{
int rval = -2;

Expand Down Expand Up @@ -1300,6 +1293,7 @@ void Laser_player_fire_spread_delay(object *obj, int laser_type, int gun_num, fi
Objects[objnum].ctype.laser_info.track_goal = Network_laser_track;
}
#endif
Objects[objnum].ctype.laser_info.track_turn_time = HOMING_TURN_TIME;
}
}

Expand Down Expand Up @@ -1365,14 +1359,6 @@ void homing_missile_turn_towards_velocity(object *objp, vms_vector *norm_vel)
vm_vector_2_matrix(&objp->orient, &new_fvec, NULL, NULL);
}

#ifdef NEWHOMER
/*
* In the original game homers turned sharper in higher FPS-values. We do not want that so we need to scale vector_to_object to FrameTime.
* For each difficulty setting we have a base value the homers will align to. This we express in a FPS value representing the homers turn radius of the original game (i.e. "The homer will turn like on XXFPS").
* NOTE: Old homers only get valid track_goal every 8 frames. This does not apply anymore so these values are divided by 4 to compensate this.
*/
fix homing_turn_base[NDL] = { 22, 24, 26, 28, 30 };
#endif

//-------------------------------------------------------------------------------------------
//sequence this laser object for this _frame_ (underscores added here to aid MK in his searching!)
Expand Down Expand Up @@ -1437,48 +1423,26 @@ void Laser_do_weapon_sequence(object *obj)

if (track_goal != -1) {
#ifdef NEWHOMER
vm_vec_sub(&vector_to_object, &Objects[track_goal].pos, &obj->pos);

// Scale vector to object to current FrameTime.
vm_vec_scale(&vector_to_object, F1_0/((float)(F1_0/homing_turn_base[Difficulty_level])/FrameTime));

vm_vec_normalize_quick(&vector_to_object);
temp_vec = obj->mtype.phys_info.velocity;
speed = vm_vec_normalize_quick(&temp_vec);
max_speed = Weapon_info[obj->id].speed[Difficulty_level];
if (speed+F1_0 < max_speed) {
speed += fixmul(max_speed, FrameTime/2);
if (speed > max_speed)
speed = max_speed;
// See if enough time (see HOMING_TURN_TIME) passed and if yes, allow a turn. If not, fly straight.
if (obj->ctype.laser_info.track_turn_time >= HOMING_TURN_TIME)
{
vm_vec_sub(&vector_to_object, &Objects[track_goal].pos, &obj->pos);
obj->ctype.laser_info.track_turn_time -= HOMING_TURN_TIME;
}

dot = vm_vec_dot(&temp_vec, &vector_to_object);

vm_vec_add2(&temp_vec, &vector_to_object);
// The boss' smart children track better...
if (Weapon_info[obj->id].render_type != WEAPON_RENDER_POLYMODEL)
vm_vec_add2(&temp_vec, &vector_to_object);
vm_vec_normalize_quick(&temp_vec);
vm_vec_scale(&temp_vec, speed);
obj->mtype.phys_info.velocity = temp_vec;

// Subtract off life proportional to amount turned.
// For hardest turn, it will lose 2 seconds per second.
else
{
fix lifelost, absdot;

absdot = abs(F1_0 - dot);

lifelost = fixmul(absdot*32, FrameTime);
obj->lifeleft -= lifelost;
vms_vector straight;
vm_vec_add(&straight, &obj->mtype.phys_info.velocity, &obj->pos);
vm_vec_sub(&vector_to_object, &straight, &obj->pos);
}
obj->ctype.laser_info.track_turn_time += FrameTime;

// Only polygon objects have visible orientation, so only they should turn.
if (Weapon_info[obj->id].render_type == WEAPON_RENDER_POLYMODEL)
homing_missile_turn_towards_velocity(obj, &temp_vec); // temp_vec is normalized velocity.
#else // OLD - ORIGINAL - MISSILE TRACKING CODE
// Scale vector to object to current FrameTime if we run really low
if (FrameTime > HOMING_TURN_TIME)
vm_vec_scale(&vector_to_object, F1_0/((float)HOMING_TURN_TIME/FrameTime));
#else
vm_vec_sub(&vector_to_object, &Objects[track_goal].pos, &obj->pos);

#endif
vm_vec_normalize_quick(&vector_to_object);
temp_vec = obj->mtype.phys_info.velocity;
speed = vm_vec_normalize_quick(&temp_vec);
Expand All @@ -1489,14 +1453,15 @@ void Laser_do_weapon_sequence(object *obj)
speed = max_speed;
}

// -- dot = vm_vec_dot(&temp_vec, &vector_to_object);
dot = vm_vec_dot(&temp_vec, &vector_to_object);

vm_vec_add2(&temp_vec, &vector_to_object);
// The boss' smart children track better...
if (Weapon_info[obj->id].render_type != WEAPON_RENDER_POLYMODEL)
vm_vec_add2(&temp_vec, &vector_to_object);
vm_vec_normalize_quick(&temp_vec);
vm_vec_scale(&temp_vec, speed);
obj->mtype.phys_info.velocity = temp_vec;
vm_vec_scale(&obj->mtype.phys_info.velocity, speed);

// Subtract off life proportional to amount turned.
// For hardest turn, it will lose 2 seconds per second.
Expand All @@ -1511,8 +1476,7 @@ void Laser_do_weapon_sequence(object *obj)

// Only polygon objects have visible orientation, so only they should turn.
if (Weapon_info[obj->id].render_type == WEAPON_RENDER_POLYMODEL)
homing_missile_turn_towards_velocity(obj, &temp_vec); // temp_vec is normalized velocity.
#endif
homing_missile_turn_towards_velocity(obj, &temp_vec); // temp_vec is normalized velocity.
}
}
}
Expand Down
1 change: 1 addition & 0 deletions d2x-rebirth/main/multi.c
Expand Up @@ -5694,6 +5694,7 @@ void multi_object_rw_to_object(object_rw *obj_rw, object *obj)
obj->ctype.laser_info.last_hitobj = obj_rw->ctype.laser_info.last_hitobj;
obj->ctype.laser_info.track_goal = obj_rw->ctype.laser_info.track_goal;
obj->ctype.laser_info.multiplier = obj_rw->ctype.laser_info.multiplier;
obj->ctype.laser_info.track_turn_time = HOMING_TURN_TIME;
break;

case CT_EXPLOSION:
Expand Down
1 change: 1 addition & 0 deletions similar/main/state.c
Expand Up @@ -359,6 +359,7 @@ void state_object_rw_to_object(object_rw *obj_rw, object *obj)
obj->ctype.laser_info.hitobj_list[obj->ctype.laser_info.last_hitobj] = 1; // restore most recent hitobj to hitobj_list
obj->ctype.laser_info.track_goal = obj_rw->ctype.laser_info.track_goal;
obj->ctype.laser_info.multiplier = obj_rw->ctype.laser_info.multiplier;
obj->ctype.laser_info.track_turn_time = HOMING_TURN_TIME;
break;

case CT_EXPLOSION:
Expand Down

0 comments on commit bbaa3c2

Please sign in to comment.