Update
[anarch.git] / constants.h
blob956baa03b14dfb4fff52e40269c564d2299943c8
1 /**
2 @file constants.h
4 This file contains definitions of game constants that are not considered
5 part of game settings and whose change can ffect the game balance and
6 playability, e.g. physics constants.
8 by Miloslav Ciz (drummyfish), 2019
10 Released under CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0/)
11 plus a waiver of all other intellectual property. The goal of this work is to
12 be and remain completely in the public domain forever, available for any use
13 whatsoever.
16 #ifndef _SFG_CONSTANTS_H
17 #define _SFG_CONSTANTS_H
19 /**
20 How quickly player moves, in squares per second.
22 #define SFG_PLAYER_MOVE_SPEED 7
24 /**
25 Gravity acceleration in squares / (second^2).
27 #define SFG_GRAVITY_ACCELERATION 30
29 /**
30 Initial upwards speed of player's jump, in squares per second.
32 #define SFG_PLAYER_JUMP_SPEED 5
34 /**
35 Melee and close-up attack range, in RCL_Units.
37 #define SFG_MELEE_RANGE 1600
39 /**
40 When a projectile is shot, it'll be offset by this distance (in RCL_Units)
41 from the shooter.
44 #define SFG_PROJECTILE_SPAWN_OFFSET 256
46 /**
47 Player's melee hit range, in RCL_Units (RCL_UNITS_PER_SQUARE means full angle,
48 180 degrees to both sides).
50 #define SFG_PLAYER_MELEE_ANGLE 512
52 /**
53 How quickly elevators and squeezers move, in RCL_Unit per second.
55 #define SFG_MOVING_WALL_SPEED 1024
57 /**
58 How quickly doors open and close, in RCL_Unit per second.
60 #define SFG_DOOR_OPEN_SPEED 2048
62 /**
63 Helper special state value.
65 #define SFG_CANT_SAVE 255
67 /**
68 Says the distance in RCL_Units at which level elements (items, monsters etc.)
69 are active.
71 #define SFG_LEVEL_ELEMENT_ACTIVE_DISTANCE (12 * 1024)
73 /**
74 Rate at which AI will be updated, which also affects how fast enemies will
75 appear.
77 #define SFG_AI_FPS 4
79 /**
80 Says a probability (0 - 255) of the AI changing its state during one update
81 step.
83 #define SFG_AI_RANDOM_CHANGE_PROBABILITY 40
85 /**
86 Distance at which level elements (sprites) collide, in RCL_Unit (1024 per
87 square).
89 #define SFG_ELEMENT_COLLISION_RADIUS 1800
91 /**
92 Height, in RCL_Units, at which collisions happen with level elements
93 (sprites).
95 #define SFG_ELEMENT_COLLISION_HEIGHT 1024
97 /**
98 Distance at which explosion does damage and throws away the player, in
99 RCL_Units. Should be higher than SFG_ELEMENT_COLLISION_RADIUS so that
100 exploded rockets also hurt the target.
102 #define SFG_EXPLOSION_RADIUS 2000
105 Distance in RCL_Units which the player is pushed away by an explosion. Watch
106 out, a slightly higher value can make player go through walls. Rather keep
107 this under RCL_UNITS_PER_SQUARE;
109 #define SFG_EXPLOSION_PUSH_AWAY_DISTANCE 1023
112 How much damage triggers a barrel explosion.
115 #define SFG_BARREL_EXPLOSION_DAMAGE_THRESHOLD 3
118 Maximum player health.
120 #define SFG_PLAYER_MAX_HEALTH 125
123 Start health of player.
125 #define SFG_PLAYER_START_HEALTH 100
128 At which value health indicator shows a warning (red color).
130 #define SFG_PLAYER_HEALTH_WARNING_LEVEL 20
133 Amount of health that is increased by taking a health kit.
135 #define SFG_HEALTH_KIT_VALUE 20
138 How much randomness (positive and negative) will be added to damage
139 (e.g. by weapons, explosions, ...). This constant is is 0 to 255, 255 meaning
140 100% of the base value.
142 #define SFG_DAMAGE_RANDOMNESS 64
145 Height of monster collision BBox in RCL_Units.
147 #define SFG_MONSTER_COLLISION_HEIGHT 1024
150 Specifies key repeat delay, in ms.
152 #define SFG_KEY_REPEAT_DELAY 500
155 Specifies key repeat period, in ms.
157 #define SFG_KEY_REPEAT_PERIOD 150
160 Angle in which multiple projectiles are spread, RCL_Units.
162 #define SFG_PROJECTILE_SPREAD_ANGLE 100
164 #define SFG_MAX_MONSTERS 64
166 #define SFG_MAX_PROJECTILES 12
168 #define SFG_MAX_DOORS 32
170 #define SFG_AMMO_BULLETS 0
171 #define SFG_AMMO_ROCKETS 1
172 #define SFG_AMMO_PLASMA 2
174 #define SFG_AMMO_TOTAL 3
176 #define SFG_AMMO_NONE SFG_AMMO_TOTAL
178 #define SFG_AMMO_INCREASE_BULLETS 10
179 #define SFG_AMMO_INCREASE_ROCKETS 5
180 #define SFG_AMMO_INCREASE_PLASMA 8
182 #define SFG_AMMO_MAX_BULLETS 200
183 #define SFG_AMMO_MAX_ROCKETS 100
184 #define SFG_AMMO_MAX_PLASMA 150
187 Duration of story text (intro/outro) in ms.
189 #define SFG_STORYTEXT_DURATION 15000
192 Time in ms of the player death animation.
194 #define SFG_LOSE_ANIMATION_DURATION 2000
197 Time in ms of the level win animation.
199 #define SFG_WIN_ANIMATION_DURATION 2500
202 Time in ms of the level start stage.
204 #define SFG_LEVEL_START_DURATION 1500
207 Vertical sprite size, in RCL_Units.
209 #define SFG_BASE_SPRITE_SIZE RCL_UNITS_PER_SQUARE
212 Default value of the settings byte.
214 #define SFG_DEFAULT_SETTINGS 0x03
216 // -----------------------------------------------------------------------------
217 // derived constants
219 #define SFG_GAME_RESOLUTION_X \
220 (SFG_SCREEN_RESOLUTION_X / SFG_RESOLUTION_SCALEDOWN)
222 #define SFG_GAME_RESOLUTION_Y \
223 (SFG_SCREEN_RESOLUTION_Y / SFG_RESOLUTION_SCALEDOWN)
225 #define SFG_MS_PER_FRAME (1000 / SFG_FPS) // ms per frame with target FPS
227 #if SFG_MS_PER_FRAME == 0
228 #undef SFG_MS_PER_FRAME
229 #define SFG_MS_PER_FRAME 1
230 #endif
232 #define SFG_KEY_REPEAT_DELAY_FRAMES \
233 (SFG_KEY_REPEAT_DELAY / SFG_MS_PER_FRAME)
235 #if SFG_KEY_REPEAT_DELAY_FRAMES == 0
236 #undef SFG_KEY_REPEAT_DELAY_FRAMES
237 #define SFG_KEY_REPEAT_DELAY_FRAMES 1
238 #endif
240 #define SFG_KEY_REPEAT_PERIOD_FRAMES \
241 (SFG_KEY_REPEAT_PERIOD / SFG_MS_PER_FRAME)
243 #if SFG_KEY_REPEAT_PERIOD_FRAMES == 0
244 #undef SFG_KEY_REPEAT_PERIOD_FRAMES
245 #define SFG_KEY_REPEAT_PERIOD_FRAMES 1
246 #endif
248 #define SFG_WEAPON_IMAGE_SCALE \
249 (SFG_GAME_RESOLUTION_X / (SFG_TEXTURE_SIZE * 5))
251 #if SFG_WEAPON_IMAGE_SCALE == 0
252 #undef SFG_WEAPON_IMAGE_SCALE
253 #define SFG_WEAPON_IMAGE_SCALE 1
254 #endif
256 #define SFG_WEAPONBOB_OFFSET_PIXELS \
257 (SFG_WEAPONBOB_OFFSET * SFG_WEAPON_IMAGE_SCALE)
259 #define SFG_WEAPON_IMAGE_POSITION_X \
260 (SFG_GAME_RESOLUTION_X / 2 - (SFG_WEAPON_IMAGE_SCALE * SFG_TEXTURE_SIZE) / 2)
262 #if SFG_GAME_RESOLUTION_Y > 70
263 #define SFG_WEAPON_IMAGE_POSITION_Y \
264 (SFG_GAME_RESOLUTION_Y - (SFG_WEAPON_IMAGE_SCALE * SFG_TEXTURE_SIZE))
265 #elif SFG_GAME_RESOLUTION_Y > 50
266 #define SFG_WEAPON_IMAGE_POSITION_Y (SFG_GAME_RESOLUTION_Y \
267 - ((SFG_WEAPON_IMAGE_SCALE * 3 * SFG_TEXTURE_SIZE) / 4))
268 #else
269 #define SFG_WEAPON_IMAGE_POSITION_Y \
270 (SFG_GAME_RESOLUTION_Y - SFG_TEXTURE_SIZE / 2)
271 #endif
273 #define SFG_PLAYER_TURN_UNITS_PER_FRAME \
274 ((SFG_PLAYER_TURN_SPEED * RCL_UNITS_PER_SQUARE) / (360 * SFG_FPS))
276 #if SFG_PLAYER_TURN_UNITS_PER_FRAME == 0
277 #undef SFG_PLAYER_TURN_UNITS_PER_FRAME
278 #define SFG_PLAYER_TURN_UNITS_PER_FRAME 1
279 #endif
281 #define SFG_PLAYER_MOVE_UNITS_PER_FRAME \
282 ((SFG_PLAYER_MOVE_SPEED * RCL_UNITS_PER_SQUARE) / SFG_FPS)
284 #if SFG_PLAYER_MOVE_UNITS_PER_FRAME == 0
285 #undef SFG_PLAYER_MOVE_UNITS_PER_FRAME
286 #define SFG_PLAYER_MOVE_UNITS_PER_FRAME 1
287 #endif
289 #define SFG_GRAVITY_SPEED_INCREASE_PER_FRAME \
290 ((SFG_GRAVITY_ACCELERATION * RCL_UNITS_PER_SQUARE) / (SFG_FPS * SFG_FPS))
292 #if SFG_GRAVITY_SPEED_INCREASE_PER_FRAME == 0
293 #undef SFG_GRAVITY_SPEED_INCREASE_PER_FRAME
294 #define SFG_GRAVITY_SPEED_INCREASE_PER_FRAME 1
295 #endif
297 #define SFG_PLAYER_JUMP_OFFSET_PER_FRAME \
298 (((SFG_PLAYER_JUMP_SPEED * RCL_UNITS_PER_SQUARE) / SFG_FPS) \
299 - SFG_GRAVITY_SPEED_INCREASE_PER_FRAME / 2)
300 /* ^ This substraction corrects the initial veloc. so that the numeric curve
301 copies the analytical (smooth) curve. Without it the numeric curve goes
302 ABOVE and makes player jump higher with lower FPS. To make sense of this
303 try to solve the differential equation and plot it. */
305 #if SFG_PLAYER_JUMP_OFFSET_PER_FRAME == 0
306 #undef SFG_PLAYER_JUMP_OFFSET_PER_FRAME
307 #define SFG_PLAYER_JUMP_OFFSET_PER_FRAME 1
308 #endif
310 #define SFG_HEADBOB_FRAME_INCREASE_PER_FRAME \
311 (SFG_HEADBOB_SPEED / SFG_FPS)
313 #if SFG_HEADBOB_FRAME_INCREASE_PER_FRAME == 0
314 #undef SFG_HEADBOB_FRAME_INCREASE_PER_FRAME
315 #define SFG_HEADBOB_FRAME_INCREASE_PER_FRAME 1
316 #endif
318 #define SFG_HEADBOB_ENABLED (SFG_HEADBOB_SPEED > 0 && SFG_HEADBOB_OFFSET > 0)
320 #define SFG_CAMERA_SHEAR_STEP_PER_FRAME \
321 ((SFG_GAME_RESOLUTION_Y * SFG_CAMERA_SHEAR_SPEED) / SFG_FPS)
323 #if SFG_CAMERA_SHEAR_STEP_PER_FRAME == 0
324 #undef SFG_CAMERA_SHEAR_STEP_PER_FRAME
325 #define SFG_CAMERA_SHEAR_STEP_PER_FRAME 1
326 #endif
328 #define SFG_CAMERA_MAX_SHEAR_PIXELS \
329 ((SFG_CAMERA_MAX_SHEAR * SFG_GAME_RESOLUTION_Y) / 1024)
331 #define SFG_FONT_SIZE_SMALL \
332 (SFG_GAME_RESOLUTION_X / (SFG_FONT_CHARACTER_SIZE * 50))
334 #if SFG_FONT_SIZE_SMALL == 0
335 #undef SFG_FONT_SIZE_SMALL
336 #define SFG_FONT_SIZE_SMALL 1
337 #endif
339 #define SFG_FONT_SIZE_MEDIUM \
340 (SFG_GAME_RESOLUTION_X / (SFG_FONT_CHARACTER_SIZE * 30))
342 #if SFG_FONT_SIZE_MEDIUM == 0
343 #undef SFG_FONT_SIZE_MEDIUM
344 #define SFG_FONT_SIZE_MEDIUM 1
345 #endif
347 #define SFG_FONT_SIZE_BIG \
348 (SFG_GAME_RESOLUTION_X / (SFG_FONT_CHARACTER_SIZE * 18))
350 #if SFG_FONT_SIZE_BIG == 0
351 #undef SFG_FONT_SIZE_BIG
352 #define SFG_FONT_SIZE_BIG 1
353 #endif
355 #define SFG_Z_BUFFER_SIZE SFG_GAME_RESOLUTION_X
358 Step in which walls get higher, in raycastlib units.
360 #define SFG_WALL_HEIGHT_STEP (RCL_UNITS_PER_SQUARE / 4)
362 #define SFG_CEILING_MAX_HEIGHT\
363 (16 * RCL_UNITS_PER_SQUARE - RCL_UNITS_PER_SQUARE / 2 )
365 #define SFG_DOOR_UP_DOWN_MASK 0x20
366 #define SFG_DOOR_LOCK(doorRecord) ((doorRecord) >> 6)
367 #define SFG_DOOR_VERTICAL_POSITION_MASK 0x1f
368 #define SFG_DOOR_HEIGHT_STEP (RCL_UNITS_PER_SQUARE / 0x1f)
370 #define SFG_DOOR_INCREMENT_PER_FRAME \
371 (SFG_DOOR_OPEN_SPEED / (SFG_DOOR_HEIGHT_STEP * SFG_FPS))
373 #if SFG_DOOR_INCREMENT_PER_FRAME == 0
374 #undef SFG_DOOR_INCREMENT_PER_FRAME
375 #define SFG_DOOR_INCREMENT_PER_FRAME 1
376 #endif
378 #define SFG_MAX_ITEMS SFG_MAX_LEVEL_ELEMENTS
380 #define SFG_MAX_SPRITE_SIZE SFG_GAME_RESOLUTION_X
382 #define SFG_MAP_PIXEL_SIZE (SFG_GAME_RESOLUTION_Y / SFG_MAP_SIZE)
384 #if SFG_MAP_PIXEL_SIZE == 0
385 #undef SFG_MAP_PIXEL_SIZE
386 #define SFG_MAP_PIXEL_SIZE 1
387 #endif
389 #define SFG_AI_UPDATE_FRAME_INTERVAL \
390 (SFG_FPS / SFG_AI_FPS)
392 #if SFG_AI_UPDATE_FRAME_INTERVAL == 0
393 #undef SFG_AI_UPDATE_FRAME_INTERVAL
394 #define SFG_AI_UPDATE_FRAME_INTERVAL 1
395 #endif
397 #define SFG_SPRITE_ANIMATION_FRAME_DURATION \
398 (SFG_FPS / SFG_SPRITE_ANIMATION_SPEED)
400 #if SFG_SPRITE_ANIMATION_FRAME_DURATION == 0
401 #undef SFG_SPRITE_ANIMATION_FRAME_DURATION
402 #define SFG_SPRITE_ANIMATION_FRAME_DURATION 1
403 #endif
405 #define SFG_HUD_MARGIN (SFG_GAME_RESOLUTION_X / 40)
407 #define SFG_HUD_BORDER_INDICATOR_WIDTH_PIXELS \
408 (SFG_GAME_RESOLUTION_Y / SFG_HUD_BORDER_INDICATOR_WIDTH)
410 #define SFG_HUD_BORDER_INDICATOR_DURATION_FRAMES \
411 (SFG_HUD_BORDER_INDICATOR_DURATION / SFG_MS_PER_FRAME)
413 #if SFG_HUD_BORDER_INDICATOR_DURATION_FRAMES == 0
414 #define SFG_HUD_BORDER_INDICATOR_DURATION_FRAMES 1
415 #endif
417 #define SFG_BLINK_PERIOD_FRAMES (SFG_BLINK_PERIOD / SFG_MS_PER_FRAME)
419 #define SFG_HUD_BAR_HEIGHT \
420 (SFG_FONT_CHARACTER_SIZE * SFG_FONT_SIZE_MEDIUM + SFG_HUD_MARGIN * 2 + 1)
422 // -----------------------------------------------------------------------------
423 // monsters
425 #define SFG_MONSTER_ATTACK_MELEE 0
426 #define SFG_MONSTER_ATTACK_FIREBALL 1
427 #define SFG_MONSTER_ATTACK_BULLET 2
428 #define SFG_MONSTER_ATTACK_FIREBALL_BULLET 3
429 #define SFG_MONSTER_ATTACK_PLASMA 4
430 #define SFG_MONSTER_ATTACK_EXPLODE 5
431 #define SFG_MONSTER_ATTACK_FIREBALL_PLASMA 6
433 #define SFG_MONSTER_ATTRIBUTE(attackType,aggressivity0to255,health0to255,spriteSize0to3) \
434 ((uint16_t) ( \
435 attackType | \
436 ((aggressivity0to255 / 8) << 3) | \
437 (spriteSize0to3 << 8) | \
438 ((health0to255 / 4) << 10)))
440 #define SFG_GET_MONSTER_ATTACK_TYPE(monsterNumber) \
441 (SFG_monsterAttributeTable[monsterNumber] & 0x0007)
443 #define SFG_GET_MONSTER_AGGRESSIVITY(monsterNumber) \
444 (((SFG_monsterAttributeTable[monsterNumber] >> 3) & 0x1F) * 8)
446 #define SFG_GET_MONSTER_SPRITE_SIZE(monsterNumber) \
447 ((SFG_monsterAttributeTable[monsterNumber] >> 8) & 0x03)
449 #define SFG_GET_MONSTER_MAX_HEALTH(monsterNumber) \
450 (((SFG_monsterAttributeTable[monsterNumber] >> 10) & 0x3F) * 4)
453 Table of monster attributes, each as a 16bit word in format:
455 MSB hhhhhhssaaaattt LSB
457 ttt: attack type
458 aaaaa: aggressivity (frequence of attacks), 0 to 31
459 ss: sprite size
460 hhhhhh: health, 0 to 63
462 uint16_t SFG_monsterAttributeTable[SFG_MONSTERS_TOTAL] =
464 /* spider */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_FIREBALL,40,61,2),
465 /* destr. */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_FIREBALL_BULLET,90,170,3),
466 /* warrior */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_MELEE,255,40,1),
467 /* plasma */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_PLASMA,56,92,1),
468 /* ender */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_FIREBALL_PLASMA,128,255,3),
469 /* turret */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_BULLET,32,23,0),
470 /* explod. */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_EXPLODE,255,36,1)
473 // -----------------------------------------------------------------------------
474 // weapons and projectiles
476 #define SFG_WEAPON_KNIFE 0
477 #define SFG_WEAPON_SHOTGUN 1
478 #define SFG_WEAPON_MACHINE_GUN 2
479 #define SFG_WEAPON_ROCKET_LAUNCHER 3
480 #define SFG_WEAPON_PLASMAGUN 4
481 #define SFG_WEAPON_SOLUTION 5
483 #define SFG_WEAPONS_TOTAL 6
485 #define SFG_WEAPON_ATTRIBUTE(fireType,projectileCount,fireCooldownMs) \
486 ((uint8_t) (fireType | ((projectileCount - 1) << 2) | ((fireCooldownMs / (SFG_MS_PER_FRAME * 16)) << 4)))
488 #define SFG_GET_WEAPON_FIRE_TYPE(weaponNumber) \
489 (SFG_weaponAttributeTable[weaponNumber] & 0x03)
491 #define SFG_GET_WEAPON_FIRE_COOLDOWN_FRAMES(weaponNumber) \
492 ((SFG_weaponAttributeTable[weaponNumber] >> 4) * 16)
494 #define SFG_GET_WEAPON_PROJECTILE_COUNT(weaponNumber) \
495 (((SFG_weaponAttributeTable[weaponNumber] >> 2) & 0x03) + 1)
497 #define SFG_MIN_WEAPON_COOLDOWN_FRAMES 8
499 #define SFG_WEAPON_FIRE_TYPE_MELEE 0
500 #define SFG_WEAPON_FIRE_TYPE_BULLET 1
501 #define SFG_WEAPON_FIRE_TYPE_FIREBALL 2
502 #define SFG_WEAPON_FIRE_TYPE_PLASMA 3
504 #define SFG_WEAPON_FIRE_TYPES_TOTAL 4
507 Table of weapon attributes, each as a byte in format:
509 MSB ccccnnff LSB
511 ff: fire type
512 nn: number of projectiles - 1
513 cccc: fire cooldown in frames, i.e. time after which the next shot can be
514 shot again, ccccc has to be multiplied by 16 to get the real value
516 static const uint8_t SFG_weaponAttributeTable[SFG_WEAPONS_TOTAL] =
518 /* knife */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_MELEE,1,650), // DPS: 6.2
519 /* shotgun */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_BULLET,2,1250), // DPS: 12.8
520 /* m. gun */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_BULLET,1,700), // DPS: 11.4
521 /* r. laun. */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_FIREBALL,1,850), // DPS: 28.2
522 /* plasma */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_PLASMA,1,550), // DPS: 32.7
523 /* solution */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_PLASMA,4,1050) // DPS: 85.7
526 static const uint8_t SFG_attackDamageTable[SFG_WEAPON_FIRE_TYPES_TOTAL] =
528 /* melee */ 4,
529 /* bullet */ 8,
530 /* explostion (fireball) */ 24,
531 /* plasma */ 18
534 #define SFG_PROJECTILE_EXPLOSION 0
535 #define SFG_PROJECTILE_FIREBALL 1
536 #define SFG_PROJECTILE_PLASMA 2
537 #define SFG_PROJECTILE_DUST 3
538 #define SFG_PROJECTILE_BULLET 4
539 #define SFG_PROJECTILE_NONE 255
541 #define SFG_PROJECTILES_TOTAL 5
543 #define SFG_PROJECTILE_ATTRIBUTE(speedSquaresPerSec,timeToLiveMs) \
544 ((uint8_t) \
545 ((((speedSquaresPerSec / 4 == 0) && (speedSquaresPerSec != 0)) ? 1 : speedSquaresPerSec / 4) | \
546 ((timeToLiveMs / (8 * SFG_MS_PER_FRAME)) << 3)))
548 #define SFG_GET_PROJECTILE_SPEED_UPS(projectileNumber) \
549 (((SFG_projectileAttributeTable[projectileNumber] & 0x07) * 4 * RCL_UNITS_PER_SQUARE) / SFG_FPS)
551 #define SFG_GET_PROJECTILE_FRAMES_TO_LIVE(projectileNumber) \
552 ((SFG_projectileAttributeTable[projectileNumber] >> 3) * 8)
555 Table of projectile attributes, each as a byte in format:
557 MSB lllllsss LSB
559 fff: half speed in game squares per second
560 lllll: eigth of frames to live
563 #define LOW_FPS (SFG_FPS < 24) ///< low FPS needs low speeds, because collisions
565 static const uint8_t SFG_projectileAttributeTable[SFG_PROJECTILES_TOTAL] =
567 /* explosion */ SFG_PROJECTILE_ATTRIBUTE(0,400),
568 /* fireball */ SFG_PROJECTILE_ATTRIBUTE(10,1000),
570 #if LOW_FPS
571 /* plasma */ SFG_PROJECTILE_ATTRIBUTE(17,500),
572 #else
573 /* plasma */ SFG_PROJECTILE_ATTRIBUTE(18,500),
574 #endif
576 /* dust */ SFG_PROJECTILE_ATTRIBUTE(0,450),
578 #if LOW_FPS
579 /* bullet */ SFG_PROJECTILE_ATTRIBUTE(17,1000)
580 #else
581 /* bullet */ SFG_PROJECTILE_ATTRIBUTE(28,1000)
582 #endif
585 #undef LOW_FPS
587 #endif // guard