Introduced hitobj_list for persistent weapon objects to keep track of multiple objects the weapon is in contect with to prevent it from doing FPS-based damage; Made persistent weapon objects not die on debris but just decrease their shields like when an ordinary player/robot is hit - makes more sense

This commit is contained in:
zicodxx 2010-02-08 13:24:42 +00:00
parent 970fd8c2d2
commit 4ebc007757
5 changed files with 57 additions and 2 deletions

View file

@ -5,6 +5,7 @@ D1X-Rebirth Changelog
main/menu.c, main/scores.c, main/scores.h: Move all globals in scores.c into struct members/local variables
main/game.c, main/newdemo.c: Don't make another Game_wind when advancing a level, fixing failed asserts / slow turning
arch/sdl/window.c: Don't send an EVENT_WINDOW_DEACTIVATED when closing a window if it wasn't the front window, now the game works properly after you're shown on the high scores
main/collide.c, main/object.c, main/object.h, main/state.c: Introduced hitobj_list for persistent weapon objects to keep track of multiple objects the weapon is in contect with to prevent it from doing FPS-based damage; Made persistent weapon objects not die on debris but just decrease their shields like when an ordinary player/robot is hit - makes more sense
20100207
--------

View file

@ -899,6 +899,24 @@ void collide_robot_and_weapon( object * robot, object * weapon, vms_vector *coll
robot->rtype.pobj_info.tmap_override = Ugly_robot_texture % NumTextures;
}
#if 1
/*
* Check if persistent weapon already hit this object. If yes, abort.
* If no, add this object to hitobj_list and do it's damage.
*/
if (weapon->mtype.phys_info.flags & PF_PERSISTENT)
{
if (!hitobj_list[weapon-Objects][robot-Objects])
{
hitobj_list[weapon-Objects][robot-Objects] = 1;
weapon->ctype.laser_info.last_hitobj = robot-Objects;
}
else
{
return;
}
}
#else
// If a persistent weapon hit robot most recently, quick abort, else we cream the same robot many times,
// depending on frame rate.
if (weapon->mtype.phys_info.flags & PF_PERSISTENT) {
@ -907,6 +925,7 @@ void collide_robot_and_weapon( object * robot, object * weapon, vms_vector *coll
else
weapon->ctype.laser_info.last_hitobj = robot-Objects;
}
#endif
if (weapon->ctype.laser_info.parent_signature == robot->signature)
return;
@ -1203,12 +1222,31 @@ void collide_player_and_weapon( object * player, object * weapon, vms_vector *co
damage = fixmul(damage, weapon->ctype.laser_info.multiplier);
#if 1
/*
* Check if persistent weapon already hit this object. If yes, abort.
* If no, add this object to hitobj_list and do it's damage.
*/
if (weapon->mtype.phys_info.flags & PF_PERSISTENT)
{
if (!hitobj_list[weapon-Objects][player-Objects])
{
hitobj_list[weapon-Objects][player-Objects] = 1;
weapon->ctype.laser_info.last_hitobj = player-Objects;
}
else
{
return;
}
}
#else
if (weapon->mtype.phys_info.flags & PF_PERSISTENT) {
if (weapon->ctype.laser_info.last_hitobj == player-Objects)
return;
else
weapon->ctype.laser_info.last_hitobj = player-Objects;
}
#endif
if (player->id == Player_num)
{
@ -1446,7 +1484,8 @@ void collide_weapon_and_debris( object * weapon, object * debris, vms_vector *co
if ( Weapon_info[weapon->id].damage_radius )
explode_badass_weapon(weapon);
maybe_kill_weapon(weapon,debris);
weapon->flags |= OF_SHOULD_BE_DEAD;
if (!(weapon->mtype.phys_info.flags & PF_PERSISTENT))
weapon->flags |= OF_SHOULD_BE_DEAD;
}
return;
}

View file

@ -83,6 +83,7 @@ void obj_detach_one(object *sub);
*/
ubyte CollisionResult[MAX_OBJECT_TYPES][MAX_OBJECT_TYPES];
ubyte hitobj_list[MAX_OBJECTS][MAX_OBJECTS]; // last_hitobj of laser_inof struct can only keep track of one object. Still a persistent laser can hit several objects at the same time. This list keeps track of those while last_hitobj will only represent the most recent (the last) hitobj.
object *ConsoleObject; //the object that is the player
@ -1129,6 +1130,7 @@ int obj_create(ubyte type,ubyte id,int segnum,vms_vector *pos,
obj->mtype.phys_info.flags |= (Weapon_info[obj->id].persistent*PF_PERSISTENT);
obj->ctype.laser_info.creation_time = GameTime;
obj->ctype.laser_info.last_hitobj = -1;
memset(&hitobj_list[objnum], 0, sizeof(ubyte)*MAX_OBJECTS);
obj->ctype.laser_info.multiplier = F1_0;
}

View file

@ -171,11 +171,13 @@ typedef struct laser_info {
short parent_num; // The object's parent's number
int parent_signature; // The object's parent's signature...
fix creation_time; // Absolute time of creation.
short last_hitobj; // For persistent weapons (survive object collision), object it most recently hit.
short last_hitobj; // For persistent weapons (survive object collision), object it most recently hit. NOTE: SEE hitobj_list!!!
short track_goal; // Object this object is tracking.
fix multiplier; // Power if this is a fusion bolt (or other super weapon to be added).
} __pack__ laser_info;
extern ubyte hitobj_list[MAX_OBJECTS][MAX_OBJECTS];
typedef struct explosion_info {
fix spawn_time; // when lifeleft is < this, spawn another
fix delete_time; // when to delete object

View file

@ -779,6 +779,17 @@ RetryObjectLoading:
}
obj_link(i,segnum);
}
// If weapon, restore the most recent hitobj to the list
if (obj->type == OBJ_WEAPON)
{
if (obj->ctype.laser_info.last_hitobj > 0 && obj->ctype.laser_info.last_hitobj < MAX_OBJECTS)
{
memset(&hitobj_list[i], 0, sizeof(ubyte)*MAX_OBJECTS);
hitobj_list[i][obj->ctype.laser_info.last_hitobj] = 1;
printf("RESTORE WEAPON[%i] LHO[%i]\n",i,obj->ctype.laser_info.last_hitobj);
}
}
}
special_reset_objects();