Fix critters dying on exit grids
This commit is contained in:
parent
280b55ab05
commit
6f62cfd466
|
@ -120,6 +120,15 @@ int actionKnockdown(Object* obj, int* anim, int maxDistance, int rotation, int d
|
||||||
distance--;
|
distance--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CE: Fix to prevent critters (including player) cross an exit grid as
|
||||||
|
// a result of knockback. Sfall has similar fix done differently and it
|
||||||
|
// affects the player only. This approach is better since it also
|
||||||
|
// prevents unreachable (=unlootable) corpses on exit grids.
|
||||||
|
if (isExitGridAt(tile, obj->elevation)) {
|
||||||
|
distance--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* soundEffectName = sfxBuildCharName(obj, *anim, CHARACTER_SOUND_EFFECT_KNOCKDOWN);
|
const char* soundEffectName = sfxBuildCharName(obj, *anim, CHARACTER_SOUND_EFFECT_KNOCKDOWN);
|
||||||
|
@ -349,16 +358,31 @@ void _show_damage_to_object(Object* a1, int damage, int flags, Object* weapon, b
|
||||||
int randomDistance = randomBetween(2, 5);
|
int randomDistance = randomBetween(2, 5);
|
||||||
int randomRotation = randomBetween(0, 5);
|
int randomRotation = randomBetween(0, 5);
|
||||||
|
|
||||||
while (randomDistance > 0) {
|
// CE: Fix to prevent critters (including player) to cross
|
||||||
int tile = tileGetTileInDirection(a1->tile, randomRotation, randomDistance);
|
// an exit grid as a result of fire dance animation. See
|
||||||
Object* v35 = NULL;
|
// `actionKnockdown` for notes.
|
||||||
_make_straight_path(a1, a1->tile, tile, NULL, &v35, 4);
|
int rotation = randomRotation;
|
||||||
if (v35 == NULL) {
|
int distance = randomDistance;
|
||||||
|
while (true) {
|
||||||
|
int tile = tileGetTileInDirection(a1->tile, (rotation + randomRotation) % ROTATION_COUNT, distance);
|
||||||
|
if (!isExitGridAt(tile, a1->elevation)) {
|
||||||
|
Object* obstacle = NULL;
|
||||||
|
_make_straight_path(a1, a1->tile, tile, NULL, &obstacle, 4);
|
||||||
|
if (obstacle == NULL) {
|
||||||
animationRegisterRotateToTile(a1, tile);
|
animationRegisterRotateToTile(a1, tile);
|
||||||
animationRegisterMoveToTileStraight(a1, tile, a1->elevation, anim, 0);
|
animationRegisterMoveToTileStraight(a1, tile, a1->elevation, anim, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
randomDistance--;
|
}
|
||||||
|
|
||||||
|
if (distance > 0) {
|
||||||
|
distance--;
|
||||||
|
} else if (rotation < ROTATION_COUNT) {
|
||||||
|
rotation++;
|
||||||
|
distance = randomDistance;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5243,4 +5243,22 @@ Object* objectTypedFindById(int id, int type)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isExitGridAt(int tile, int elevation)
|
||||||
|
{
|
||||||
|
ObjectListNode* objectListNode = gObjectListHeadByTile[tile];
|
||||||
|
while (objectListNode != NULL) {
|
||||||
|
Object* obj = objectListNode->obj;
|
||||||
|
if (obj->elevation == elevation) {
|
||||||
|
if ((obj->flags & OBJECT_HIDDEN) == 0) {
|
||||||
|
if (isExitGridPid(obj->pid)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
objectListNode = objectListNode->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace fallout
|
} // namespace fallout
|
||||||
|
|
|
@ -100,6 +100,7 @@ int _obj_load_dude(File* stream);
|
||||||
void _obj_fix_violence_settings(int* fid);
|
void _obj_fix_violence_settings(int* fid);
|
||||||
|
|
||||||
Object* objectTypedFindById(int id, int type);
|
Object* objectTypedFindById(int id, int type);
|
||||||
|
bool isExitGridAt(int tile, int elevation);
|
||||||
|
|
||||||
} // namespace fallout
|
} // namespace fallout
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue