thing.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. /*
  2. A Thing is anything that "physically exists" in an Area, that is, a "level".
  3. */
  4. #include "thing.h"
  5. #include "area.h"
  6. #include "flags.h"
  7. #include "draw.h"
  8. #include "mem.h"
  9. #include "monolog.h"
  10. #include "thing_struct.h"
  11. #define THING_WALL_MASS INFINITY
  12. #define THING_ACTOR_MASS 1.0
  13. /** Gets the ID of the thing. Returns negative on error or for a
  14. thing that doesn't belong to an area yet.*/
  15. int thing_id(Thing * thing) {
  16. if (!thing) return -3;
  17. return thing->id;
  18. }
  19. /** Sets the ID of the thing. Returns negative on error or
  20. for a thing that doesn't belong to an area yet (as inicated by newid)
  21. */
  22. int thing_id_(Thing * thing, int newid) {
  23. if (!thing) return -3;
  24. return thing->id = newid;
  25. }
  26. /** Sets the z value of the Thing. This influences which layer it
  27. and, if set, it's Shape is in. Logically,
  28. there are 4 layers in every area, 2 bottom ones and 2 top ones.
  29. Layer 0 is for the floor or walls itself, layer 1 for things that
  30. are standing or lying on the floor, or for edges,
  31. layer 2 is for things on the "top floor", that is, another
  32. floor above the current one which may be used for bridges,
  33. overpasess, etc. Layer 3 is then for things standing
  34. or lying on that top layer.
  35. */
  36. Thing * thing_z_(Thing * self, int z) {
  37. if (!self) return NULL;
  38. self->z = z;
  39. if(self->hull) {
  40. bumphull_layers_(self->hull, 1 << z);
  41. }
  42. return self;
  43. }
  44. /** Sets an individual flag on the Thing. */
  45. int thing_setflag(Thing * self, int flag) {
  46. return flags_set(&self->flags, flag);
  47. }
  48. /** Unsets an individual flag on the Thing. */
  49. int thing_unsetflag(Thing * self, int flag) {
  50. register int wflags = self->flags;
  51. return flags_unset(&self->flags, flag);
  52. }
  53. /** Sets or unsets an individual flag on the Thing.
  54. If set is true the flag is set, if false it's unset. */
  55. int thing_flag_(Thing * self, int flag, int set) {
  56. return flags_put(&self->flags, flag, set);
  57. }
  58. /** Checks if an individual flag is set. */
  59. int thing_flag(Thing * self, int flag) {
  60. return flags_get(self->flags, flag);
  61. }
  62. /** Uninitializes a thing. */
  63. Thing * thing_done(Thing * self) {
  64. if(!self) return NULL;
  65. bumphull_free(self->hull);
  66. bumpbody_free(self->physical);
  67. self->physical= NULL;
  68. self->hull = NULL;
  69. self->area = NULL;
  70. self->z = -1;
  71. self->kind = THING_UNUSED;
  72. spritestate_done(&self->spritestate);
  73. return self;
  74. }
  75. /** Frees a thing. */
  76. Thing * thing_free(Thing * self) {
  77. thing_done(self);
  78. mem_free(self);
  79. return NULL;
  80. }
  81. /** Allocates a Thing. */
  82. Thing * thing_alloc() {
  83. return STRUCT_ALLOC(Thing);
  84. }
  85. /* Sets the sprite of a thing. */
  86. Sprite * thing_sprite_(Thing * thing, Sprite * sprite) {
  87. if (!thing) return NULL;
  88. return spritestate_sprite_(&thing->spritestate, sprite);
  89. }
  90. /* Gets the sprite of a thing. */
  91. Sprite * thing_sprite(Thing * thing) {
  92. if (!thing) return NULL;
  93. return spritestate_sprite(&thing->spritestate);
  94. }
  95. /* Sets the pose of the sprite state of a thing. The direction is
  96. kept the same as it was. */
  97. int thing_pose_(Thing * thing, int pose) {
  98. if (!thing) return -3;
  99. return spritestate_pose_(&thing->spritestate, pose);
  100. }
  101. /* Sets the direction of the sprite state of a thing. The pose is
  102. kept the same as it was. */
  103. int thing_direction_(Thing * thing, int direction) {
  104. if (!thing) return -3;
  105. return spritestate_direction_(&thing->spritestate, direction);
  106. }
  107. /** Generic initialization of a thing Initializes a Thing.
  108. Sets the given values and some flags. Links the Shape given
  109. to the Thing if shape is not NULL.
  110. Does NOT call area_addthing on the given area.
  111. Returns null if that failed, but does no cleanup. */
  112. Thing * thing_init_generic(Thing * self, Area * area, int id, int kind, int z,
  113. BumpBody * body, BumpHull * shape) {
  114. if(!self) return NULL;
  115. self->kind = kind;
  116. self->id = id;
  117. self->area = area;
  118. self->physical= body;
  119. self->hull = shape;
  120. self->flags = 0;
  121. thing_z_(self, z);
  122. spritestate_init(&self->spritestate, NULL, self);
  123. /* If the thing has a body and it is not static,
  124. assume it is owned by this thing and must be freed when calling
  125. thing_done.
  126. */
  127. bumpbody_data_(self->physical, self);
  128. return self;
  129. }
  130. /** Initializes a rectangular, static, non-rotating Thing. Uses the
  131. area's static body, and makes a new rectangular shape for it.
  132. Returns NULL on error. Uses the area's static body.
  133. thing_initstatic isn't needed since bump understands tile maps.
  134. */
  135. /** Initializes a rectangular, dynamic, non-rotating Thing, with mass 1
  136. and makes a new body and rectangular shape for it. Returns NULL on error.
  137. Uses the area's static body. */
  138. Thing * thing_init_dynamic(Thing * self, Area * area,
  139. int id, int kind, int x, int y, int z, int w, int h) {
  140. BumpBody * body = NULL;
  141. BumpHull * shape = NULL;
  142. BeVec pos , delta;
  143. BumpAABB bounds;
  144. if(!self) return NULL;
  145. if(!area) return NULL;
  146. pos = bevec(x, y);
  147. body = bumpbody_new(pos, 1.0);
  148. if(!body) goto out_of_memory;
  149. // dynamic things ARE positioned correctly and do not use an offset
  150. // the object's shape is locally around the body
  151. bounds = bumpaabb(x, y, w, h);
  152. delta = bevec0();
  153. shape = bumphull_newall(body, delta, bounds, 1 << z, kind);
  154. if(!shape) goto out_of_memory;
  155. return thing_init_generic(self, area, id, kind, z, body, shape);
  156. out_of_memory:
  157. bumpbody_free(body);
  158. thing_done(self);
  159. return NULL;
  160. }
  161. /** Allocates and initializes a new static Thing. Not needed anymore. */
  162. /* thing_newstatic */
  163. /** Allocates and initializes a new dynamic Thing. */
  164. Thing * thing_new_dynamic(Area * area,
  165. int id, int kind,
  166. int x, int y, int z, int w, int h) {
  167. Thing * self = thing_alloc();
  168. if(!thing_init_dynamic(self, area, id, kind, x, y, z, w, h)) {
  169. return thing_free(self);
  170. }
  171. return self;
  172. }
  173. /** Accessors for thing's properties, forwarded to the body
  174. of the thing. **/
  175. /** Position of the thing. */
  176. BeVec thing_p(Thing * self) {
  177. return bumpbody_p(self->physical);
  178. }
  179. /** Bounds box of the thing */
  180. BumpAABB thing_aabb(Thing *self) {
  181. return bumphull_aabb(self->hull);
  182. }
  183. /** Width of thing. */
  184. int thing_w(Thing * self) {
  185. return thing_aabb(self).hs.x * 2;
  186. }
  187. /** Height of thing. */
  188. int thing_h(Thing * self) {
  189. return thing_aabb(self).hs.y * 2;
  190. }
  191. /** Position X coordinates (top left). */
  192. int thing_x(Thing * self) {
  193. return thing_p(self).x - thing_aabb(self).hs.x ;
  194. }
  195. /** Position Y coordinates (top left). */
  196. int thing_y(Thing * self) {
  197. return thing_p(self).y - thing_aabb(self).hs.y ;
  198. }
  199. /** Position X coordinates (center). */
  200. int thing_cx(Thing * self) {
  201. return thing_p(self).x;
  202. }
  203. /** Position Y coordinates (center). */
  204. int thing_cy(Thing * self) {
  205. return thing_p(self).y;
  206. }
  207. /** Layer of thing. */
  208. int thing_z(Thing * self) {
  209. return self->z;
  210. }
  211. /** Velocity of the thing. */
  212. BeVec thing_v(Thing * self) {
  213. return bumpbody_v(self->physical);
  214. }
  215. /** Speed X coordinates. */
  216. int thing_vx(Thing * self) {
  217. return thing_v(self).x;
  218. }
  219. /** Speed Y coordinates. */
  220. int thing_vy(Thing * self) {
  221. return thing_v(self).y;
  222. }
  223. /** Set velocity. */
  224. void thing_v_(Thing * self, BeVec v) {
  225. bumpbody_v_(self->physical, v);
  226. }
  227. /** Set velocity by xy. */
  228. void thing_vxy_(Thing * self, int vx, int vy) {
  229. BeVec v = bevec(vx, vy);
  230. thing_v_(self, v);
  231. }
  232. /** Set x velocity only, leaving y unchanged . */
  233. void thing_vx_(Thing * self, int vx) {
  234. BeVec v = thing_v(self);
  235. v.x = vx;
  236. thing_v_(self, v);
  237. }
  238. /** Set y velocity only, leaving x unchanged . */
  239. void thing_vy_(Thing * self, int vy) {
  240. BeVec v = thing_v(self);
  241. v.y = vy;
  242. thing_v_(self, v);
  243. }
  244. /** Sets position of thing's body. */
  245. void thing_p_(Thing * self, BeVec p) {
  246. bumpbody_p_(self->physical, p);
  247. }
  248. /** Adds delta to the position of thing's body. */
  249. void thing_deltap(Thing * self, BeVec delta) {
  250. BeVec old = thing_p(self);
  251. thing_p_(self, bevec_add(old, delta));
  252. }
  253. /** Set position by xy. */
  254. void thing_pxy_(Thing * self, int x, int y) {
  255. BeVec p = bevec(x, y);
  256. thing_p_(self, p);
  257. }
  258. /** Set x velocity only, leaving y unchanged . */
  259. void thing_x_(Thing * self, int x) {
  260. BeVec p = thing_p(self);
  261. p.x = x;
  262. thing_p_(self, p);
  263. }
  264. /** Set x velocity only, leaving y unchanged . */
  265. void thing_y_(Thing * self, int y) {
  266. BeVec p = thing_p(self);
  267. p.y = y;
  268. thing_p_(self, p);
  269. }
  270. /** Applies a force on the center of gravity of the thing. */
  271. void thing_applyforce(Thing * thing, const BeVec f) {
  272. bumpbody_applyforce(thing->physical, f);
  273. }
  274. /** Applies an impulse on the center of gravity of the thing. */
  275. void thing_applyimpulse(Thing * thing, const BeVec f) {
  276. bumpbody_applyimpulse(thing->physical, f);
  277. }
  278. /* Resets the force on this thing to 0. */
  279. void thing_resetforces(Thing * thing) {
  280. bumpbody_resetforces(thing->physical);
  281. }
  282. /* Returns the position of self, works both for static and dynamic things.
  283. * Redundant but kept for backcompat.
  284. */
  285. BeVec thing_sdp(Thing * self) {
  286. return thing_p(self);
  287. }
  288. /* Draws a thing to the current active drawing target, corresponding
  289. to it's shape and kind and taking the camera into account. Useful for
  290. checking or debugging the physics. */
  291. void thing_draw(Thing * self, Camera * camera) {
  292. int cx ;
  293. int cy ;
  294. int drawx, x;
  295. int drawy, y;
  296. int w, h ;
  297. int sw, sh ;
  298. int sx, sy ;
  299. int t = 2;
  300. Color color;
  301. // don't draw null things.
  302. if(!self) return;
  303. cx = camera_at_x(camera);
  304. cy = camera_at_y(camera);
  305. w = self->size.x;
  306. h = self->size.y;
  307. if ((self->physical) && (self->hull)) {
  308. x = bumpbody_p(self->physical).x - bumphull_aabb(self->hull).hs.x;
  309. y = bumpbody_p(self->physical).y - bumphull_aabb(self->hull).hs.y;
  310. w = bumphull_aabb(self->hull).hs.x * 2;
  311. h = bumphull_aabb(self->hull).hs.y * 2;
  312. }
  313. color = color_rgba(0xee, 0x44, 0x00, 0x88);
  314. t = 8;
  315. /* Do not draw out of camera range. */
  316. if(!camera_cansee(camera, x, y, w, h)) {
  317. return;
  318. }
  319. drawx = x - cx;
  320. drawy = y - cy;
  321. /* Draw sprite if available... */
  322. if(spritestate_can_draw_p(&self->spritestate)) {
  323. BeVec spriteat = bevec(drawx, drawy);
  324. /* Draw elliptical shadow under sprite unless disabled */
  325. if (!(self->flags & THING_FLAGS_NO_SHADOW)) {
  326. color = color_rgbaf(0.0, 0.0, 0.0, 0.5);
  327. sx = drawx + w / 2;
  328. sy = drawy + ((4*h)/5);
  329. sw = (4 * w) / 11;
  330. sh = h / 3;
  331. al_draw_filled_ellipse(sx, sy, sw, sh, color);
  332. }
  333. spritestate_draw(&self->spritestate, &spriteat);
  334. } else {
  335. /* ... otherwise debug box to alert scripters of it's absence. */
  336. draw_box(drawx, drawy, w, h, color, t);
  337. }
  338. }
  339. /* Returns the direction the sprite of this thing is currently facing */
  340. int thing_direction(Thing * self) {
  341. if (!self) return SPRITE_NO_DIRECTION;
  342. return spritestate_direction(&self->spritestate);
  343. }
  344. /* Returns the pose of the sprite of this thing */
  345. int thing_pose(Thing * self) {
  346. if (!self) return SPRITE_STAND;
  347. return spritestate_pose(&self->spritestate);
  348. }
  349. /* Changes the pose to newpose but only if it's oldpose.
  350. * Returns negative if the pose wasn't changed. */
  351. int thing_poseifold_(Thing * self, int oldpose, int newpose) {
  352. if (thing_pose(self) == oldpose) {
  353. return thing_pose_(self, newpose);
  354. }
  355. return -1;
  356. }
  357. /* Updates the thing, especialy it's spite state direction and animation. */
  358. void thing_update(Thing * self, double dt) {
  359. /* Update the things layer if uit has no support under hit's feet and
  360. it's level is greater than 1 and it's flying. */
  361. if ((thing_z(self) > 1) && (self->hull)) {
  362. if(!bumphull_support(self->hull)) {
  363. /* No support, drop down. */
  364. thing_z_(self, 1);
  365. }
  366. }
  367. if(!flags_get(self->flags, THING_FLAGS_LOCK_DIRECTION)) {
  368. int newdir;
  369. BeVec vel = thing_v(self);
  370. double magnitude = bevec_length(vel);
  371. if (fabs(magnitude) > 0.00) {
  372. /* could change dir if moving. TODO: take the old direction into
  373. account for more control of facing when moving diagonally. */
  374. if (vel.x < -0.01) {
  375. newdir = SPRITE_WEST;
  376. } else if (vel.x > 0.01) {
  377. newdir = SPRITE_EAST;
  378. } else if (vel.y < -0.01) {
  379. newdir = SPRITE_NORTH;
  380. } else if (vel.y > 0.01) {
  381. newdir = SPRITE_SOUTH;
  382. } else { /* Not much motion, don't change dir */
  383. newdir = thing_direction(self);
  384. }
  385. /* Change direction. spritestate_pose will see if nothing changed and do nothing. in that case */
  386. thing_poseifold_(self, SPRITE_STAND, SPRITE_WALK);
  387. thing_direction_(self, newdir);
  388. } else {
  389. thing_poseifold_(self, SPRITE_WALK, SPRITE_STAND);
  390. /* This won't work on attacking, etc. */
  391. }
  392. } else {
  393. LOG("Thing direction locked!");
  394. }
  395. spritestate_update(&self->spritestate, dt);
  396. }
  397. /* Compares a thing with another, for drawing order. Things with low
  398. z come before those with high z, and with same z, low y comes before high y.
  399. qsort compatible. */
  400. int thing_compare_for_drawing(const void * p1, const void * p2) {
  401. Thing * self = *((Thing **) p1);
  402. Thing * other = *((Thing **) p2);
  403. BeVec pos1, pos2;
  404. if(!self) {
  405. if(!other) {
  406. return 0;
  407. }
  408. /* Sort nulls to the back. */
  409. return 1;
  410. }
  411. if(!self) return -1;
  412. /* Compare Z if no nulls. */
  413. if (self->z < other->z) return -1;
  414. if (self->z > other->z) return 1;
  415. pos1 = thing_sdp(self);
  416. pos2 = thing_sdp(other);
  417. /* compare y if z is equal */
  418. if ( pos1.y < pos2.y ) return -1;
  419. if ( pos1.y > pos2.y ) return 1;
  420. /* Compare by address or whatever*/
  421. if (((uintptr_t)p1) < ((uintptr_t)p2)) return -1;
  422. if (((uintptr_t)p1) > ((uintptr_t)p2)) return 1;
  423. if (((uintptr_t)p1) == ((uintptr_t)p2)) return 0;
  424. return 0;
  425. }
  426. /** Tints a layer in the sprite's state of this thing. */
  427. int thing_tint_layer(Thing * me, int layer_index, Color color) {
  428. if (!me) return -1;
  429. return spritestate_tint_layer(&me->spritestate, layer_index, color);
  430. }
  431. /** Hides or shows a layer in he sprite of this thing. */
  432. int thing_hide_layer(Thing * me, int layer, int hidden) {
  433. if (!me) return -1;
  434. return spritestate_set_layer_hidden(&me->spritestate, layer, hidden);
  435. }
  436. /** Returns true if the layer of the sprite is hidden false if not. */
  437. int thing_is_layer_hidden(Thing * me, int layer) {
  438. return spritestate_get_layer_hidden(&me->spritestate, layer);
  439. }
  440. /** Sets the loop mode of the given action of the thing. */
  441. int thing_set_action_loop(Thing * me, int action, int loopmode) {
  442. return spritestate_set_action_loop(&me->spritestate, action, loopmode);
  443. }
  444. /** Gets the loop mode of the given action of the thing. */
  445. int thing_get_action_loop(Thing * me, int action) {
  446. return spritestate_get_action_loop(&me->spritestate, action);
  447. }
  448. /** Checks if the given action is done in case of actions set to one-shot
  449. * loop mode only.
  450. */
  451. int thing_is_action_done(Thing * me, int action) {
  452. return spritestate_is_action_done(&me->spritestate, action);
  453. }
  454. /** Sets the loop mode for the given pose and direction of the thing. */
  455. int thing_set_pose_direction_loop
  456. (Thing * me, int pose, int direction, int loopmode) {
  457. return spritestate_set_pose_direction_loop(&me->spritestate, pose, direction, loopmode);
  458. }
  459. /** Gets the loop mode for the given pose and direction of the thing. */
  460. int thing_get_pose_direction_loop
  461. (Thing * me, int pose, int direction) {
  462. return spritestate_get_pose_direction_loop(&me->spritestate, pose, direction);
  463. }
  464. /** Sets a flag on the main hull of the Thing. */
  465. int thing_set_hull_flag(Thing * me, int flag) {
  466. if (!me) return 0;
  467. return bumphull_set_flag(me->hull, flag);
  468. }
  469. /** Unsets a flag for the main hull of the thing. */
  470. int thing_unset_hull_flag(Thing * me, int flag) {
  471. if (!me) return 0;
  472. return bumphull_unset_flag(me->hull, flag);
  473. }
  474. /** Sets all flags for the main hull of the thing. */
  475. int thing_hull_flags_(Thing * me, int flags) {
  476. if (!me) return 0;
  477. return bumphull_flags_(me->hull, flags);
  478. }
  479. /** Gets all flags for the main hull of the thing. */
  480. int thing_hull_flags(Thing * me) {
  481. if (!me) return 0;
  482. return bumphull_flags(me->hull);
  483. }
  484. /** Returns the group of the main hull of the thing. */
  485. int thing_hull_group(Thing * me) {
  486. if (!me) return -1;
  487. return bumphull_group(me->hull);
  488. }
  489. /** Sets the group of the main hull of the thing. */
  490. int thing_hull_group_(Thing * me, int group) {
  491. if (!me) return -1;
  492. return bumphull_group_(me->hull, group);
  493. }