constants.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. /**
  2. @file constants.h
  3. This file contains definitions of game constants that are not considered
  4. part of game settings and whose change can ffect the game balance and
  5. playability, e.g. physics constants.
  6. by Miloslav Ciz (drummyfish), 2019
  7. Released under CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0/)
  8. plus a waiver of all other intellectual property. The goal of this work is to
  9. be and remain completely in the public domain forever, available for any use
  10. whatsoever.
  11. */
  12. #ifndef _SFG_CONSTANTS_H
  13. #define _SFG_CONSTANTS_H
  14. /**
  15. How quickly player moves, in squares per second.
  16. */
  17. #define SFG_PLAYER_MOVE_SPEED 7
  18. /**
  19. Gravity acceleration in squares / (second^2).
  20. */
  21. #define SFG_GRAVITY_ACCELERATION 30
  22. /**
  23. Initial upwards speed of player's jump, in squares per second.
  24. */
  25. #define SFG_PLAYER_JUMP_SPEED 5
  26. /**
  27. Melee and close-up attack range, in RCL_Units.
  28. */
  29. #define SFG_MELEE_RANGE 1600
  30. /**
  31. When a projectile is shot, it'll be offset by this distance (in RCL_Units)
  32. from the shooter.
  33. */
  34. #define SFG_PROJECTILE_SPAWN_OFFSET 256
  35. /**
  36. Player's melee hit range, in RCL_Units (RCL_UNITS_PER_SQUARE means full angle,
  37. 180 degrees to both sides).
  38. */
  39. #define SFG_PLAYER_MELEE_ANGLE 512
  40. /**
  41. How quickly elevators and squeezers move, in RCL_Unit per second.
  42. */
  43. #define SFG_MOVING_WALL_SPEED 1024
  44. /**
  45. How quickly doors open and close, in RCL_Unit per second.
  46. */
  47. #define SFG_DOOR_OPEN_SPEED 2048
  48. /**
  49. Helper special state value.
  50. */
  51. #define SFG_CANT_SAVE 255
  52. /**
  53. Says the distance in RCL_Units at which level elements (items, monsters etc.)
  54. are active.
  55. */
  56. #define SFG_LEVEL_ELEMENT_ACTIVE_DISTANCE (12 * 1024)
  57. /**
  58. Rate at which AI will be updated, which also affects how fast enemies will
  59. appear.
  60. */
  61. #define SFG_AI_FPS 4
  62. /**
  63. Says a probability (0 - 255) of the AI changing its state during one update
  64. step.
  65. */
  66. #define SFG_AI_RANDOM_CHANGE_PROBABILITY 40
  67. /**
  68. Distance at which level elements (sprites) collide, in RCL_Unit (1024 per
  69. square).
  70. */
  71. #define SFG_ELEMENT_COLLISION_RADIUS 1800
  72. /**
  73. Height, in RCL_Units, at which collisions happen with level elements
  74. (sprites).
  75. */
  76. #define SFG_ELEMENT_COLLISION_HEIGHT 1024
  77. /**
  78. Distance at which explosion does damage and throws away the player, in
  79. RCL_Units. Should be higher than SFG_ELEMENT_COLLISION_RADIUS so that
  80. exploded rockets also hurt the target.
  81. */
  82. #define SFG_EXPLOSION_RADIUS 2000
  83. /**
  84. Distance in RCL_Units which the player is pushed away by an explosion. Watch
  85. out, a slightly higher value can make player go through walls. Rather keep
  86. this under RCL_UNITS_PER_SQUARE;
  87. */
  88. #define SFG_EXPLOSION_PUSH_AWAY_DISTANCE 1023
  89. /**
  90. How much damage triggers a barrel explosion.
  91. */
  92. #define SFG_BARREL_EXPLOSION_DAMAGE_THRESHOLD 3
  93. /**
  94. Maximum player health.
  95. */
  96. #define SFG_PLAYER_MAX_HEALTH 125
  97. /**
  98. Start health of player.
  99. */
  100. #define SFG_PLAYER_START_HEALTH 100
  101. /**
  102. At which value health indicator shows a warning (red color).
  103. */
  104. #define SFG_PLAYER_HEALTH_WARNING_LEVEL 20
  105. /**
  106. Amount of health that is increased by taking a health kit.
  107. */
  108. #define SFG_HEALTH_KIT_VALUE 20
  109. /**
  110. How much randomness (positive and negative) will be added to damage
  111. (e.g. by weapons, explosions, ...). This constant is is 0 to 255, 255 meaning
  112. 100% of the base value.
  113. */
  114. #define SFG_DAMAGE_RANDOMNESS 64
  115. /**
  116. Height of monster collision BBox in RCL_Units.
  117. */
  118. #define SFG_MONSTER_COLLISION_HEIGHT 1024
  119. /**
  120. Specifies key repeat delay, in ms.
  121. */
  122. #define SFG_KEY_REPEAT_DELAY 500
  123. /**
  124. Specifies key repeat period, in ms.
  125. */
  126. #define SFG_KEY_REPEAT_PERIOD 150
  127. /**
  128. Angle in which multiple projectiles are spread, RCL_Units.
  129. */
  130. #define SFG_PROJECTILE_SPREAD_ANGLE 100
  131. #define SFG_MAX_MONSTERS 64
  132. #define SFG_MAX_PROJECTILES 12
  133. #define SFG_MAX_DOORS 32
  134. #define SFG_AMMO_BULLETS 0
  135. #define SFG_AMMO_ROCKETS 1
  136. #define SFG_AMMO_PLASMA 2
  137. #define SFG_AMMO_TOTAL 3
  138. #define SFG_AMMO_NONE SFG_AMMO_TOTAL
  139. #define SFG_AMMO_INCREASE_BULLETS 10
  140. #define SFG_AMMO_INCREASE_ROCKETS 5
  141. #define SFG_AMMO_INCREASE_PLASMA 8
  142. #define SFG_AMMO_MAX_BULLETS 200
  143. #define SFG_AMMO_MAX_ROCKETS 100
  144. #define SFG_AMMO_MAX_PLASMA 150
  145. /**
  146. Duration of story text (intro/outro) in ms.
  147. */
  148. #define SFG_STORYTEXT_DURATION 15000
  149. /**
  150. Time in ms of the player death animation.
  151. */
  152. #define SFG_LOSE_ANIMATION_DURATION 2000
  153. /**
  154. Time in ms of the level win animation.
  155. */
  156. #define SFG_WIN_ANIMATION_DURATION 2500
  157. /**
  158. Time in ms of the level start stage.
  159. */
  160. #define SFG_LEVEL_START_DURATION 1500
  161. /**
  162. Vertical sprite size, in RCL_Units.
  163. */
  164. #define SFG_BASE_SPRITE_SIZE RCL_UNITS_PER_SQUARE
  165. /**
  166. Default value of the settings byte.
  167. */
  168. #define SFG_DEFAULT_SETTINGS 0x03
  169. // -----------------------------------------------------------------------------
  170. // derived constants
  171. #define SFG_GAME_RESOLUTION_X \
  172. (SFG_SCREEN_RESOLUTION_X / SFG_RESOLUTION_SCALEDOWN)
  173. #define SFG_GAME_RESOLUTION_Y \
  174. (SFG_SCREEN_RESOLUTION_Y / SFG_RESOLUTION_SCALEDOWN)
  175. #define SFG_MS_PER_FRAME (1000 / SFG_FPS) // ms per frame with target FPS
  176. #if SFG_MS_PER_FRAME == 0
  177. #undef SFG_MS_PER_FRAME
  178. #define SFG_MS_PER_FRAME 1
  179. #endif
  180. #define SFG_KEY_REPEAT_DELAY_FRAMES \
  181. (SFG_KEY_REPEAT_DELAY / SFG_MS_PER_FRAME)
  182. #if SFG_KEY_REPEAT_DELAY_FRAMES == 0
  183. #undef SFG_KEY_REPEAT_DELAY_FRAMES
  184. #define SFG_KEY_REPEAT_DELAY_FRAMES 1
  185. #endif
  186. #define SFG_KEY_REPEAT_PERIOD_FRAMES \
  187. (SFG_KEY_REPEAT_PERIOD / SFG_MS_PER_FRAME)
  188. #if SFG_KEY_REPEAT_PERIOD_FRAMES == 0
  189. #undef SFG_KEY_REPEAT_PERIOD_FRAMES
  190. #define SFG_KEY_REPEAT_PERIOD_FRAMES 1
  191. #endif
  192. #define SFG_WEAPON_IMAGE_SCALE \
  193. (SFG_GAME_RESOLUTION_X / (SFG_TEXTURE_SIZE * 5))
  194. #if SFG_WEAPON_IMAGE_SCALE == 0
  195. #undef SFG_WEAPON_IMAGE_SCALE
  196. #define SFG_WEAPON_IMAGE_SCALE 1
  197. #endif
  198. #define SFG_WEAPONBOB_OFFSET_PIXELS \
  199. (SFG_WEAPONBOB_OFFSET * SFG_WEAPON_IMAGE_SCALE)
  200. #define SFG_WEAPON_IMAGE_POSITION_X \
  201. (SFG_GAME_RESOLUTION_X / 2 - (SFG_WEAPON_IMAGE_SCALE * SFG_TEXTURE_SIZE) / 2)
  202. #if SFG_GAME_RESOLUTION_Y > 70
  203. #define SFG_WEAPON_IMAGE_POSITION_Y \
  204. (SFG_GAME_RESOLUTION_Y - (SFG_WEAPON_IMAGE_SCALE * SFG_TEXTURE_SIZE))
  205. #elif SFG_GAME_RESOLUTION_Y > 50
  206. #define SFG_WEAPON_IMAGE_POSITION_Y (SFG_GAME_RESOLUTION_Y \
  207. - ((SFG_WEAPON_IMAGE_SCALE * 3 * SFG_TEXTURE_SIZE) / 4))
  208. #else
  209. #define SFG_WEAPON_IMAGE_POSITION_Y \
  210. (SFG_GAME_RESOLUTION_Y - SFG_TEXTURE_SIZE / 2)
  211. #endif
  212. #define SFG_PLAYER_TURN_UNITS_PER_FRAME \
  213. ((SFG_PLAYER_TURN_SPEED * RCL_UNITS_PER_SQUARE) / (360 * SFG_FPS))
  214. #if SFG_PLAYER_TURN_UNITS_PER_FRAME == 0
  215. #undef SFG_PLAYER_TURN_UNITS_PER_FRAME
  216. #define SFG_PLAYER_TURN_UNITS_PER_FRAME 1
  217. #endif
  218. #define SFG_PLAYER_MOVE_UNITS_PER_FRAME \
  219. ((SFG_PLAYER_MOVE_SPEED * RCL_UNITS_PER_SQUARE) / SFG_FPS)
  220. #if SFG_PLAYER_MOVE_UNITS_PER_FRAME == 0
  221. #undef SFG_PLAYER_MOVE_UNITS_PER_FRAME
  222. #define SFG_PLAYER_MOVE_UNITS_PER_FRAME 1
  223. #endif
  224. #define SFG_GRAVITY_SPEED_INCREASE_PER_FRAME \
  225. ((SFG_GRAVITY_ACCELERATION * RCL_UNITS_PER_SQUARE) / (SFG_FPS * SFG_FPS))
  226. #if SFG_GRAVITY_SPEED_INCREASE_PER_FRAME == 0
  227. #undef SFG_GRAVITY_SPEED_INCREASE_PER_FRAME
  228. #define SFG_GRAVITY_SPEED_INCREASE_PER_FRAME 1
  229. #endif
  230. #define SFG_PLAYER_JUMP_OFFSET_PER_FRAME \
  231. (((SFG_PLAYER_JUMP_SPEED * RCL_UNITS_PER_SQUARE) / SFG_FPS) \
  232. - SFG_GRAVITY_SPEED_INCREASE_PER_FRAME / 2)
  233. /* ^ This subtraction corrects the initial veloc. so that the numeric curve
  234. copies the analytical (smooth) curve. Without it the numeric curve goes
  235. ABOVE and makes player jump higher with lower FPS. To make sense of this
  236. try to solve the differential equation and plot it. */
  237. #if SFG_PLAYER_JUMP_OFFSET_PER_FRAME == 0
  238. #undef SFG_PLAYER_JUMP_OFFSET_PER_FRAME
  239. #define SFG_PLAYER_JUMP_OFFSET_PER_FRAME 1
  240. #endif
  241. #define SFG_HEADBOB_FRAME_INCREASE_PER_FRAME \
  242. (SFG_HEADBOB_SPEED / SFG_FPS)
  243. #if SFG_HEADBOB_FRAME_INCREASE_PER_FRAME == 0
  244. #undef SFG_HEADBOB_FRAME_INCREASE_PER_FRAME
  245. #define SFG_HEADBOB_FRAME_INCREASE_PER_FRAME 1
  246. #endif
  247. #define SFG_HEADBOB_ENABLED (SFG_HEADBOB_SPEED > 0 && SFG_HEADBOB_OFFSET > 0)
  248. #define SFG_CAMERA_SHEAR_STEP_PER_FRAME \
  249. ((SFG_GAME_RESOLUTION_Y * SFG_CAMERA_SHEAR_SPEED) / SFG_FPS)
  250. #if SFG_CAMERA_SHEAR_STEP_PER_FRAME == 0
  251. #undef SFG_CAMERA_SHEAR_STEP_PER_FRAME
  252. #define SFG_CAMERA_SHEAR_STEP_PER_FRAME 1
  253. #endif
  254. #define SFG_CAMERA_MAX_SHEAR_PIXELS \
  255. ((SFG_CAMERA_MAX_SHEAR * SFG_GAME_RESOLUTION_Y) / 1024)
  256. #define SFG_FONT_SIZE_SMALL \
  257. (SFG_GAME_RESOLUTION_X / (SFG_FONT_CHARACTER_SIZE * 50))
  258. #if SFG_FONT_SIZE_SMALL == 0
  259. #undef SFG_FONT_SIZE_SMALL
  260. #define SFG_FONT_SIZE_SMALL 1
  261. #endif
  262. #define SFG_FONT_SIZE_MEDIUM \
  263. (SFG_GAME_RESOLUTION_X / (SFG_FONT_CHARACTER_SIZE * 30))
  264. #if SFG_FONT_SIZE_MEDIUM == 0
  265. #undef SFG_FONT_SIZE_MEDIUM
  266. #define SFG_FONT_SIZE_MEDIUM 1
  267. #endif
  268. #define SFG_FONT_SIZE_BIG \
  269. (SFG_GAME_RESOLUTION_X / (SFG_FONT_CHARACTER_SIZE * 18))
  270. #if SFG_FONT_SIZE_BIG == 0
  271. #undef SFG_FONT_SIZE_BIG
  272. #define SFG_FONT_SIZE_BIG 1
  273. #endif
  274. #define SFG_Z_BUFFER_SIZE SFG_GAME_RESOLUTION_X
  275. /**
  276. Step in which walls get higher, in raycastlib units.
  277. */
  278. #define SFG_WALL_HEIGHT_STEP (RCL_UNITS_PER_SQUARE / 4)
  279. #define SFG_CEILING_MAX_HEIGHT\
  280. (16 * RCL_UNITS_PER_SQUARE - RCL_UNITS_PER_SQUARE / 2 )
  281. #define SFG_DOOR_UP_DOWN_MASK 0x20
  282. #define SFG_DOOR_LOCK(doorRecord) ((doorRecord) >> 6)
  283. #define SFG_DOOR_VERTICAL_POSITION_MASK 0x1f
  284. #define SFG_DOOR_HEIGHT_STEP (RCL_UNITS_PER_SQUARE / 0x1f)
  285. #define SFG_DOOR_INCREMENT_PER_FRAME \
  286. (SFG_DOOR_OPEN_SPEED / (SFG_DOOR_HEIGHT_STEP * SFG_FPS))
  287. #if SFG_DOOR_INCREMENT_PER_FRAME == 0
  288. #undef SFG_DOOR_INCREMENT_PER_FRAME
  289. #define SFG_DOOR_INCREMENT_PER_FRAME 1
  290. #endif
  291. #define SFG_MAX_ITEMS SFG_MAX_LEVEL_ELEMENTS
  292. #define SFG_MAX_SPRITE_SIZE SFG_GAME_RESOLUTION_X
  293. #define SFG_MAP_PIXEL_SIZE (SFG_GAME_RESOLUTION_Y / SFG_MAP_SIZE)
  294. #if SFG_MAP_PIXEL_SIZE == 0
  295. #undef SFG_MAP_PIXEL_SIZE
  296. #define SFG_MAP_PIXEL_SIZE 1
  297. #endif
  298. #define SFG_AI_UPDATE_FRAME_INTERVAL \
  299. (SFG_FPS / SFG_AI_FPS)
  300. #if SFG_AI_UPDATE_FRAME_INTERVAL == 0
  301. #undef SFG_AI_UPDATE_FRAME_INTERVAL
  302. #define SFG_AI_UPDATE_FRAME_INTERVAL 1
  303. #endif
  304. #define SFG_SPRITE_ANIMATION_FRAME_DURATION \
  305. (SFG_FPS / SFG_SPRITE_ANIMATION_SPEED)
  306. #if SFG_SPRITE_ANIMATION_FRAME_DURATION == 0
  307. #undef SFG_SPRITE_ANIMATION_FRAME_DURATION
  308. #define SFG_SPRITE_ANIMATION_FRAME_DURATION 1
  309. #endif
  310. #define SFG_HUD_MARGIN (SFG_GAME_RESOLUTION_X / 40)
  311. #define SFG_HUD_BORDER_INDICATOR_WIDTH_PIXELS \
  312. (SFG_GAME_RESOLUTION_Y / SFG_HUD_BORDER_INDICATOR_WIDTH)
  313. #define SFG_HUD_BORDER_INDICATOR_DURATION_FRAMES \
  314. (SFG_HUD_BORDER_INDICATOR_DURATION / SFG_MS_PER_FRAME)
  315. #if SFG_HUD_BORDER_INDICATOR_DURATION_FRAMES == 0
  316. #define SFG_HUD_BORDER_INDICATOR_DURATION_FRAMES 1
  317. #endif
  318. #define SFG_BLINK_PERIOD_FRAMES (SFG_BLINK_PERIOD / SFG_MS_PER_FRAME)
  319. #define SFG_HUD_BAR_HEIGHT \
  320. (SFG_FONT_CHARACTER_SIZE * SFG_FONT_SIZE_MEDIUM + SFG_HUD_MARGIN * 2 + 1)
  321. // -----------------------------------------------------------------------------
  322. // monsters
  323. #define SFG_MONSTER_ATTACK_MELEE 0
  324. #define SFG_MONSTER_ATTACK_FIREBALL 1
  325. #define SFG_MONSTER_ATTACK_BULLET 2
  326. #define SFG_MONSTER_ATTACK_FIREBALL_BULLET 3
  327. #define SFG_MONSTER_ATTACK_PLASMA 4
  328. #define SFG_MONSTER_ATTACK_EXPLODE 5
  329. #define SFG_MONSTER_ATTACK_FIREBALL_PLASMA 6
  330. #define SFG_MONSTER_ATTRIBUTE(attackType,aggressivity0to255,health0to255,spriteSize0to3) \
  331. ((uint16_t) ( \
  332. attackType | \
  333. ((aggressivity0to255 / 8) << 3) | \
  334. (spriteSize0to3 << 8) | \
  335. ((health0to255 / 4) << 10)))
  336. #define SFG_GET_MONSTER_ATTACK_TYPE(monsterNumber) \
  337. (SFG_monsterAttributeTable[monsterNumber] & 0x0007)
  338. #define SFG_GET_MONSTER_AGGRESSIVITY(monsterNumber) \
  339. (((SFG_monsterAttributeTable[monsterNumber] >> 3) & 0x1F) * 8)
  340. #define SFG_GET_MONSTER_SPRITE_SIZE(monsterNumber) \
  341. ((SFG_monsterAttributeTable[monsterNumber] >> 8) & 0x03)
  342. #define SFG_GET_MONSTER_MAX_HEALTH(monsterNumber) \
  343. (((SFG_monsterAttributeTable[monsterNumber] >> 10) & 0x3F) * 4)
  344. /**
  345. Table of monster attributes, each as a 16bit word in format:
  346. MSB hhhhhhssaaaattt LSB
  347. ttt: attack type
  348. aaaaa: aggressivity (frequence of attacks), 0 to 31
  349. ss: sprite size
  350. hhhhhh: health, 0 to 63
  351. */
  352. uint16_t SFG_monsterAttributeTable[SFG_MONSTERS_TOTAL] =
  353. {
  354. /* spider */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_FIREBALL,40,61,2),
  355. /* destr. */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_FIREBALL_BULLET,90,170,3),
  356. /* warrior */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_MELEE,255,40,1),
  357. /* plasma */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_PLASMA,56,92,1),
  358. /* ender */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_FIREBALL_PLASMA,128,255,3),
  359. /* turret */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_BULLET,32,23,0),
  360. /* explod. */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_EXPLODE,255,36,1)
  361. };
  362. // -----------------------------------------------------------------------------
  363. // weapons and projectiles
  364. #define SFG_WEAPON_KNIFE 0
  365. #define SFG_WEAPON_SHOTGUN 1
  366. #define SFG_WEAPON_MACHINE_GUN 2
  367. #define SFG_WEAPON_ROCKET_LAUNCHER 3
  368. #define SFG_WEAPON_PLASMAGUN 4
  369. #define SFG_WEAPON_SOLUTION 5
  370. #define SFG_WEAPONS_TOTAL 6
  371. #define SFG_WEAPON_ATTRIBUTE(fireType,projectileCount,fireCooldownMs) \
  372. ((uint8_t) (fireType | ((projectileCount - 1) << 2) | ((fireCooldownMs / (SFG_MS_PER_FRAME * 16)) << 4)))
  373. #define SFG_GET_WEAPON_FIRE_TYPE(weaponNumber) \
  374. (SFG_weaponAttributeTable[weaponNumber] & 0x03)
  375. #define SFG_GET_WEAPON_FIRE_COOLDOWN_FRAMES(weaponNumber) \
  376. ((SFG_weaponAttributeTable[weaponNumber] >> 4) * 16)
  377. #define SFG_GET_WEAPON_PROJECTILE_COUNT(weaponNumber) \
  378. (((SFG_weaponAttributeTable[weaponNumber] >> 2) & 0x03) + 1)
  379. #define SFG_MIN_WEAPON_COOLDOWN_FRAMES 8
  380. #define SFG_WEAPON_FIRE_TYPE_MELEE 0
  381. #define SFG_WEAPON_FIRE_TYPE_BULLET 1
  382. #define SFG_WEAPON_FIRE_TYPE_FIREBALL 2
  383. #define SFG_WEAPON_FIRE_TYPE_PLASMA 3
  384. #define SFG_WEAPON_FIRE_TYPES_TOTAL 4
  385. /**
  386. Table of weapon attributes, each as a byte in format:
  387. MSB ccccnnff LSB
  388. ff: fire type
  389. nn: number of projectiles - 1
  390. cccc: fire cooldown in frames, i.e. time after which the next shot can be
  391. shot again, ccccc has to be multiplied by 16 to get the real value
  392. */
  393. static const uint8_t SFG_weaponAttributeTable[SFG_WEAPONS_TOTAL] =
  394. {
  395. /* knife */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_MELEE,1,650), // DPS: 6.2
  396. /* shotgun */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_BULLET,2,1250), // DPS: 12.8
  397. /* m. gun */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_BULLET,1,700), // DPS: 11.4
  398. /* r. laun. */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_FIREBALL,1,850), // DPS: 28.2
  399. /* plasma */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_PLASMA,1,550), // DPS: 32.7
  400. /* solution */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_PLASMA,4,1050) // DPS: 85.7
  401. };
  402. static const uint8_t SFG_attackDamageTable[SFG_WEAPON_FIRE_TYPES_TOTAL] =
  403. {
  404. /* melee */ 4,
  405. /* bullet */ 8,
  406. /* explostion (fireball) */ 24,
  407. /* plasma */ 18
  408. };
  409. #define SFG_PROJECTILE_EXPLOSION 0
  410. #define SFG_PROJECTILE_FIREBALL 1
  411. #define SFG_PROJECTILE_PLASMA 2
  412. #define SFG_PROJECTILE_DUST 3
  413. #define SFG_PROJECTILE_BULLET 4
  414. #define SFG_PROJECTILE_NONE 255
  415. #define SFG_PROJECTILES_TOTAL 5
  416. #define SFG_PROJECTILE_ATTRIBUTE(speedSquaresPerSec,timeToLiveMs) \
  417. ((uint8_t) \
  418. ((((speedSquaresPerSec / 4 == 0) && (speedSquaresPerSec != 0)) ? 1 : speedSquaresPerSec / 4) | \
  419. ((timeToLiveMs / (8 * SFG_MS_PER_FRAME)) << 3)))
  420. #define SFG_GET_PROJECTILE_SPEED_UPF(projectileNumber) \
  421. (((SFG_projectileAttributeTable[projectileNumber] & 0x07) * 4 * RCL_UNITS_PER_SQUARE) / SFG_FPS)
  422. #define SFG_GET_PROJECTILE_FRAMES_TO_LIVE(projectileNumber) \
  423. ((SFG_projectileAttributeTable[projectileNumber] >> 3) * 8)
  424. /**
  425. Table of projectile attributes, each as a byte in format:
  426. MSB lllllsss LSB
  427. fff: half speed in game squares per second
  428. lllll: eigth of frames to live
  429. */
  430. #define LOW_FPS (SFG_FPS < 24) ///< low FPS needs low speeds, because collisions
  431. static const uint8_t SFG_projectileAttributeTable[SFG_PROJECTILES_TOTAL] =
  432. {
  433. /* explosion */ SFG_PROJECTILE_ATTRIBUTE(0,400),
  434. /* fireball */ SFG_PROJECTILE_ATTRIBUTE(10,1000),
  435. #if LOW_FPS
  436. /* plasma */ SFG_PROJECTILE_ATTRIBUTE(17,500),
  437. #else
  438. /* plasma */ SFG_PROJECTILE_ATTRIBUTE(18,500),
  439. #endif
  440. /* dust */ SFG_PROJECTILE_ATTRIBUTE(0,450),
  441. #if LOW_FPS
  442. /* bullet */ SFG_PROJECTILE_ATTRIBUTE(17,1000)
  443. #else
  444. /* bullet */ SFG_PROJECTILE_ATTRIBUTE(28,1000)
  445. #endif
  446. };
  447. #undef LOW_FPS
  448. #endif // guard