• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JackAshwell11 / Hades / 13236983756

10 Feb 2025 08:53AM UTC coverage: 83.282% (-1.2%) from 84.528%
13236983756

Pull #276

github

web-flow
Merge 755765110 into c93eef42c
Pull Request #276: Implement a reinforcement learning AI agent to autonomously play the game

45 of 94 new or added lines in 8 files covered. (47.87%)

10 existing lines in 3 files now uncovered.

1360 of 1633 relevant lines covered (83.28%)

9765.5 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.56
/src/hades_extensions/src/ecs/systems/physics.cpp
1
// Related header
2
#include "ecs/systems/physics.hpp"
3

4
// Std headers
5
#include <algorithm>
6

7
// Local headers
8
#include "ecs/systems/attacks.hpp"
9
#include "ecs/systems/movements.hpp"
10
#include "ecs/systems/sprite.hpp"
11
#include "factories.hpp"
12

13
void PhysicsSystem::add_force(const GameObjectID game_object_id, const cpVect &force) const {
34✔
14
  cpBodyApplyForceAtLocalPoint(
63✔
15
      *get_registry()->get_component<KinematicComponent>(game_object_id)->body,
63✔
16
      cpvnormalize(force) * get_registry()->get_component<MovementForce>(game_object_id)->get_value(), cpvzero);
66✔
17
}
31✔
18

19
void PhysicsSystem::add_bullet(const std::pair<cpVect, cpVect> &bullet, const double damage,
11✔
20
                               const GameObjectType source_type) const {
21
  const auto bullet_id{get_registry()->create_game_object(GameObjectType::Bullet, get<0>(bullet),
22✔
22
                                                          get_factories().at(GameObjectType::Bullet)(0))};
22✔
23
  const auto damage_component{get_registry()->get_component<Damage>(bullet_id)};
11✔
24
  const auto kinematic_component{get_registry()->get_component<KinematicComponent>(bullet_id)};
11✔
25
  damage_component->add_to_max_value(damage - damage_component->get_value());
11✔
26
  damage_component->set_value(damage);
11✔
27
  cpShapeSetFilter(*kinematic_component->shape,
11✔
28
                   {static_cast<cpGroup>(source_type), static_cast<cpBitmask>(GameObjectType::Bullet),
11✔
29
                    ~static_cast<cpBitmask>(source_type)});
11✔
30
  cpBodySetVelocity(*kinematic_component->body, get<1>(bullet));
11✔
31
}
11✔
32

33
auto PhysicsSystem::get_nearest_item(const GameObjectID game_object_id) const -> GameObjectID {
5✔
34
  // Get the current position of the game object
35
  const cpVect &game_object_position{
36
      cpBodyGetPosition(*get_registry()->get_component<KinematicComponent>(game_object_id)->body)};
5✔
37

38
  // Collect all relevant game objects
39
  std::vector<std::pair<GameObjectID, cpFloat>> distances;
5✔
40
  for (const auto &[id, component_tuple] : get_registry()->find_components<KinematicComponent>()) {
27✔
41
    if (const auto kinematic_component{std::get<0>(component_tuple)};
11✔
42
        game_object_id != id && (cpShapeGetSensor(*kinematic_component->shape) != 0U) &&
6✔
43
        get_registry()->get_game_object_type(id) != GameObjectType::Floor && !kinematic_component->collected) {
17✔
44
      if (const cpFloat distance{
6✔
45
              cpvlength(cpvsub(game_object_position, cpBodyGetPosition(*kinematic_component->body)))};
6✔
46
          distance <= SPRITE_SIZE / 2) {
6✔
47
        distances.emplace_back(id, distance);
4✔
48
      }
49
    }
11✔
50
  }
11✔
51

52
  // Return the nearest game object, otherwise, return -1
53
  const auto nearest_element{std::ranges::min_element(
5✔
54
      distances.begin(), distances.end(), [](const auto &lhs, const auto &rhs) { return lhs.second < rhs.second; })};
1✔
55
  return nearest_element != distances.end() ? nearest_element->first : -1;
10✔
56
}
5✔
57

NEW
58
auto PhysicsSystem::get_wall_distances(const cpVect &current_position) const -> std::vector<cpVect> {
×
NEW
59
  const auto space{get_registry()->get_space()};
×
NEW
60
  auto raycast{[&space, &current_position](const cpVect direction) -> cpVect {
×
61
    // Calculate the end position of the ray based on the direction
NEW
62
    const auto end_position{current_position + cpvnormalize(direction) * 30 * SPRITE_SIZE};
×
63

64
    // Perform the raycast
65
    cpSegmentQueryInfo info;
NEW
66
    if (cpSpaceSegmentQueryFirst(space, current_position, end_position, SPRITE_SIZE / 4,
×
67
                                 {CP_NO_GROUP, CP_ALL_CATEGORIES, static_cast<cpBitmask>(GameObjectType::Wall)},
NEW
68
                                 &info) != nullptr) {
×
NEW
69
      return info.point;
×
70
    }
NEW
71
    return cpvzero;
×
NEW
72
  }};
×
73

74
  // Perform raycasts in all directions
NEW
75
  return {raycast({0, 1}), raycast({1, 0}),  raycast({0, -1}), raycast({-1, 0}),
×
NEW
76
          raycast({1, 1}), raycast({1, -1}), raycast({-1, 1}), raycast({-1, -1})};
×
77
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc