Permalink
Browse files

Basic mounts are in. Need work.

  • Loading branch information...
thebracket committed May 19, 2017
1 parent 563f176 commit 4e1654bd6bd93400c83e6ea859ec5b86c438ff17
@@ -0,0 +1,22 @@
#pragma once
#include <rltk.hpp>
#include <string>
#include <cereal/cereal.hpp>
#include <cereal/types/polymorphic.hpp>
using namespace rltk;
struct riding_t {
std::size_t riding;
riding_t() {}
riding_t(const std::size_t carrier) : riding(carrier) {}
template<class Archive>
void serialize(Archive & archive)
{
archive( riding ); // serialize things by passing them to the archive
}
};
CEREAL_REGISTER_TYPE(rltk::impl::component_store_t<rltk::impl::component_t<riding_t>>)
@@ -17,7 +17,10 @@
#include "../../components/natural_attacks_t.hpp"
#include "../../components/renderable_composite.hpp"
#include "../region/region.hpp"
#include "../raws/defs/civilization_t.hpp"
#include "../../raws/defs/civilization_t.hpp"
#include "../../raws/defs/raw_creature_t.hpp"
#include "../../raws/creatures.hpp"
#include "../../components/riding_t.hpp"
int sentient_get_stat_mod(const std::string stat, const raw_species_t * species) {
if (!species) return 0;
@@ -168,6 +171,45 @@ void create_sentient(planet_t &planet, rltk::random_number_generator &rng, std::
ammo->component<item_t>()->category = finder->categories;
ammo->component<item_t>()->claimed = true;
}
if (unit.equipment.mount != "") {
std::cout << "Spawning a mount: " << unit.equipment.mount << "\n";
// Spawn a mount at the same location, with a riding_t tag on the sentient
auto critter_def = get_creature_def( unit.equipment.mount );
bool male = true;
if (rng.roll_dice(1,4)<=2) male = false;
name_t name{};
name.first_name = critter_def->name;
if (male) {
name.last_name = critter_def->male_name;
} else {
name.last_name = critter_def->female_name;
}
game_stats_t stats;
stats.profession_tag = "Mount";
stats.age = 1;
for (auto it=critter_def->stats.begin(); it!=critter_def->stats.end(); ++it) {
if (it->first == "str") stats.strength = it->second;
if (it->first == "dex") stats.dexterity = it->second;
if (it->first == "con") stats.constitution = it->second;
if (it->first == "int") stats.intelligence = it->second;
if (it->first == "wis") stats.wisdom = it->second;
if (it->first == "cha") stats.charisma = it->second;
}
auto mount = create_entity()
->assign(position_t{x,y,z})
->assign(renderable_t{critter_def->glyph, critter_def->glyph_ascii, critter_def->fg, rltk::colors::BLACK})
->assign(std::move(name))
->assign(std::move(stats))
->assign(create_health_component_creature(critter_def->tag))
->assign(initiative_t{})
->assign(ai_mode_idle_t{});
// Remove the position_t from the parent and assign a riding marker
sentient->assign(riding_t{mount->id});
}
if (announce) {
emit_deferred(log_message{
@@ -55,6 +55,7 @@ struct civ_equipment_t {
std::string melee = "";
std::string ranged = "";
std::string ammo = "";
std::string mount = "";
};
struct civ_unit_sentient_t {
View
@@ -135,6 +135,7 @@ void read_civ_types() noexcept
if (afield == "melee") equip.melee = lua_tostring(lua_state, -1);
if (afield == "ranged") equip.ranged = lua_tostring(lua_state, -1);
if (afield == "ammo") equip.ammo = lua_tostring(lua_state, -1);
if (afield == "mount") equip.mount = lua_tostring(lua_state, -1);
if (afield == "both" || afield == "male" || afield == "female") {
lua_pushstring(lua_state, afield.c_str());
lua_gettable(lua_state, -2);
@@ -7,6 +7,7 @@
#include "../../components/settler_ai.hpp"
#include "../../planet/region/region.hpp"
#include "../../main/game_rng.hpp"
#include "../../components/riding_t.hpp"
using namespace region;
@@ -98,6 +99,17 @@ void movement_system::configure() {
emit_deferred(vegetation_damage_message{idx, 1});
}
auto mounted = entity(msg.entity_id)->component<riding_t>();
if (mounted) {
auto mount_pos = entity(mounted->riding)->component<position_t>();
mount_pos->x = epos->x;
mount_pos->y = epos->y;
mount_pos->z = epos->z;
mount_pos->offsetX = epos->offsetX;
mount_pos->offsetY = epos->offsetY;
mount_pos->offsetZ = epos->offsetZ;
}
emit(entity_moved_message{msg.entity_id, origin, msg.destination});
emit(renderables_changed_message{});
});
@@ -14,6 +14,7 @@
#include "../../../main/game_rng.hpp"
#include "../../../raws/raws.hpp"
#include "../../../raws/materials.hpp"
#include "../../../components/riding_t.hpp"
using namespace region;
@@ -41,7 +42,16 @@ void idle_grazer(entity_t &e, ai_tag_my_turn_t &t, grazer_ai &grazer) {
}
void idle_sentient(entity_t &e, ai_tag_my_turn_t &t, sentient_ai &sentient) {
auto mounted = e.component<riding_t>();
auto pos = e.component<position_t>();
if (mounted) {
auto mount = entity(mounted->riding);
if (!mount) {
delete_component<riding_t>(e.id);
}
}
int feelings = planet.civs.civs[sentient.civ_id].cordex_feelings;
if (sentient.hostile || feelings < 0) {
@@ -13,6 +13,7 @@
#include "../../../components/initiative.hpp"
#include "../../../main/game_pause.hpp"
#include "../../../main/game_designations.hpp"
#include "../../../components/riding_t.hpp"
void ai_visibility_scan::configure() {}
@@ -104,12 +105,18 @@ void ai_visibility_scan::update(const double duration_ms) {
} else if (sentient) {
// Run away! Eventually, we want the option for combat here based on morale. Also, when hunting
// is implemented it's a good idea not to run away from your target.
auto mounted = e.component<riding_t>();
const float range = shooting_range(e, pos);
if (hostile.terror_distance < 1.5F) {
// Hit it with melee weapon
emit_deferred(sentient_attack_message{e.id, hostile.closest_fear});
initiative->initiative_modifier += get_weapon_initiative_penalty(get_melee_id(e));
delete_component<ai_tag_my_turn_t>(e.id);
if (mounted) {
// Let the mount attack also
emit_deferred(creature_attack_message(mounted->riding, hostile.closest_fear));
}
} else if ( range != -1 && range < hostile.terror_distance) {
// Shoot it
emit_deferred(sentient_ranged_attack_message{e.id, hostile.closest_fear});
@@ -119,6 +126,7 @@ void ai_visibility_scan::update(const double duration_ms) {
emit_deferred(entity_wants_to_charge_message{e.id, hostile.closest_fear});
ai_visibility::ai->goal = SENTIENT_GOAL_CHARGE;
}
} else if (settler) {
// Run away! Eventually, we want the option for combat here based on morale. Also, when hunting
// is implemented it's a good idea not to run away from your target.
@@ -141,7 +141,7 @@ void mode_units_system::render_creatures() {
void mode_units_system::render_natives() {
std::vector<std::pair<std::size_t, std::string>> natives;
each<sentient_ai, name_t>([&natives] (entity_t &e, sentient_ai &ai, name_t &name) {
natives.emplace_back(std::make_pair(e.id, name.first_name + std::string(" ") + name.last_name));
natives.emplace_back(std::make_pair(e.id, name.first_name + std::string(" ") + name.last_name + std::string(" #") + std::to_string(e.id)));
});
const char* native_listbox_items[natives.size()];
for (int i=0; i<natives.size(); ++i) {
@@ -151,7 +151,7 @@ void mode_units_system::render_natives() {
ImGui::PushItemWidth(-1);
ImGui::ListBox("## Natives", &current_native, native_listbox_items, natives.size(), 10);
if (ImGui::Button(std::string(btn_goto + std::string(" ")).c_str())) {
auto selected_critter = natives[current_settler].first;
auto selected_critter = natives[current_native].first;
auto the_critter = entity(selected_critter);
if (the_critter) {
auto pos = the_critter->component<position_t>();
@@ -7,6 +7,7 @@
#include "../tasks/initiative.hpp"
#include "../../components/slidemove.hpp"
#include "../../components/ai_tags/ai_tag_my_turn.hpp"
#include "../../components/riding_t.hpp"
void initiative_system::on_message(const tick_message &msg) {
each<initiative_t>([] (entity_t &e, initiative_t &i) {
@@ -35,8 +36,18 @@ void initiative_system::on_message(const tick_message &msg) {
auto settler_ai_v = e.component<settler_ai_t>();
auto sentient_ai_v = e.component<sentient_ai>();
auto grazer_ai_v = e.component<grazer_ai>();
auto mount_v = e.component<riding_t>();
if (settler_ai_v) {
if (mount_v) {
auto mount_entity = entity(mount_v->riding);
if (!mount_entity) {
// Mount has gone away - be confused and revert to old behavior!
delete_component<riding_t>(e.id);
} else {
auto stats = mount_entity->component<game_stats_t>(); // Use the mount's initiative
if (stats) tasks::calculate_initiative(i, *stats);
}
} else if (settler_ai_v) {
auto stats = e.component<game_stats_t>();
if (stats) {
tasks::calculate_initiative(i, *stats);
@@ -48,8 +59,6 @@ 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 {
std::cout << "Warning: Entity has initiative but no AI???\n";
}
// Reset modifiers
Oops, something went wrong.

0 comments on commit 4e1654b

Please sign in to comment.