summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE7
-rw-r--r--assets/fx/water_splash.oggbin0 -> 13636 bytes
-rw-r--r--assets/fx/water_splash_0.pngbin0 -> 285 bytes
-rw-r--r--assets/fx/water_splash_1.pngbin0 -> 299 bytes
-rw-r--r--assets/fx/water_splash_2.pngbin0 -> 362 bytes
-rw-r--r--src/audio.cpp2
-rw-r--r--src/common.hpp1
-rw-r--r--src/game/assets.cpp4
-rw-r--r--src/game/effects.cpp12
-rw-r--r--src/game/game.hpp14
-rw-r--r--src/game/unit_soldier.cpp57
-rw-r--r--src/world.cpp29
12 files changed, 82 insertions, 44 deletions
diff --git a/LICENSE b/LICENSE
index d86aa53..ffc8475 100644
--- a/LICENSE
+++ b/LICENSE
@@ -34,6 +34,7 @@ assets/units/spider/*.ogg
The following assets were made by various other authors:
-FILE AUTHOR LICENSE
-assets/FanwoodText.otf Barry Schwartz MIT
-assets/fx/explosion.ogg cydon at freesound.org CC0
+FILE AUTHOR LICENSE
+assets/FanwoodText.otf Barry Schwartz MIT
+assets/fx/explosion.ogg cydon at freesound.org CC0
+assets/fx/water_splash.ogg Rocktopus at freesound.org CC-BY \ No newline at end of file
diff --git a/assets/fx/water_splash.ogg b/assets/fx/water_splash.ogg
new file mode 100644
index 0000000..d026945
--- /dev/null
+++ b/assets/fx/water_splash.ogg
Binary files differ
diff --git a/assets/fx/water_splash_0.png b/assets/fx/water_splash_0.png
new file mode 100644
index 0000000..23d49e9
--- /dev/null
+++ b/assets/fx/water_splash_0.png
Binary files differ
diff --git a/assets/fx/water_splash_1.png b/assets/fx/water_splash_1.png
new file mode 100644
index 0000000..2200371
--- /dev/null
+++ b/assets/fx/water_splash_1.png
Binary files differ
diff --git a/assets/fx/water_splash_2.png b/assets/fx/water_splash_2.png
new file mode 100644
index 0000000..787102a
--- /dev/null
+++ b/assets/fx/water_splash_2.png
Binary files differ
diff --git a/src/audio.cpp b/src/audio.cpp
index b806959..d3ecc03 100644
--- a/src/audio.cpp
+++ b/src/audio.cpp
@@ -69,7 +69,7 @@ void update(v3f_t camera, bool paused)
// and +Y pointing down
sf::Listener::setPosition(camera);
sf::Listener::setDirection(0.0f, 0.0f, -1.0f);
- sf::Listener::setUpVector(0.0f, 1.0f, 0.0f);
+ sf::Listener::setUpVector(0.0f, 1.0f, 0.0f);
// remove sounds that finished playing from playing_sounds
playing_sounds.remove_if( [](sf::Sound &sound) {
diff --git a/src/common.hpp b/src/common.hpp
index ff5839f..620580e 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -199,6 +199,7 @@ namespace world {
bool test_rect(const cmodel_t *cmodel, const entity_t *ignore);
+ trace_t point_v_tiles(v2f_t at, cflags_t cflags);
trace_t ray_v_ents(v2f_t start, v2f_t end, cflags_t cflags, const entity_t *ignore);
trace_t ray_v_tiles(v2f_t start, v2f_t end, cflags_t cflags);
trace_t ray_v_all(v2f_t start, v2f_t end, cflags_t cflags, const entity_t *ignore);
diff --git a/src/game/assets.cpp b/src/game/assets.cpp
index 05b647a..0148e27 100644
--- a/src/game/assets.cpp
+++ b/src/game/assets.cpp
@@ -86,9 +86,11 @@ void load(void)
fx.explosion.load("assets/fx/explosion_", 7);
fx.explosion_sound.load("assets/fx/explosion.ogg");
- fx.explosion_sound.volume = 3.0f;
+ fx.explosion_sound.volume = 12.0f;
fx.ricochet.load("assets/fx/ricochet_", 3);
fx.ricochet_sound.load("assets/fx/ricochet.ogg");
+ fx.water_splash.load("assets/fx/water_splash_", 3);
+ fx.water_splash_sound.load("assets/fx/water_splash.ogg");
deco.stone.load("assets/deco/stone_", 1);
deco.stone_cracked.load("assets/deco/stone_cracked_", 1);
diff --git a/src/game/effects.cpp b/src/game/effects.cpp
index 501b296..daa2770 100644
--- a/src/game/effects.cpp
+++ b/src/game/effects.cpp
@@ -182,11 +182,12 @@ void fx_explosion_t::render_to(render::state_t *render)
render->render(phase, &assets::fx.explosion, render_bounds, sf::Color::White);
}
-fx_ricochet_t::fx_ricochet_t(state_t *game_, v2f_t x_) : effect_t(game_)
+fx_bullet_miss_t::fx_bullet_miss_t(state_t *game_, v2f_t x_, bool water_) : effect_t(game_)
{
ttl = game->now + 0.3;
x = x_;
+ water = water_;
render_bounds[0] = x - v2f_t(0.12f, 0.12f);
render_bounds[1] = x + v2f_t(0.12f, 0.12f);
@@ -197,13 +198,16 @@ fx_ricochet_t::fx_ricochet_t(state_t *game_, v2f_t x_) : effect_t(game_)
ignore_waking = true;
wake();
- assets::fx.ricochet_sound.play_3d(x);
+ if (water)
+ assets::fx.water_splash_sound.play_3d(x);
+ else
+ assets::fx.ricochet_sound.play_3d(x);
}
-void fx_ricochet_t::render_to(render::state_t *render)
+void fx_bullet_miss_t::render_to(render::state_t *render)
{
double phase = (game->now - ttl) / 0.3f;
- render->render(phase, &assets::fx.ricochet, render_bounds, sf::Color::White);
+ render->render(phase, (water ? &assets::fx.water_splash : &assets::fx.ricochet), render_bounds, sf::Color::White);
}
} // namespace game
diff --git a/src/game/game.hpp b/src/game/game.hpp
index 61ea146..1a28413 100644
--- a/src/game/game.hpp
+++ b/src/game/game.hpp
@@ -86,8 +86,8 @@ namespace game {
} repl_assets_t;
typedef struct {
- render::animated_texture_t blood, flash, explosion, ricochet;
- audio::sound_t explosion_sound, ricochet_sound;
+ render::animated_texture_t blood, flash, explosion, ricochet, water_splash;
+ audio::sound_t explosion_sound, ricochet_sound, water_splash_sound;
} fx_assets_t;
typedef struct {
@@ -249,7 +249,8 @@ namespace game {
bool rocket_fired = false;
void check_area(void);
- void shoot(v2f_t aim);
+ void shoot(v2f_t from, v2f_t at, int damage);
+ void fire_shotgun(v2f_t aim);
void target_and_attack(void);
unit_soldier_t(game::state_t *game_);
@@ -390,12 +391,13 @@ namespace game {
void render_to(render::state_t *render);
};
- class fx_ricochet_t : public effect_t {
+ class fx_bullet_miss_t : public effect_t {
v2f_t x;
+ bool water;
public:
- fx_ricochet_t(game::state_t *game_, v2f_t x_);
- ~fx_ricochet_t(void) {};
+ fx_bullet_miss_t(game::state_t *game_, v2f_t x_, bool water_);
+ ~fx_bullet_miss_t(void) {};
void render_to(render::state_t *render);
};
diff --git a/src/game/unit_soldier.cpp b/src/game/unit_soldier.cpp
index 4cf840d..2131493 100644
--- a/src/game/unit_soldier.cpp
+++ b/src/game/unit_soldier.cpp
@@ -78,17 +78,39 @@ static v2f_t spread_aim(v2f_t x, v2f_t aim, float cof, procgen::prng_t *prng)
sin(dth) * tmp[0] + cos(dth) * tmp[1]);
}
-void unit_soldier_t::shoot(v2f_t aim)
+void unit_soldier_t::shoot(v2f_t from, v2f_t at, int damage)
{
- v2f_t end;
world::trace_t trace;
- v2f_t muzzle_point;
fx_tracer_t *tracer;
+
+ trace = world->ray_v_all_p3d(from, at, CF_SOLID|CF_BODY|CF_BODY_SMALL, -1, this);
+ if (trace.hit && trace.ent) {
+ entity_t *ent = dynamic_cast<entity_t*>(trace.ent);
+ ent->damage(damage, this);
+ }
+
+ tracer = new fx_tracer_t(game, from, at);
+ tracer->place(&game->world);
+
+ if (trace.hit && (!trace.ent || trace.ent->type == ET_UNIT)) {
+ fx_bullet_miss_t *bullet_miss;
+ bool water;
+
+ water = (trace.tile && trace.tile->type == TILE_WATER);
+ bullet_miss = new fx_bullet_miss_t(game, trace.end, water);
+ bullet_miss->place(&game->world);
+ }
+}
+
+void unit_soldier_t::fire_shotgun(v2f_t aim)
+{
+ v2f_t muzzle_point;
+ world::trace_t trace;
fx_flash_t *flash;
- end = spread_aim(x, aim, 0.1f, &game->prng);
+ muzzle_point = x + v2f_t(0, -0.7f);
- trace = world->ray_v_all_p3d(x, end, CF_SOLID|CF_BODY|CF_BODY_SMALL, -1, this);
+ trace = world->ray_v_all_p3d(x, aim, CF_SOLID|CF_BODY|CF_BODY_SMALL, -1, this);
if (!manual_firing && trace.hit &&
trace.ent && trace.ent->type == ET_UNIT) {
unit_t *unit = dynamic_cast<unit_t*>(trace.ent);
@@ -98,31 +120,20 @@ void unit_soldier_t::shoot(v2f_t aim)
return;
}
- muzzle_point = x + v2f_t(0, -1.0f);
+ for (size_t i = 0; i < 5; i++) {
+ v2f_t end;
- tracer = new fx_tracer_t(game, muzzle_point, trace.end);
- tracer->place(&game->world);
+ end = spread_aim(muzzle_point, aim, 0.1f, &game->prng);
+ shoot(muzzle_point, end, 1);
+ }
flash = new fx_flash_t(game, muzzle_point, 5.0f, sf::Color(255, 170, 50, 80));
flash->place(&game->world);
-
last_attack = game->now;
-
assets::soldier.fire.play_3d(x);
-
- if (trace.hit && trace.ent) {
- entity_t *ent = dynamic_cast<entity_t*>(trace.ent);
- ent->damage(3, this);
- }
-
- if (!trace.hit || (trace.ent && trace.ent->type != ET_UNIT)) {
- fx_ricochet_t *ricochet;
-
- ricochet = new fx_ricochet_t(game, trace.end);
- ricochet->place(&game->world);
- }
}
+
void unit_soldier_t::target_and_attack(void)
{
unit_t *target;
@@ -155,7 +166,7 @@ skip_targetting:
if (last_attack + game->prng.next_float(1.4f, 1.6f) > game->now)
return;
- shoot(aim);
+ fire_shotgun(aim);
}
void unit_soldier_t::on_think(void)
diff --git a/src/world.cpp b/src/world.cpp
index 0d96234..6688e0b 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -433,6 +433,27 @@ trace_t world_t::ray_v_ents(v2f_t start, v2f_t end, cflags_t cflags,
return best;
}
+trace_t world_t::point_v_tiles(v2f_t at, cflags_t cflags)
+{
+ tile_index_t index;
+ tile_t *tile;
+ trace_t trace;
+
+ index = tile_index_t(at.floor());
+ tile = get_tile(index, SECTOR_FULL);
+
+ if (tiles[tile->type] & cflags) {
+ trace.hit = true;
+ trace.frac = 0.0f;
+ trace.tile = tile;
+ } else {
+ trace.hit = false;
+ trace.frac = 1.0f;
+ }
+
+ trace.end = at;
+ return trace;
+}
trace_t world_t::ray_v_tiles(v2f_t start, v2f_t end, cflags_t cflags)
{
@@ -443,12 +464,8 @@ trace_t world_t::ray_v_tiles(v2f_t start, v2f_t end, cflags_t cflags)
dx = end - start;
quad = quadrant(dx);
- if (quad == 4) {
- res.hit = false;
- res.end = end;
- res.frac = 1.0f;
- return res;
- }
+ if (quad == 4)
+ return point_v_tiles(start, cflags);
start ^= transforms[quad];
dx ^= transforms[quad];