Mirai's Miscellaneous Misadventures

M45 / core / effects.c

1/* license: AGPLv3 or later */
2/* copyright 2023 zamfofex */
3
4#include <mimimi.h>
5
6void mimimi_conveyor_tick(struct mimimi_conveyor *conveyor)
7{
8	struct mimimi_sprite *sprite;
9	struct mimimi_ground *ground;
10	unsigned char was_airborne;
11	int x1, x2, y;
12	
13	sprite = conveyor->sprite;
14	ground = conveyor->ground;
15	was_airborne = conveyor->was_airborne;
16	
17	conveyor->was_airborne = sprite->physics.airborne;
18	
19	if (sprite->physics.airborne != 0)
20	{
21		if (was_airborne == 0)
22			sprite->physics.dx += conveyor->speed;
23		return;
24	}
25	
26	x1 = (sprite->position.x - sprite->physics.width / 2) / 128;
27	x2 = (sprite->position.x + sprite->physics.width / 2) / 128;
28	y = (sprite->position.y + 64) / 128;
29	
30	if (mimimi_ground_tile(ground, x1, y) != 0 || mimimi_ground_tile(ground, x2, y) != 0)
31		sprite->position.x += conveyor->speed;
32}
33
34void mimimi_positioned_physics_tick(struct mimimi_positioned_physics *physics, struct mimimi_ground *ground)
35{
36	int dx, dy;
37	unsigned char was_airborne;
38	struct mimimi_position other_position;
39	unsigned char airborne;
40	
41	dx = physics->transform.x - physics->previous.x;
42	dy = physics->transform.y - physics->previous.y;
43	
44	physics->previous = physics->transform;
45	
46	was_airborne = physics->was_airborne;
47	physics->was_airborne = physics->other.airborne;
48	
49	airborne = physics->physics->airborne;
50	
51	physics->other.dx = physics->physics->dx;
52	physics->other.dy = physics->physics->dy;
53	physics->other.width = physics->physics->width;
54	physics->other.height = physics->physics->height;
55	
56	other_position = *physics->position;
57	other_position.x -= physics->transform.x;
58	other_position.y -= physics->transform.y;
59	
60	if (physics->other.airborne == 0)
61	{
62		other_position.x += dx;
63		other_position.y += dy;
64	}
65	
66	if (physics->physics->airborne != 0) physics->other.airborne = 1;
67	mimimi_collision_physics_tick(&physics->other, &other_position, ground);
68	if (physics->other.airborne == 0) physics->physics->airborne = 0;
69	
70	if (airborne == 0) return;
71	
72	other_position.x += physics->transform.x;
73	other_position.y += physics->transform.y;
74	
75	*physics->position = other_position;
76	
77	physics->physics->dx = physics->other.dx;
78	physics->physics->dy = physics->other.dy;
79	
80	if (physics->other.airborne != 0 && was_airborne == 0)
81	{
82		physics->physics->dx += dx;
83		physics->physics->dy += dy;
84	}
85}
86
87void mimimi_positioned_physics(struct mimimi_positioned_physics *physics, struct mimimi_physics *other, struct mimimi_position *position)
88{
89	mimimi_physics(&physics->other, 0, 0);
90	physics->physics = other;
91	physics->position = position;
92	physics->transform.x = 0;
93	physics->transform.y = 0;
94	physics->previous = *position;
95	physics->was_airborne = other->airborne;
96}
97
98void mimimi_trampoline_tick(struct mimimi_trampoline *trampoline)
99{
100	struct mimimi_sprite *sprite;
101	struct mimimi_ground *ground;
102	int dy;
103	int x1, x2, y;
104	
105	sprite = trampoline->sprite;
106	ground = trampoline->ground;
107	
108	dy = trampoline->dy;
109	trampoline->dy = 0;
110	
111	if (sprite->physics.airborne != 0)
112	{
113		trampoline->dy = sprite->physics.dy;
114		return;
115	}
116	
117	if (dy == 0) return;
118	
119	x1 = (sprite->position.x - sprite->physics.width / 2) / 128;
120	x2 = (sprite->position.x + sprite->physics.width / 2) / 128;
121	y = (sprite->position.y + 64) / 128;
122	
123	if (mimimi_ground_tile(ground, x1, y) != 0) return;
124	if (mimimi_ground_tile(ground, x2, y) != 0) return;
125	
126	sprite->physics.airborne = 1;
127	sprite->physics.dy -= dy * trampoline->restitution / 256;
128}