Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions src/thing_corpses.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,19 +443,18 @@ struct Thing *create_dead_creature(const struct Coord3d *pos, ThingModel model,
thing->corpse.exp_level = exp_level;
thing->mappos.x.val = pos->x.val;
thing->mappos.y.val = pos->y.val;
thing->mappos.z.val = 0;
thing->mappos.z.val = get_thing_height_at(thing, &thing->mappos);
thing->clipbox_size_xy = 0;
thing->clipbox_size_z = 0;
thing->solid_size_xy = 0;
thing->solid_size_z = 0;
struct CreatureModelConfig *crconf = creature_stats_get(model);
thing->clipbox_size_xy = crconf->size_xy;
thing->clipbox_size_z = crconf->size_z;
thing->solid_size_xy = crconf->thing_size_xy;
thing->solid_size_z = crconf->thing_size_z;
thing->fall_acceleration = 16;
thing->inertia_floor = 204;
thing->inertia_air = 51;
thing->bounce_angle = 0;
thing->movement_flags |= TMvF_Unknown08;
thing->creation_turn = game.play_gameturn;
struct CreatureModelConfig* crconf = creature_stats_get(model);
if (crconf->transparency_flags != 0)
{
set_flag(thing->rendering_flags, crconf->transparency_flags);
Expand Down
2 changes: 1 addition & 1 deletion src/thing_effects.c
Original file line number Diff line number Diff line change
Expand Up @@ -1075,7 +1075,7 @@ TbBool explosion_affecting_thing(struct Thing *tngsrc, struct Thing *tngdst, con
if (game.conf.rules.magic.weight_calculate_push > 0)
{
int weight = compute_creature_weight(tngdst);
adjusted_blow_strength = weight_calculated_push_strenght(weight, blow_strength);
adjusted_blow_strength = weight_calculated_push_strength(weight, blow_strength);
}


Expand Down
2 changes: 1 addition & 1 deletion src/thing_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -3424,7 +3424,7 @@ HitTargetFlags hit_type_to_hit_targets(long hit_type)
HitTF_AnyWorkshopBoxes|HitTF_AnySpellbooks|HitTF_AnyDnSpecialBoxes|
HitTF_EnemyShotsCollide|HitTF_AlliedShotsCollide|HitTF_OwnedShotsCollide|
HitTF_EnemyDestructibleTraps|HitTF_AlliedDestructibleTraps|HitTF_OwnedDestructibleTraps|
HitTF_AnyFoodObjects|HitTF_AnyGoldPiles;
HitTF_AnyFoodObjects|HitTF_AnyGoldPiles|HitTF_CreatureDeadBodies;
case THit_CrtrsNObjcts:
return HitTF_EnemyCreatures|HitTF_AlliedCreatures|HitTF_OwnedCreatures|HitTF_ArmourAffctdCreatrs|HitTF_PreventDmgCreatrs|
HitTF_EnemySoulContainer|HitTF_AlliedSoulContainer|HitTF_OwnedSoulContainer|
Expand Down
116 changes: 94 additions & 22 deletions src/thing_shots.c
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,7 @@ void shot_kill_creature(struct Thing *shotng, struct Thing *creatng)
* @param push_strength The original push strength.
* @return The adjusted push strength.
*/
int weight_calculated_push_strenght(int weight, int push_strength)
int weight_calculated_push_strength(int weight, int push_strength)
{
const int min_weight = 6; // Minimum weight threshold for the creature.
const int max_weight = game.conf.rules.magic.weight_calculate_push; // Maximum weight threshold for the creature.
Expand Down Expand Up @@ -1205,7 +1205,7 @@ long melee_shot_hit_creature_at(struct Thing *shotng, struct Thing *trgtng, stru
if (game.conf.rules.magic.weight_calculate_push > 0)
{
int weight = compute_creature_weight(trgtng);
adjusted_throw_strength = weight_calculated_push_strenght(weight, throw_strength);
adjusted_throw_strength = weight_calculated_push_strength(weight, throw_strength);
}
if (shotst->push_on_hit || creature_is_being_unconscious(trgtng))
{
Expand Down Expand Up @@ -1395,7 +1395,7 @@ long shot_hit_creature_at(struct Thing *shotng, struct Thing *trgtng, struct Coo
if (game.conf.rules.magic.weight_calculate_push > 0)
{
int weight = compute_creature_weight(trgtng);
adjusted_push_strength = weight_calculated_push_strenght(weight, push_strength);
adjusted_push_strength = weight_calculated_push_strength(weight, push_strength);
}

if (push_strength != 0 )
Expand Down Expand Up @@ -1503,28 +1503,100 @@ long shot_hit_creature_at(struct Thing *shotng, struct Thing *trgtng, struct Coo
return 1;
}

TbBool shot_hit_shootable_thing_at(struct Thing *shotng, struct Thing *target, struct Coord3d *pos)
long shot_hit_dead_creature_at(struct Thing *shotng, struct Thing *trgtng, struct Coord3d *pos)
{
if (!thing_exists(target))
return false;
if (target->class_id == TCls_Object) {
return shot_hit_object_at(shotng, target, pos);
long i;
struct ShotConfigStats* shotst = get_shot_model_stats(shotng->model);
long push_strength = shotst->push_on_hit;
long adjusted_push_strength = push_strength;
if (game.conf.rules.magic.weight_calculate_push > 0)
{
int weight = compute_creature_weight(trgtng);
adjusted_push_strength = weight_calculated_push_strength(weight, push_strength);
}
if (push_strength != 0 )
{
i = adjusted_push_strength * shotng->velocity.x.val;
trgtng->veloc_push_add.x.val += i / 16;
i = adjusted_push_strength * shotng->velocity.y.val;
trgtng->veloc_push_add.y.val += i / 16;
trgtng->state_flags |= TF1_PushAdd;
}
if (target->class_id == TCls_Creature) {
return shot_hit_creature_at(shotng, target, pos);
if (push_strength == 0)
push_strength++;
if (game.conf.rules.game.classic_bugs_flags & ClscBug_FaintedImmuneToBoulder)
{
push_strength *= 5;
int move_x = push_strength * shotng->velocity.x.val / 16.0;
int move_y = push_strength * shotng->velocity.y.val / 16.0;
trgtng->veloc_push_add.x.val += move_x;
trgtng->veloc_push_add.y.val += move_y;
trgtng->state_flags |= TF1_PushAdd;
}
else
{
if (shotst->model_flags & ShMF_Boulder) //Boulders move units slightly but without purpose
{
if (abs(shotng->velocity.x.val) >= abs(shotng->velocity.y.val))
{
i = push_strength * shotng->velocity.x.val;
trgtng->veloc_push_add.x.val += i / 64;
i = push_strength * shotng->velocity.x.val * (CREATURE_RANDOM(shotng, 3) - 1);
trgtng->veloc_push_add.y.val += i / 64;
}
else
{
i = push_strength * shotng->velocity.y.val;
trgtng->veloc_push_add.y.val += i / 64;
i = push_strength * shotng->velocity.y.val * (CREATURE_RANDOM(shotng, 3) - 1);
trgtng->veloc_push_add.x.val += i / 64;
}
trgtng->state_flags |= TF1_PushAdd;
}
else // Normal shots blast dead units out of the way
{
push_strength *= 5;
i = push_strength * shotng->velocity.x.val;
trgtng->veloc_push_add.x.val += i / 16;
i = push_strength * shotng->velocity.y.val;
trgtng->veloc_push_add.y.val += i / 16;
trgtng->state_flags |= TF1_PushAdd;
}
}
if (target->class_id == TCls_Trap) {
return shot_hit_trap_at(shotng, target, pos);
create_relevant_effect_for_shot_hitting_thing(shotng, trgtng);
if (shotst->model_flags & ShMF_Boulder)
{
return 0; // We're not actually hitting the dead units with a boulder
}
if (target->class_id == TCls_DeadCreature) {
//TODO implement shooting dead bodies
if (shotst->destroy_on_first_hit != 0) {
delete_thing_structure(shotng, 0);
}
if (target->class_id == TCls_Shot) {
// On a shot for collision, both shots are destroyed
//TODO maybe make both shots explode instead?
shotng->health = -1;
target->health = -1;
return true;
return 1;
}

TbBool shot_hit_shootable_thing_at(struct Thing *shotng, struct Thing *target, struct Coord3d *pos)
{
if (thing_exists(target))
{
switch(target->class_id)
{
case TCls_Object:
return shot_hit_object_at(shotng, target, pos);
case TCls_Creature:
return shot_hit_creature_at(shotng, target, pos);
case TCls_Trap:
return shot_hit_trap_at(shotng, target, pos);
case TCls_DeadCreature:
return shot_hit_dead_creature_at(shotng, target, pos);
case TCls_Shot:
{
// On a shot for collision, both shots are destroyed
//TODO maybe make both shots explode instead?
shotng->health = -1;
target->health = -1;
return true;
}
}
}
return false;
}
Expand Down Expand Up @@ -1630,7 +1702,7 @@ TbBool shot_hit_something_while_moving(struct Thing *shotng, struct Coord3d *nxp
if (thing_is_invalid(targetng)) {
return false;
}
SYNCDBG(18,"The %s index %d, collided with %s index %d",thing_model_name(shotng),(int)shotng->index,thing_model_name(targetng),(int)targetng->index);
// SYNCDBG(18,"The %s index %d, collided with %s index %d",thing_model_name(shotng),(int)shotng->index,thing_model_name(targetng),(int)targetng->index);
if (shot_hit_shootable_thing_at(shotng, targetng, nxpos)) {
return true;
}
Expand Down Expand Up @@ -1951,7 +2023,7 @@ static TngUpdateRet affect_thing_by_wind(struct Thing *thing, ModTngFilterParam
{
long weight = compute_creature_weight(thing);
//max push distance
blow_distance = maxdistance - (maxdistance - weight_calculated_push_strenght(weight, maxdistance));
blow_distance = maxdistance - (maxdistance - weight_calculated_push_strength(weight, maxdistance));
// distance between startposition and actual position of the projectile
int origin_distance = get_chessboard_distance(&shotng->shot.originpos, &thing->mappos) + 1;
creature_distance = origin_distance;
Expand Down
2 changes: 1 addition & 1 deletion src/thing_shots.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ TbBool thing_is_shot(const struct Thing *thing);
long get_damage_of_melee_shot(struct Thing *shotng, const struct Thing *target, TbBool NeverBlock);
long project_damage_of_melee_shot(long shot_dexterity, long shot_damage, const struct Thing *target);
void create_relevant_effect_for_shot_hitting_thing(struct Thing *shotng, struct Thing *target);
int weight_calculated_push_strenght(int weight, int push_strength);
int weight_calculated_push_strength(int weight, int push_strength);

TbBool shot_is_slappable(const struct Thing *thing, PlayerNumber plyr_idx);
TbBool shot_model_is_navigable(long tngmodel);
Expand Down
32 changes: 30 additions & 2 deletions src/thing_stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -1196,11 +1196,13 @@ GoldAmount calculate_gold_digged_out_of_slab_with_single_hit(long damage_did_to_
long compute_creature_weight(const struct Thing* creatng)
{
struct CreatureControl* cctrl = creature_control_get_from_thing(creatng);
struct CreatureModelConfig* crconf;
long weight;
if (!creature_control_invalid(cctrl))
{
struct CreatureModelConfig* crconf = creature_stats_get_from_thing(creatng);
crconf = creature_stats_get_from_thing(creatng);
long eye_height = get_creature_eye_height(creatng);
long weight = eye_height >> 2;
weight = eye_height >> 2;
weight += (crconf->hunger_fill + crconf->lair_size + 1) * cctrl->exp_level;
if (creature_is_immune_to_spell_effect(creatng, CSAfF_Wind))
{
Expand All @@ -1220,6 +1222,32 @@ long compute_creature_weight(const struct Thing* creatng)
}
return weight;
}
else
{
if (thing_is_dead_creature(creatng))
{
crconf = creature_stats_get_from_thing(creatng);
weight = crconf->base_eye_height >> 2;
weight += (crconf->hunger_fill + crconf->lair_size + 1);
if (creature_is_immune_to_spell_effect(creatng, CSAfF_Wind))
{
weight = weight * 3 / 2;
}
if ((get_creature_model_flags(creatng) & CMF_Trembling) != 0)
{
weight = weight * 3 / 2;
}
if ((get_creature_model_flags(creatng) & CMF_IsDiptera) != 0)
{
weight = weight / 2;
}
if (crconf->can_go_locked_doors == true)
{
weight = weight / 10;
}
return weight;
}
}
return 0;
}

Expand Down