mirror of https://gitlab.com/drummyfish/anarch
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
587 lines
16 KiB
587 lines
16 KiB
/** |
|
@file constants.h |
|
|
|
This file contains definitions of game constants that are not considered |
|
part of game settings and whose change can ffect the game balance and |
|
playability, e.g. physics constants. |
|
|
|
by Miloslav Ciz (drummyfish), 2019 |
|
|
|
Released under CC0 1.0 (https://creativecommons.org/publicdomain/zero/1.0/) |
|
plus a waiver of all other intellectual property. The goal of this work is to |
|
be and remain completely in the public domain forever, available for any use |
|
whatsoever. |
|
*/ |
|
|
|
#ifndef _SFG_CONSTANTS_H |
|
#define _SFG_CONSTANTS_H |
|
|
|
/** |
|
How quickly player moves, in squares per second. |
|
*/ |
|
#define SFG_PLAYER_MOVE_SPEED 7 |
|
|
|
/** |
|
Gravity acceleration in squares / (second^2). |
|
*/ |
|
#define SFG_GRAVITY_ACCELERATION 30 |
|
|
|
/** |
|
Initial upwards speed of player's jump, in squares per second. |
|
*/ |
|
#define SFG_PLAYER_JUMP_SPEED 5 |
|
|
|
/** |
|
Melee and close-up attack range, in RCL_Units. |
|
*/ |
|
#define SFG_MELEE_RANGE 1600 |
|
|
|
/** |
|
When a projectile is shot, it'll be offset by this distance (in RCL_Units) |
|
from the shooter. |
|
*/ |
|
|
|
#define SFG_PROJECTILE_SPAWN_OFFSET 256 |
|
|
|
/** |
|
Player's melee hit range, in RCL_Units (RCL_UNITS_PER_SQUARE means full angle, |
|
180 degrees to both sides). |
|
*/ |
|
#define SFG_PLAYER_MELEE_ANGLE 512 |
|
|
|
/** |
|
How quickly elevators and squeezers move, in RCL_Unit per second. |
|
*/ |
|
#define SFG_MOVING_WALL_SPEED 1024 |
|
|
|
/** |
|
How quickly doors open and close, in RCL_Unit per second. |
|
*/ |
|
#define SFG_DOOR_OPEN_SPEED 2048 |
|
|
|
/** |
|
Helper special state value. |
|
*/ |
|
#define SFG_CANT_SAVE 255 |
|
|
|
/** |
|
Says the distance in RCL_Units at which level elements (items, monsters etc.) |
|
are active. |
|
*/ |
|
#define SFG_LEVEL_ELEMENT_ACTIVE_DISTANCE (12 * 1024) |
|
|
|
/** |
|
Rate at which AI will be updated, which also affects how fast enemies will |
|
appear. |
|
*/ |
|
#define SFG_AI_FPS 4 |
|
|
|
/** |
|
Says a probability (0 - 255) of the AI changing its state during one update |
|
step. |
|
*/ |
|
#define SFG_AI_RANDOM_CHANGE_PROBABILITY 40 |
|
|
|
/** |
|
Distance at which level elements (sprites) collide, in RCL_Unit (1024 per |
|
square). |
|
*/ |
|
#define SFG_ELEMENT_COLLISION_RADIUS 1800 |
|
|
|
/** |
|
Height, in RCL_Units, at which collisions happen with level elements |
|
(sprites). |
|
*/ |
|
#define SFG_ELEMENT_COLLISION_HEIGHT 1024 |
|
|
|
/** |
|
Distance at which explosion does damage and throws away the player, in |
|
RCL_Units. Should be higher than SFG_ELEMENT_COLLISION_RADIUS so that |
|
exploded rockets also hurt the target. |
|
*/ |
|
#define SFG_EXPLOSION_RADIUS 2000 |
|
|
|
/** |
|
Distance in RCL_Units which the player is pushed away by an explosion. Watch |
|
out, a slightly higher value can make player go through walls. Rather keep |
|
this under RCL_UNITS_PER_SQUARE; |
|
*/ |
|
#define SFG_EXPLOSION_PUSH_AWAY_DISTANCE 1023 |
|
|
|
/** |
|
How much damage triggers a barrel explosion. |
|
*/ |
|
|
|
#define SFG_BARREL_EXPLOSION_DAMAGE_THRESHOLD 3 |
|
|
|
/** |
|
Maximum player health. |
|
*/ |
|
#define SFG_PLAYER_MAX_HEALTH 125 |
|
|
|
/** |
|
Start health of player. |
|
*/ |
|
#define SFG_PLAYER_START_HEALTH 100 |
|
|
|
/** |
|
At which value health indicator shows a warning (red color). |
|
*/ |
|
#define SFG_PLAYER_HEALTH_WARNING_LEVEL 20 |
|
|
|
/** |
|
Amount of health that is increased by taking a health kit. |
|
*/ |
|
#define SFG_HEALTH_KIT_VALUE 20 |
|
|
|
/** |
|
How much randomness (positive and negative) will be added to damage |
|
(e.g. by weapons, explosions, ...). This constant is is 0 to 255, 255 meaning |
|
100% of the base value. |
|
*/ |
|
#define SFG_DAMAGE_RANDOMNESS 64 |
|
|
|
/** |
|
Height of monster collision BBox in RCL_Units. |
|
*/ |
|
#define SFG_MONSTER_COLLISION_HEIGHT 1024 |
|
|
|
/** |
|
Specifies key repeat delay, in ms. |
|
*/ |
|
#define SFG_KEY_REPEAT_DELAY 500 |
|
|
|
/** |
|
Specifies key repeat period, in ms. |
|
*/ |
|
#define SFG_KEY_REPEAT_PERIOD 150 |
|
|
|
/** |
|
Angle in which multiple projectiles are spread, RCL_Units. |
|
*/ |
|
#define SFG_PROJECTILE_SPREAD_ANGLE 100 |
|
|
|
#define SFG_MAX_MONSTERS 64 |
|
|
|
#define SFG_MAX_PROJECTILES 12 |
|
|
|
#define SFG_MAX_DOORS 32 |
|
|
|
#define SFG_AMMO_BULLETS 0 |
|
#define SFG_AMMO_ROCKETS 1 |
|
#define SFG_AMMO_PLASMA 2 |
|
|
|
#define SFG_AMMO_TOTAL 3 |
|
|
|
#define SFG_AMMO_NONE SFG_AMMO_TOTAL |
|
|
|
#define SFG_AMMO_INCREASE_BULLETS 10 |
|
#define SFG_AMMO_INCREASE_ROCKETS 5 |
|
#define SFG_AMMO_INCREASE_PLASMA 8 |
|
|
|
#define SFG_AMMO_MAX_BULLETS 200 |
|
#define SFG_AMMO_MAX_ROCKETS 100 |
|
#define SFG_AMMO_MAX_PLASMA 150 |
|
|
|
/** |
|
Duration of story text (intro/outro) in ms. |
|
*/ |
|
#define SFG_STORYTEXT_DURATION 15000 |
|
|
|
/** |
|
Time in ms of the player death animation. |
|
*/ |
|
#define SFG_LOSE_ANIMATION_DURATION 2000 |
|
|
|
/** |
|
Time in ms of the level win animation. |
|
*/ |
|
#define SFG_WIN_ANIMATION_DURATION 2500 |
|
|
|
/** |
|
Time in ms of the level start stage. |
|
*/ |
|
#define SFG_LEVEL_START_DURATION 1500 |
|
|
|
/** |
|
Vertical sprite size, in RCL_Units. |
|
*/ |
|
#define SFG_BASE_SPRITE_SIZE RCL_UNITS_PER_SQUARE |
|
|
|
/** |
|
Default value of the settings byte. |
|
*/ |
|
#define SFG_DEFAULT_SETTINGS 0x03 |
|
|
|
// ----------------------------------------------------------------------------- |
|
// derived constants |
|
|
|
#define SFG_GAME_RESOLUTION_X \ |
|
(SFG_SCREEN_RESOLUTION_X / SFG_RESOLUTION_SCALEDOWN) |
|
|
|
#define SFG_GAME_RESOLUTION_Y \ |
|
(SFG_SCREEN_RESOLUTION_Y / SFG_RESOLUTION_SCALEDOWN) |
|
|
|
#define SFG_MS_PER_FRAME (1000 / SFG_FPS) // ms per frame with target FPS |
|
|
|
#if SFG_MS_PER_FRAME == 0 |
|
#undef SFG_MS_PER_FRAME |
|
#define SFG_MS_PER_FRAME 1 |
|
#endif |
|
|
|
#define SFG_KEY_REPEAT_DELAY_FRAMES \ |
|
(SFG_KEY_REPEAT_DELAY / SFG_MS_PER_FRAME) |
|
|
|
#if SFG_KEY_REPEAT_DELAY_FRAMES == 0 |
|
#undef SFG_KEY_REPEAT_DELAY_FRAMES |
|
#define SFG_KEY_REPEAT_DELAY_FRAMES 1 |
|
#endif |
|
|
|
#define SFG_KEY_REPEAT_PERIOD_FRAMES \ |
|
(SFG_KEY_REPEAT_PERIOD / SFG_MS_PER_FRAME) |
|
|
|
#if SFG_KEY_REPEAT_PERIOD_FRAMES == 0 |
|
#undef SFG_KEY_REPEAT_PERIOD_FRAMES |
|
#define SFG_KEY_REPEAT_PERIOD_FRAMES 1 |
|
#endif |
|
|
|
#define SFG_WEAPON_IMAGE_SCALE \ |
|
(SFG_GAME_RESOLUTION_X / (SFG_TEXTURE_SIZE * 5)) |
|
|
|
#if SFG_WEAPON_IMAGE_SCALE == 0 |
|
#undef SFG_WEAPON_IMAGE_SCALE |
|
#define SFG_WEAPON_IMAGE_SCALE 1 |
|
#endif |
|
|
|
#define SFG_WEAPONBOB_OFFSET_PIXELS \ |
|
(SFG_WEAPONBOB_OFFSET * SFG_WEAPON_IMAGE_SCALE) |
|
|
|
#define SFG_WEAPON_IMAGE_POSITION_X \ |
|
(SFG_GAME_RESOLUTION_X / 2 - (SFG_WEAPON_IMAGE_SCALE * SFG_TEXTURE_SIZE) / 2) |
|
|
|
#if SFG_GAME_RESOLUTION_Y > 70 |
|
#define SFG_WEAPON_IMAGE_POSITION_Y \ |
|
(SFG_GAME_RESOLUTION_Y - (SFG_WEAPON_IMAGE_SCALE * SFG_TEXTURE_SIZE)) |
|
#elif SFG_GAME_RESOLUTION_Y > 50 |
|
#define SFG_WEAPON_IMAGE_POSITION_Y (SFG_GAME_RESOLUTION_Y \ |
|
- ((SFG_WEAPON_IMAGE_SCALE * 3 * SFG_TEXTURE_SIZE) / 4)) |
|
#else |
|
#define SFG_WEAPON_IMAGE_POSITION_Y \ |
|
(SFG_GAME_RESOLUTION_Y - SFG_TEXTURE_SIZE / 2) |
|
#endif |
|
|
|
#define SFG_PLAYER_TURN_UNITS_PER_FRAME \ |
|
((SFG_PLAYER_TURN_SPEED * RCL_UNITS_PER_SQUARE) / (360 * SFG_FPS)) |
|
|
|
#if SFG_PLAYER_TURN_UNITS_PER_FRAME == 0 |
|
#undef SFG_PLAYER_TURN_UNITS_PER_FRAME |
|
#define SFG_PLAYER_TURN_UNITS_PER_FRAME 1 |
|
#endif |
|
|
|
#define SFG_PLAYER_MOVE_UNITS_PER_FRAME \ |
|
((SFG_PLAYER_MOVE_SPEED * RCL_UNITS_PER_SQUARE) / SFG_FPS) |
|
|
|
#if SFG_PLAYER_MOVE_UNITS_PER_FRAME == 0 |
|
#undef SFG_PLAYER_MOVE_UNITS_PER_FRAME |
|
#define SFG_PLAYER_MOVE_UNITS_PER_FRAME 1 |
|
#endif |
|
|
|
#define SFG_GRAVITY_SPEED_INCREASE_PER_FRAME \ |
|
((SFG_GRAVITY_ACCELERATION * RCL_UNITS_PER_SQUARE) / (SFG_FPS * SFG_FPS)) |
|
|
|
#if SFG_GRAVITY_SPEED_INCREASE_PER_FRAME == 0 |
|
#undef SFG_GRAVITY_SPEED_INCREASE_PER_FRAME |
|
#define SFG_GRAVITY_SPEED_INCREASE_PER_FRAME 1 |
|
#endif |
|
|
|
#define SFG_PLAYER_JUMP_OFFSET_PER_FRAME \ |
|
(((SFG_PLAYER_JUMP_SPEED * RCL_UNITS_PER_SQUARE) / SFG_FPS) \ |
|
- SFG_GRAVITY_SPEED_INCREASE_PER_FRAME / 2) |
|
/* ^ This substraction corrects the initial veloc. so that the numeric curve |
|
copies the analytical (smooth) curve. Without it the numeric curve goes |
|
ABOVE and makes player jump higher with lower FPS. To make sense of this |
|
try to solve the differential equation and plot it. */ |
|
|
|
#if SFG_PLAYER_JUMP_OFFSET_PER_FRAME == 0 |
|
#undef SFG_PLAYER_JUMP_OFFSET_PER_FRAME |
|
#define SFG_PLAYER_JUMP_OFFSET_PER_FRAME 1 |
|
#endif |
|
|
|
#define SFG_HEADBOB_FRAME_INCREASE_PER_FRAME \ |
|
(SFG_HEADBOB_SPEED / SFG_FPS) |
|
|
|
#if SFG_HEADBOB_FRAME_INCREASE_PER_FRAME == 0 |
|
#undef SFG_HEADBOB_FRAME_INCREASE_PER_FRAME |
|
#define SFG_HEADBOB_FRAME_INCREASE_PER_FRAME 1 |
|
#endif |
|
|
|
#define SFG_HEADBOB_ENABLED (SFG_HEADBOB_SPEED > 0 && SFG_HEADBOB_OFFSET > 0) |
|
|
|
#define SFG_CAMERA_SHEAR_STEP_PER_FRAME \ |
|
((SFG_GAME_RESOLUTION_Y * SFG_CAMERA_SHEAR_SPEED) / SFG_FPS) |
|
|
|
#if SFG_CAMERA_SHEAR_STEP_PER_FRAME == 0 |
|
#undef SFG_CAMERA_SHEAR_STEP_PER_FRAME |
|
#define SFG_CAMERA_SHEAR_STEP_PER_FRAME 1 |
|
#endif |
|
|
|
#define SFG_CAMERA_MAX_SHEAR_PIXELS \ |
|
((SFG_CAMERA_MAX_SHEAR * SFG_GAME_RESOLUTION_Y) / 1024) |
|
|
|
#define SFG_FONT_SIZE_SMALL \ |
|
(SFG_GAME_RESOLUTION_X / (SFG_FONT_CHARACTER_SIZE * 50)) |
|
|
|
#if SFG_FONT_SIZE_SMALL == 0 |
|
#undef SFG_FONT_SIZE_SMALL |
|
#define SFG_FONT_SIZE_SMALL 1 |
|
#endif |
|
|
|
#define SFG_FONT_SIZE_MEDIUM \ |
|
(SFG_GAME_RESOLUTION_X / (SFG_FONT_CHARACTER_SIZE * 30)) |
|
|
|
#if SFG_FONT_SIZE_MEDIUM == 0 |
|
#undef SFG_FONT_SIZE_MEDIUM |
|
#define SFG_FONT_SIZE_MEDIUM 1 |
|
#endif |
|
|
|
#define SFG_FONT_SIZE_BIG \ |
|
(SFG_GAME_RESOLUTION_X / (SFG_FONT_CHARACTER_SIZE * 18)) |
|
|
|
#if SFG_FONT_SIZE_BIG == 0 |
|
#undef SFG_FONT_SIZE_BIG |
|
#define SFG_FONT_SIZE_BIG 1 |
|
#endif |
|
|
|
#define SFG_Z_BUFFER_SIZE SFG_GAME_RESOLUTION_X |
|
|
|
/** |
|
Step in which walls get higher, in raycastlib units. |
|
*/ |
|
#define SFG_WALL_HEIGHT_STEP (RCL_UNITS_PER_SQUARE / 4) |
|
|
|
#define SFG_CEILING_MAX_HEIGHT\ |
|
(16 * RCL_UNITS_PER_SQUARE - RCL_UNITS_PER_SQUARE / 2 ) |
|
|
|
#define SFG_DOOR_UP_DOWN_MASK 0x20 |
|
#define SFG_DOOR_LOCK(doorRecord) ((doorRecord) >> 6) |
|
#define SFG_DOOR_VERTICAL_POSITION_MASK 0x1f |
|
#define SFG_DOOR_HEIGHT_STEP (RCL_UNITS_PER_SQUARE / 0x1f) |
|
|
|
#define SFG_DOOR_INCREMENT_PER_FRAME \ |
|
(SFG_DOOR_OPEN_SPEED / (SFG_DOOR_HEIGHT_STEP * SFG_FPS)) |
|
|
|
#if SFG_DOOR_INCREMENT_PER_FRAME == 0 |
|
#undef SFG_DOOR_INCREMENT_PER_FRAME |
|
#define SFG_DOOR_INCREMENT_PER_FRAME 1 |
|
#endif |
|
|
|
#define SFG_MAX_ITEMS SFG_MAX_LEVEL_ELEMENTS |
|
|
|
#define SFG_MAX_SPRITE_SIZE SFG_GAME_RESOLUTION_X |
|
|
|
#define SFG_MAP_PIXEL_SIZE (SFG_GAME_RESOLUTION_Y / SFG_MAP_SIZE) |
|
|
|
#if SFG_MAP_PIXEL_SIZE == 0 |
|
#undef SFG_MAP_PIXEL_SIZE |
|
#define SFG_MAP_PIXEL_SIZE 1 |
|
#endif |
|
|
|
#define SFG_AI_UPDATE_FRAME_INTERVAL \ |
|
(SFG_FPS / SFG_AI_FPS) |
|
|
|
#if SFG_AI_UPDATE_FRAME_INTERVAL == 0 |
|
#undef SFG_AI_UPDATE_FRAME_INTERVAL |
|
#define SFG_AI_UPDATE_FRAME_INTERVAL 1 |
|
#endif |
|
|
|
#define SFG_SPRITE_ANIMATION_FRAME_DURATION \ |
|
(SFG_FPS / SFG_SPRITE_ANIMATION_SPEED) |
|
|
|
#if SFG_SPRITE_ANIMATION_FRAME_DURATION == 0 |
|
#undef SFG_SPRITE_ANIMATION_FRAME_DURATION |
|
#define SFG_SPRITE_ANIMATION_FRAME_DURATION 1 |
|
#endif |
|
|
|
#define SFG_HUD_MARGIN (SFG_GAME_RESOLUTION_X / 40) |
|
|
|
#define SFG_HUD_BORDER_INDICATOR_WIDTH_PIXELS \ |
|
(SFG_GAME_RESOLUTION_Y / SFG_HUD_BORDER_INDICATOR_WIDTH) |
|
|
|
#define SFG_HUD_BORDER_INDICATOR_DURATION_FRAMES \ |
|
(SFG_HUD_BORDER_INDICATOR_DURATION / SFG_MS_PER_FRAME) |
|
|
|
#if SFG_HUD_BORDER_INDICATOR_DURATION_FRAMES == 0 |
|
#define SFG_HUD_BORDER_INDICATOR_DURATION_FRAMES 1 |
|
#endif |
|
|
|
#define SFG_BLINK_PERIOD_FRAMES (SFG_BLINK_PERIOD / SFG_MS_PER_FRAME) |
|
|
|
#define SFG_HUD_BAR_HEIGHT \ |
|
(SFG_FONT_CHARACTER_SIZE * SFG_FONT_SIZE_MEDIUM + SFG_HUD_MARGIN * 2 + 1) |
|
|
|
// ----------------------------------------------------------------------------- |
|
// monsters |
|
|
|
#define SFG_MONSTER_ATTACK_MELEE 0 |
|
#define SFG_MONSTER_ATTACK_FIREBALL 1 |
|
#define SFG_MONSTER_ATTACK_BULLET 2 |
|
#define SFG_MONSTER_ATTACK_FIREBALL_BULLET 3 |
|
#define SFG_MONSTER_ATTACK_PLASMA 4 |
|
#define SFG_MONSTER_ATTACK_EXPLODE 5 |
|
#define SFG_MONSTER_ATTACK_FIREBALL_PLASMA 6 |
|
|
|
#define SFG_MONSTER_ATTRIBUTE(attackType,aggressivity0to255,health0to255,spriteSize0to3) \ |
|
((uint16_t) ( \ |
|
attackType | \ |
|
((aggressivity0to255 / 8) << 3) | \ |
|
(spriteSize0to3 << 8) | \ |
|
((health0to255 / 4) << 10))) |
|
|
|
#define SFG_GET_MONSTER_ATTACK_TYPE(monsterNumber) \ |
|
(SFG_monsterAttributeTable[monsterNumber] & 0x0007) |
|
|
|
#define SFG_GET_MONSTER_AGGRESSIVITY(monsterNumber) \ |
|
(((SFG_monsterAttributeTable[monsterNumber] >> 3) & 0x1F) * 8) |
|
|
|
#define SFG_GET_MONSTER_SPRITE_SIZE(monsterNumber) \ |
|
((SFG_monsterAttributeTable[monsterNumber] >> 8) & 0x03) |
|
|
|
#define SFG_GET_MONSTER_MAX_HEALTH(monsterNumber) \ |
|
(((SFG_monsterAttributeTable[monsterNumber] >> 10) & 0x3F) * 4) |
|
|
|
/** |
|
Table of monster attributes, each as a 16bit word in format: |
|
|
|
MSB hhhhhhssaaaattt LSB |
|
|
|
ttt: attack type |
|
aaaaa: aggressivity (frequence of attacks), 0 to 31 |
|
ss: sprite size |
|
hhhhhh: health, 0 to 63 |
|
*/ |
|
uint16_t SFG_monsterAttributeTable[SFG_MONSTERS_TOTAL] = |
|
{ |
|
/* spider */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_FIREBALL,40,61,2), |
|
/* destr. */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_FIREBALL_BULLET,90,170,3), |
|
/* warrior */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_MELEE,255,40,1), |
|
/* plasma */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_PLASMA,56,92,1), |
|
/* ender */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_FIREBALL_PLASMA,128,255,3), |
|
/* turret */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_BULLET,32,23,0), |
|
/* explod. */ SFG_MONSTER_ATTRIBUTE(SFG_MONSTER_ATTACK_EXPLODE,255,36,1) |
|
}; |
|
|
|
// ----------------------------------------------------------------------------- |
|
// weapons and projectiles |
|
|
|
#define SFG_WEAPON_KNIFE 0 |
|
#define SFG_WEAPON_SHOTGUN 1 |
|
#define SFG_WEAPON_MACHINE_GUN 2 |
|
#define SFG_WEAPON_ROCKET_LAUNCHER 3 |
|
#define SFG_WEAPON_PLASMAGUN 4 |
|
#define SFG_WEAPON_SOLUTION 5 |
|
|
|
#define SFG_WEAPONS_TOTAL 6 |
|
|
|
#define SFG_WEAPON_ATTRIBUTE(fireType,projectileCount,fireCooldownMs) \ |
|
((uint8_t) (fireType | ((projectileCount - 1) << 2) | ((fireCooldownMs / (SFG_MS_PER_FRAME * 16)) << 4))) |
|
|
|
#define SFG_GET_WEAPON_FIRE_TYPE(weaponNumber) \ |
|
(SFG_weaponAttributeTable[weaponNumber] & 0x03) |
|
|
|
#define SFG_GET_WEAPON_FIRE_COOLDOWN_FRAMES(weaponNumber) \ |
|
((SFG_weaponAttributeTable[weaponNumber] >> 4) * 16) |
|
|
|
#define SFG_GET_WEAPON_PROJECTILE_COUNT(weaponNumber) \ |
|
(((SFG_weaponAttributeTable[weaponNumber] >> 2) & 0x03) + 1) |
|
|
|
#define SFG_MIN_WEAPON_COOLDOWN_FRAMES 8 |
|
|
|
#define SFG_WEAPON_FIRE_TYPE_MELEE 0 |
|
#define SFG_WEAPON_FIRE_TYPE_BULLET 1 |
|
#define SFG_WEAPON_FIRE_TYPE_FIREBALL 2 |
|
#define SFG_WEAPON_FIRE_TYPE_PLASMA 3 |
|
|
|
#define SFG_WEAPON_FIRE_TYPES_TOTAL 4 |
|
|
|
/** |
|
Table of weapon attributes, each as a byte in format: |
|
|
|
MSB ccccnnff LSB |
|
|
|
ff: fire type |
|
nn: number of projectiles - 1 |
|
cccc: fire cooldown in frames, i.e. time after which the next shot can be |
|
shot again, ccccc has to be multiplied by 16 to get the real value |
|
*/ |
|
static const uint8_t SFG_weaponAttributeTable[SFG_WEAPONS_TOTAL] = |
|
{ |
|
/* knife */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_MELEE,1,650), // DPS: 6.2 |
|
/* shotgun */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_BULLET,2,1250), // DPS: 12.8 |
|
/* m. gun */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_BULLET,1,700), // DPS: 11.4 |
|
/* r. laun. */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_FIREBALL,1,850), // DPS: 28.2 |
|
/* plasma */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_PLASMA,1,550), // DPS: 32.7 |
|
/* solution */ SFG_WEAPON_ATTRIBUTE(SFG_WEAPON_FIRE_TYPE_PLASMA,4,1050) // DPS: 85.7 |
|
}; |
|
|
|
static const uint8_t SFG_attackDamageTable[SFG_WEAPON_FIRE_TYPES_TOTAL] = |
|
{ |
|
/* melee */ 4, |
|
/* bullet */ 8, |
|
/* explostion (fireball) */ 24, |
|
/* plasma */ 18 |
|
}; |
|
|
|
#define SFG_PROJECTILE_EXPLOSION 0 |
|
#define SFG_PROJECTILE_FIREBALL 1 |
|
#define SFG_PROJECTILE_PLASMA 2 |
|
#define SFG_PROJECTILE_DUST 3 |
|
#define SFG_PROJECTILE_BULLET 4 |
|
#define SFG_PROJECTILE_NONE 255 |
|
|
|
#define SFG_PROJECTILES_TOTAL 5 |
|
|
|
#define SFG_PROJECTILE_ATTRIBUTE(speedSquaresPerSec,timeToLiveMs) \ |
|
((uint8_t) \ |
|
((((speedSquaresPerSec / 4 == 0) && (speedSquaresPerSec != 0)) ? 1 : speedSquaresPerSec / 4) | \ |
|
((timeToLiveMs / (8 * SFG_MS_PER_FRAME)) << 3))) |
|
|
|
#define SFG_GET_PROJECTILE_SPEED_UPS(projectileNumber) \ |
|
(((SFG_projectileAttributeTable[projectileNumber] & 0x07) * 4 * RCL_UNITS_PER_SQUARE) / SFG_FPS) |
|
|
|
#define SFG_GET_PROJECTILE_FRAMES_TO_LIVE(projectileNumber) \ |
|
((SFG_projectileAttributeTable[projectileNumber] >> 3) * 8) |
|
|
|
/** |
|
Table of projectile attributes, each as a byte in format: |
|
|
|
MSB lllllsss LSB |
|
|
|
fff: half speed in game squares per second |
|
lllll: eigth of frames to live |
|
*/ |
|
|
|
#define LOW_FPS (SFG_FPS < 24) ///< low FPS needs low speeds, because collisions |
|
|
|
static const uint8_t SFG_projectileAttributeTable[SFG_PROJECTILES_TOTAL] = |
|
{ |
|
/* explosion */ SFG_PROJECTILE_ATTRIBUTE(0,400), |
|
/* fireball */ SFG_PROJECTILE_ATTRIBUTE(10,1000), |
|
|
|
#if LOW_FPS |
|
/* plasma */ SFG_PROJECTILE_ATTRIBUTE(17,500), |
|
#else |
|
/* plasma */ SFG_PROJECTILE_ATTRIBUTE(18,500), |
|
#endif |
|
|
|
/* dust */ SFG_PROJECTILE_ATTRIBUTE(0,450), |
|
|
|
#if LOW_FPS |
|
/* bullet */ SFG_PROJECTILE_ATTRIBUTE(17,1000) |
|
#else |
|
/* bullet */ SFG_PROJECTILE_ATTRIBUTE(28,1000) |
|
#endif |
|
}; |
|
|
|
#undef LOW_FPS |
|
|
|
#endif // guard
|
|
|