1 #include <shadowdive/rgba_image.h>
2 #include "game/protos/intersect.h"
3 #include "utils/log.h"
4
intersect_object_object(object * a,object * b)5 int intersect_object_object(object *a, object *b) {
6 if(a->cur_sprite == NULL || b->cur_sprite == NULL) return 0;
7 vec2i pos_a = vec2i_add(object_get_pos(a), a->cur_sprite->pos);
8 vec2i pos_b = vec2i_add(object_get_pos(b), b->cur_sprite->pos);
9 vec2i size_a = object_get_size(a);
10 vec2i size_b = object_get_size(b);
11 return !(
12 pos_a.x > (pos_b.x + size_b.x) ||
13 pos_a.y > (pos_b.y + size_b.y) ||
14 (pos_a.x + size_a.x) < pos_b.x ||
15 (pos_a.y + size_a.y) < pos_b.y);
16 }
17
intersect_object_point(object * obj,vec2i point)18 int intersect_object_point(object *obj, vec2i point) {
19 if(obj->cur_sprite == NULL) return 0;
20 vec2i pos = vec2i_add(object_get_pos(obj), obj->cur_sprite->pos);
21 vec2i size = object_get_size(obj);
22 return (
23 point.x < (pos.x + size.x) &&
24 point.y < (pos.y + size.y) &&
25 point.x > pos.x &&
26 point.y > pos.y);
27 }
28
29
intersect_sprite_hitpoint(object * obj,object * target,int level,vec2i * point)30 int intersect_sprite_hitpoint(object *obj, object *target, int level, vec2i *point) {
31 // Make sure both objects have sprites going
32 if(obj->cur_sprite == NULL || target->cur_sprite == NULL) {
33 return 0;
34 }
35 // Make sure there are hitpoints to check.
36 if(vector_size(&obj->cur_animation->collision_coords) == 0) {
37 return 0;
38 }
39
40 int object_dir = OBJECT_FACE_RIGHT;
41 int target_dir = OBJECT_FACE_RIGHT;
42
43 // Some useful variables
44 vec2i pos_a = vec2i_add(object_get_pos(obj), obj->cur_sprite->pos);
45 vec2i pos_b = vec2i_add(object_get_pos(target), target->cur_sprite->pos);
46 vec2i size_a = object_get_size(obj);
47 vec2i size_b = object_get_size(target);
48
49 if ((object_get_direction(obj) == OBJECT_FACE_LEFT && !player_frame_isset(obj, "r")) ||
50 (object_get_direction(obj) == OBJECT_FACE_RIGHT && player_frame_isset(obj, "r"))) {
51 object_dir = OBJECT_FACE_LEFT;
52 pos_a.x = object_get_pos(obj).x + ((obj->cur_sprite->pos.x * -1) - size_a.x);
53 }
54
55 if ((object_get_direction(target) == OBJECT_FACE_LEFT && !player_frame_isset(target, "r")) ||
56 (object_get_direction(target) == OBJECT_FACE_RIGHT && player_frame_isset(target, "r"))) {
57 target_dir = OBJECT_FACE_LEFT;
58 pos_b.x = object_get_pos(target).x + ((target->cur_sprite->pos.x * -1) - size_b.x);
59 }
60
61
62 // Iterate through hitpoints
63 vec2i hcoords[level];
64 int found = 0;
65 iterator it;
66 collision_coord *cc;
67 vector_iter_begin(&obj->cur_animation->collision_coords, &it);
68 while((cc = iter_next(&it)) != NULL) {
69 // Skip coords that don't belong to the frame we are checking
70 if(cc->frame_index != obj->cur_sprite->id) continue;
71
72 // Convert coords to target sprite local space
73 int t = (object_dir == OBJECT_FACE_RIGHT)
74 ? (pos_a.x + cc->pos.x - obj->cur_sprite->pos.x)
75 : (pos_a.x + (size_a.x - cc->pos.x) + obj->cur_sprite->pos.x);
76
77 // convert global coordinates to local coordinates by compensating for the other player's position
78 int xcoord = t - pos_b.x;
79 // Also note that the hit pixel position during jumps is innacurate because hacks
80 int ycoord = (pos_a.y + size_a.y + cc->pos.y) - pos_b.y;
81
82 ycoord -= (obj->cur_sprite->pos.y + size_a.y);
83
84 // Make sure that the hitpixel is within the area of the target sprite
85 if(xcoord < 0 || xcoord >= size_b.x) continue;
86 if(ycoord < 0 || ycoord >= size_b.y) continue;
87
88 // Get hitpixel
89 surface *sfc = target->cur_sprite->data;
90 int hitpoint = (ycoord * sfc->w) + xcoord;
91 if (target_dir == OBJECT_FACE_LEFT) {
92 hitpoint = (ycoord * sfc->w) + (sfc->w - xcoord);
93 }
94 if(sfc->stencil[hitpoint] > 0) {
95 hcoords[found++] = vec2i_create(xcoord, ycoord);
96 if(found >= level) {
97 vec2f sum = vec2f_create(0,0);
98 for(int k = 0; k < level; k++) {
99 sum.x += hcoords[k].x;
100 sum.y += hcoords[k].y;
101 }
102 point->x = (sum.x / level) + pos_b.x;
103 point->y = (sum.y / level) + pos_b.y;
104 return 1;
105 }
106 }
107 }
108
109 return 0;
110 }
111