Files
factorygame/tiles/turret.c
2025-06-10 21:59:51 +02:00

101 lines
3.0 KiB
C

//
// Created by bruno on 6.9.2025.
//
#include "turret.h"
#include "tile.h"
#include "../util/audio.h"
#include "../entity/entity.h"
const uint16_t AmmoDamages[ITEMREGISTRY_SIZE] = {
[IRON_INGOT] = 2,
[GOLD_INGOT] = 1,
[SILVER_INGOT] = 3,
[PLATINUM_INGOT] = 5,
[IRON_BULLET] = 20,
[GOLD_BULLET] = 10,
[SILVER_BULLET] = 30,
[PLATINUM_BULLET] = 50,
};
void updateTurret(Tile *tile) {
ItemOnBelt *inItem = &tile->items[TURRET_AMMO_INPUT_SLOT];
Item inItemType = ItemRegistry[inItem->type];
uint16_t damage = AmmoDamages[inItem->type];
// Reduce cooldown (miscVal) if above 0
if (tile->miscVal > 0) {
tile->miscVal--;
}
// If there's no ammo or it's invalid, stop the sound and return
if (damage == 0) {
if (tile->audioCh < NUM_SYNTH_VOICES) {
audioData.synthVoices[tile->audioCh].volume = 0;
}
if (animationStep % (TileRegistry[tile->type].animation.frameCount - 1) == 0) {
tile->fixedFrame = 1;
}
return;
}
// Search for a target entity
bool foundEnt = false;
for (int i = 0; i < entities.activeCount; i++) {
Entity *ent = &entities.entities[i];
int dx = abs(ent->renderRect.x - (tile->rect.x * TILE_SIZE));
int dy = abs(ent->renderRect.y - (tile->rect.y * TILE_SIZE));
int d = sqrt(dx * dx + dy * dy);
if (d <= (TILE_SIZE * 8)) {
foundEnt = true;
if (tile->miscVal == 0) {
// Do damage and consume ammo
ent->health -= damage;
inItem->type = 0;
// Get or reuse audio channel
if (tile->audioCh >= NUM_SYNTH_VOICES) {
tile->audioCh = getAvailableChannel();
}
if (tile->audioCh < NUM_SYNTH_VOICES) {
SynthVoice *voice = &audioData.synthVoices[tile->audioCh];
voice->volume = 255;
voice->phase = 0;
voice->sourceRect.x = tile->rect.x * TILE_SIZE;
voice->sourceRect.y = tile->rect.y * TILE_SIZE;
voice->waveform = WAVE_TRIANGLE;
voice->frequency = 400;
}
tile->fixedFrame = 0;
tile->miscVal = 20; // Cooldown (ticks) until next fire
}
break; // Only shoot one entity
}
}
// No entity found? Fade sound out
if (!foundEnt && tile->audioCh < NUM_SYNTH_VOICES) {
SynthVoice *voice = &audioData.synthVoices[tile->audioCh];
if (voice->volume > 0) {
voice->volume--;
}
if (animationStep % (TileRegistry[tile->type].animation.frameCount - 1) == 0) {
tile->fixedFrame = 1;
}
}
// Lower frequency for pitch effect if it's still playing
if (tile->audioCh < NUM_SYNTH_VOICES) {
SynthVoice *voice = &audioData.synthVoices[tile->audioCh];
if (voice->frequency > 80) {
voice->frequency--;
}
}
}