Permalink
Browse files

Spaceship turret defense.

  • Loading branch information...
thebracket committed Jun 2, 2017
1 parent 4c4c990 commit 853ed8eced0c5f29b45feb4b4edf4d0e335d3ce0
View
BIN +15 Bytes (100%) rex/spaceship.xp
Binary file not shown.
@@ -0,0 +1,32 @@
#pragma once
#include <rltk.hpp>
#include <cereal/cereal.hpp>
#include <cereal/types/unordered_set.hpp>
#include <cereal/types/polymorphic.hpp>
using namespace rltk;
struct turret_t {
turret_t() {}
turret_t(const int rng, const int hb, const int n, const int d, const int bonus, const std::size_t civ) : range(rng), hit_bonus(hb),
damage_dice(n),
damage_die(d),
damage_bonus(bonus),
owner_civilization(civ) {}
int range = 6;
int hit_bonus = 0;
int damage_dice = 1;
int damage_die = 6;
int damage_bonus = 0;
std::size_t owner_civilization = 0;
template<class Archive>
void serialize(Archive & archive)
{
archive( range, hit_bonus, damage_dice, damage_die, damage_bonus, owner_civilization ); // serialize things by passing them to the archive
}
};
CEREAL_REGISTER_TYPE(rltk::impl::component_store_t<rltk::impl::component_t<turret_t>>)
@@ -35,6 +35,14 @@ struct settler_ranged_attack_message : public rltk::base_message_t {
std::size_t victim;
};
struct turret_ranged_attack_message : public rltk::base_message_t {
turret_ranged_attack_message() {}
turret_ranged_attack_message(const std::size_t attack, const std::size_t defend) : attacker(attack), victim(defend) {}
std::size_t attacker;
std::size_t victim;
};
struct sentient_attack_message : public rltk::base_message_t {
sentient_attack_message() {}
sentient_attack_message(const std::size_t attack, const std::size_t defend) : attacker(attack), victim(defend) {}
@@ -16,6 +16,8 @@
#include "../../../raws/defs/building_def_t.hpp"
#include "../../../components/receives_signal.hpp"
#include "../../../components/camera_options.hpp"
#include "../../../components/turret_t.hpp"
#include "../../../components/initiative.hpp"
using namespace region;
@@ -54,6 +56,11 @@ void add_building(std::string tag, const int x, const int y, const int z, const
new_building->assign(smoke_emitter_t{});
} else if (tag == "energy_door" || tag == "door") {
new_building->assign(construct_door_t{})->assign(receives_signal_t{});
} else if (tag == "ship_defense_turret") {
std::cout << "Turret created\n";
new_building->assign(viewshed_t{8, false});
new_building->assign(turret_t{8, 0, 1, 8, 0, civ_owner});
new_building->assign(initiative_t{});
}
}
@@ -89,6 +96,8 @@ void add_construction(const int x, const int y, const int z, const std::string t
set_tile(idx, tile_type::STAIRS_UPDOWN, false, false, wood, 0, true, true);
} else if (type == "cordex") {
add_building("cordex", x, y, z, civ_owner);
} else if (type == "ship_defense_turret") {
add_building("ship_defense_turret", x, y, z, civ_owner);
} else if (type == "solar_panel") {
add_building("solar_panel", x, y, z, civ_owner);
} else if (type == "cryo_bed") {
@@ -151,6 +160,9 @@ void build_escape_pod(const int crash_x, const int crash_y, const int crash_z) {
add_construction(x, y, z, "storage_locker", false, 0);
} else if (output->glyph == 'C') {
add_construction(x, y, z, "cordex", false, 0);
} else if (output->glyph == 243) {
std::cout << "Turret detected and built\n";
add_construction(x, y, z, "ship_defense_turret", false, 0);
} else if (output->glyph == 251) {
add_construction(x, y, z, "small_replicator", false, 0);
} else if (output->glyph == 232) {
@@ -56,11 +56,14 @@ void idle_sentient(entity_t &e, ai_tag_my_turn_t &t, sentient_ai &sentient) {
if (sentient.hostile || feelings < 0) {
sentient.goal = SENTIENT_GOAL_KILL;
sentient.hostile = true;
} else {
sentient.goal = SENTIENT_GOAL_IDLE;
sentient.hostile = false;
}
if (sentient.goal == SENTIENT_GOAL_KILL) {
sentient.hostile = true;
//std::cout << "Sentient kill mode\n";
// Close for the kill!
const int idx = mapidx(*pos);
@@ -14,6 +14,7 @@
#include "../../../main/game_pause.hpp"
#include "../../../main/game_designations.hpp"
#include "../../../components/riding_t.hpp"
#include "../../../components/turret_t.hpp"
void ai_visibility_scan::configure() {}
@@ -60,6 +61,51 @@ bool settler_hostile_scan(entity_t &other) {
return false;
}
bool turret_friendly_scan(entity_t &other) {
// A friendly (civ0) turret
if (other.component<grazer_ai>()) {
if (designations->standing_order_wildlife_treatment != standing_orders::SO_WILDLIFE_IGNORE) {
return true;
} else {
return false;
}
}
auto sentient = other.component<sentient_ai>();
if (sentient) {
if (sentient->hostile) {
return true;
} else {
return false;
}
}
return false;
}
bool turret_hostile_scan(entity_t &other) {
bool hostile_sentient = false;
auto other_sentient = other.component<sentient_ai>();
if (other_sentient) {
const std::size_t my_civ = ai_visibility::ai->civ_id;
const std::size_t their_civ = other_sentient->civ_id;
if (my_civ != their_civ) {
auto civfinder = planet.civs.civs[my_civ].relations.find(their_civ);
if (civfinder != planet.civs.civs[my_civ].relations.end()) {
if (civfinder->second < 0) hostile_sentient = true;
}
}
}
if ((other.component<grazer_ai>()) ||
(other.component<settler_ai_t>() && ai_visibility::ai->hostile) ||
hostile_sentient)
{
return true;
}
return false;
}
void ai_visibility_scan::update(const double duration_ms) {
if (pause_mode != RUNNING) return;
@@ -68,6 +114,7 @@ void ai_visibility_scan::update(const double duration_ms) {
auto sentient = e.component<sentient_ai>();
auto settler = e.component<settler_ai_t>();
auto initiative = e.component<initiative_t>();
auto turret = e.component<turret_t>();
std::function<bool(rltk::entity_t&)> scanner_func;
if (grazer) {
@@ -77,6 +124,12 @@ void ai_visibility_scan::update(const double duration_ms) {
ai_visibility::ai = sentient;
} else if (settler) {
scanner_func = settler_hostile_scan;
} else if (turret) {
if (turret->owner_civilization == 0) {
scanner_func = turret_friendly_scan;
} else {
scanner_func = turret_hostile_scan;
}
} else {
throw std::runtime_error("Visibility present, but no AI?");
}
@@ -142,6 +195,11 @@ void ai_visibility_scan::update(const double duration_ms) {
} else {
emit_deferred(entity_wants_to_flee_message{e.id, hostile.closest_fear});
}
} else if (turret) {
const int range = shooting_range(e, pos);
if (range <= turret->range) {
emit_deferred(turret_ranged_attack_message{ e.id, hostile.closest_fear });
}
}
});
}
@@ -7,6 +7,7 @@
#include "../../components/settler_ai.hpp"
#include "../../components/sentient_ai.hpp"
#include "../../planet/region/region.hpp"
#include "../../components/turret_t.hpp"
using namespace rltk;
using namespace region;
@@ -156,11 +157,12 @@ void visibility_system::update(const double duration_ms) {
}
}
// What can we see? - Grazers, Sentients and Settlers only
// What can we see? - Grazers, Sentients, Turrets and Settlers only
auto grazer = e.component<grazer_ai>();
auto settler = e.component<settler_ai_t>();
auto sentient = e.component<sentient_ai>();
if (grazer || settler || sentient) {
auto sentient = e.component<sentient_ai>();
auto turret = e.component<turret_t>();
if (grazer || settler || sentient || turret) {
view.visible_entities.clear();
for (const int &idx : view.visible_cache) {
int x,y,z;
@@ -7,6 +7,7 @@ add_library(damage STATIC
kill_system.cpp
healing_system.cpp
sentient_attacks.cpp
turret_ranged_attack.cpp
)
target_link_libraries(damage rltk utils components raws)
cotire(damage)
@@ -0,0 +1,38 @@
#include "turret_ranged_attack.hpp"
#include "../tasks/civ_dislike.hpp"
#include "../../components/turret_t.hpp"
#include "weapons_helpers.hpp"
#include "../../components/item.hpp"
#include "../../main/game_logger.hpp"
#include "../../main/game_rng.hpp"
#include "../../raws/materials.hpp"
#include "../../raws/defs/item_def_t.hpp"
#include "../../raws/defs/material_def_t.hpp"
using namespace rltk;
void turret_ranged_attack_system::on_message(const turret_ranged_attack_message &msg) {
auto attacker = entity(msg.attacker);
auto defender = entity(msg.victim);
auto turret = attacker->component<turret_t>();
if (!attacker || !defender || !turret) return;
auto attacker_pos = attacker->component<position_t>();
auto defender_pos = defender->component<position_t>();
// Send the bolt on its way
emit(emit_particles_message{3, attacker_pos->x, attacker_pos->y, attacker_pos->z,
defender_pos->x, defender_pos->y, defender_pos->z});
LOG ss;
const int die_roll = rng.roll_dice(1, 20) + turret->hit_bonus;
const int armor_class = calculate_armor_class(*defender);
if (die_roll > armor_class) {
const int damage = std::max(1, rng.roll_dice(turret->damage_dice, turret->damage_dice) + turret->damage_bonus);
ss.text("The turret hits for "+std::to_string(damage)+" points of damage.");
emit(inflict_damage_message{ msg.victim, damage, "turret" });
} else {
ss.text("The turret misses.");
}
emit_deferred(log_message{ss.chars});
}
@@ -0,0 +1,11 @@
#pragma once
#include <rltk.hpp>
#include "../../messages/messages.hpp"
class turret_ranged_attack_system : public rltk::mailbox_system<turret_ranged_attack_message> {
public:
turret_ranged_attack_system() { system_name = "Turret Ranged"; }
virtual void on_message(const turret_ranged_attack_message &msg) override final;
};
@@ -8,6 +8,7 @@
#include "../../components/slidemove.hpp"
#include "../../components/ai_tags/ai_tag_my_turn.hpp"
#include "../../components/riding_t.hpp"
#include "../../components/turret_t.hpp"
void initiative_system::on_message(const tick_message &msg) {
each<initiative_t>([] (entity_t &e, initiative_t &i) {
@@ -37,6 +38,7 @@ void initiative_system::on_message(const tick_message &msg) {
auto sentient_ai_v = e.component<sentient_ai>();
auto grazer_ai_v = e.component<grazer_ai>();
auto mount_v = e.component<riding_t>();
auto turret_v = e.component<turret_t>();
if (mount_v) {
auto mount_entity = entity(mount_v->riding);
@@ -59,6 +61,8 @@ void initiative_system::on_message(const tick_message &msg) {
}
} else if (grazer_ai_v) {
i.initiative = std::max(1, rng.roll_dice(1, 12) - i.initiative_modifier);
} else if (turret_v) {
i.initiative = 10;
}
// Reset modifiers
View
@@ -72,6 +72,7 @@
#include "ai/settler/ai_work_hunt.hpp"
#include "ai/settler/ai_work_butcher.hpp"
#include "physics/explosive_system.hpp"
#include "damage/turret_ranged_attack.hpp"
void add_systems_to_ecs() {
add_system<fluid_system>();
@@ -125,6 +126,7 @@ void add_systems_to_ecs() {
add_system<settler_melee_attacks_system>();
add_system<creature_attacks_system>();
add_system<sentient_attacks_system>();
add_system<turret_ranged_attack_system>();
add_system<damage_system>();
add_system<kill_system>();
add_system<healing_system>();
View
@@ -5,6 +5,13 @@ buildings = {
skill = { name="Construction", difficulty=25 },
render_rex = "cordex.xp"
},
ship_defense_turret = {
name = "Ship Defense Turret",
component = { { item="ship_turret_kit", qty=1 } },
skill = { name="Construction", difficulty=25 },
render = { width=1, height=1, tiles={ {glyph=glyphs['greater_than_equal'], foreground = colors['red'], background = colors['black']} } },
render_ascii = { width=1, height=1, tiles={ {glyph=glyphs['greater_than_equal'], foreground = colors['red'], background = colors['black'] } } }
},
wall = {
name = "Wall", components = { { item="block", qty=1 } }, skill = { name="Construction", difficulty=10 }, structure=true,
provides = { wall={energy_cost=0} },
@@ -242,7 +242,6 @@ buildings["intermediate_forge"] = {
},
};
<<<<<<< HEAD
------------------------------------------------------------------------------------------------------------------------
-- Intermediate forges cover up to medieval forge technology up to the renaissance.
------------------------------------------------------------------------------------------------------------------------
@@ -271,7 +270,6 @@ buildings["advanced_forge"] = {
------------------------------------------------------------------------------------------------------------------------
-- Intermediate forges cover up to medieval forge technology up to the renaissance.
=======
reactions["make_light_mace"] = {
name = "Make Light Mace",
workshop = "intermediate_forge",
@@ -382,13 +382,6 @@ buildings["intermediate_workshop"] = {
},
};
<<<<<<< HEAD
reactions["make_precision_tools"] = {
name = "Make Precision Tools",
workshop = "intermediate_workshop",
inputs = { { item="block", material="wood", qty=2 }, { item="block", qty=2, mat_type="metal" } },
outputs = { { item="precision_tools", qty=1 } },
=======
reactions["make_heavy_crossbow"] = {
name = "Make Heavy Crossbow",
workshop = "intermediate_workshop",
Oops, something went wrong.

0 comments on commit 853ed8e

Please sign in to comment.