Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/npc #120

Merged
merged 14 commits into from
Mar 19, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions basecamp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include <algorithm>
#include <sstream>

#include "basecamp.h"

basecamp::basecamp()
: name()
, posx(0), posy(0)
{

}

basecamp::basecamp(std::string const& name_, int const posx_, int const posy_)
: name(name_)
, posx(posx_), posy(posy_)
{

}

std::string basecamp::board_name() const
{
return name + " Board";
}

std::string basecamp::save_data() const
{
std::stringstream data;

// TODO: This will lose underscores, is that a problem?
// strip spaces from name
std::string savename = name;
replace(savename.begin(), savename.end(), ' ', '_');

data << savename << " " << posx << " " << posy;
return data.str();
}

void basecamp::load_data(std::string const& data)
{
std::stringstream stream(data);
stream >> name >> posx >> posy;

// add space to name
replace(name.begin(), name.end(), '_', ' ');
}
29 changes: 29 additions & 0 deletions basecamp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef _BASECAMP_H_
#define _BASECAMP_H_

#include <string>

class basecamp
{
public:
basecamp();
basecamp(std::string const& name_, int const posx_, int const posy_);

inline bool is_valid() const { return !name.empty(); }
inline int board_x() const { return posx; }
inline int board_y() const { return posy; }
inline std::string const& camp_name() const { return name; }

std::string board_name() const;

// Save/load
std::string save_data() const;
void load_data(std::string const& data);

private:
std::string name;
int posx, posy; // location of associated bulletin board
};


#endif
9 changes: 9 additions & 0 deletions construction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,15 @@ void game::init_construction()
COMP(itm_2x4, 8, NULL);
COMP(itm_nail, 40, NULL);

// Base stuff
CONSTRUCT("Build Bulletin Board", 0, &construct::able_empty,
&construct::done_nothing);
STAGE(t_bulletin, 10)
TOOL(itm_saw, NULL);
TOOL(itm_hammer, itm_hatchet, itm_nailgun, NULL);
COMP(itm_2x4, 4, NULL);
COMP(itm_nail, 8, NULL);

// Household stuff
CONSTRUCT("Build Dresser", 1, &construct::able_indoors,
&construct::done_nothing);
Expand Down
2 changes: 2 additions & 0 deletions dialogue.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct talk_function
void mission_favor (game *g, npc *p);
void give_equipment (game *g, npc *p);
void start_trade (game *g, npc *p);
void assign_base(game *g, npc *p);
void follow (game *g, npc *p); // p follows u
void deny_follow (game *g, npc *p); // p gets DI_ASKED_TO_FOLLOW
void deny_lead (game *g, npc *p); // p gets DI_ASKED_TO_LEAD
Expand All @@ -58,6 +59,7 @@ struct talk_function
void start_training (game *g, npc *p);

void toggle_use_guns (game *g, npc *p);
void toggle_use_silent (game *g, npc *p);
void toggle_use_grenades (game *g, npc *p);
void set_engagement_none (game *g, npc *p);
void set_engagement_close (game *g, npc *p);
Expand Down
31 changes: 20 additions & 11 deletions game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5218,17 +5218,26 @@ void game::examine()
} while (u.cash >= 10 && query_yn("Play again?"));
}
} else if (m.ter(examx, examy) == t_bulletin) {
// TODO: Bulletin Boards
switch (menu("Bulletin Board", "Check jobs", "Check events",
"Check other notices", "Post notice", "Cancel", NULL)) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
basecamp *camp = m.camp_at(examx, examy);
if (camp && camp->board_x() == examx && camp->board_y() == examy) {
std::vector<std::string> options;
options.push_back("Cancel");
int choice = menu_vec(camp->board_name().c_str(), options) - 1;
}
else {
bool create_camp = m.allow_camp(examx, examy);
std::vector<std::string> options;
if (create_camp)
options.push_back("Create camp");
options.push_back("Cancel");
// TODO: Other Bulletin Boards
int choice = menu_vec("Bulletin Board", options) - 1;
if (choice >= 0 && choice < options.size()) {
if (options[choice] == "Create camp") {
// TODO: Allow text entry for name
m.add_camp("Home", examx, examy);
}
}
}
} else if (m.ter(examx, examy) == t_fault) {
popup("\
Expand Down
13 changes: 13 additions & 0 deletions item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1176,6 +1176,19 @@ bool item::is_gun()
return type->is_gun();
}

bool item::is_silent()
{
if ( is_null() )
return false;

// So far only gun code uses this check
return type->is_gun() && (
noise() < 5 || // almost silent
curammo->type == AT_BOLT || // crossbows
curammo->type == AT_ARROW // bows
);
}

bool item::is_gunmod()
{
if( is_null() )
Expand Down
1 change: 1 addition & 0 deletions item.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ class item
bool is_bashing_weapon();
bool is_cutting_weapon();
bool is_gun();
bool is_silent();
bool is_gunmod();
bool is_bionic();
bool is_ammo();
Expand Down
45 changes: 44 additions & 1 deletion map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ void map::board_vehicle(game *g, int x, int y, player *p)
return;
}
veh->parts[seat_part].set_flag(vehicle_part::passenger_flag);
veh->parts[seat_part].passenger_id = 0; // Player is 0
veh->parts[seat_part].passenger_id = p->id; // Player is 0

p->posx = x;
p->posy = y;
Expand Down Expand Up @@ -2409,6 +2409,49 @@ computer* map::computer_at(const int x, const int y)
return &(grid[nonant]->comp);
}

bool map::allow_camp(const int x, const int y, const int radius)
{
return camp_at(x, y, radius) == NULL;
}

basecamp* map::camp_at(const int x, const int y, const int radius)
{
// locate the nearest camp in a CAMPSIZE radius
if (!INBOUNDS(x, y))
return NULL;

const int sx = std::max(0, x / SEEX - CAMPSIZE);
const int sy = std::max(0, y / SEEY - CAMPSIZE);
const int ex = std::min(MAPSIZE - 1, x / SEEX + CAMPSIZE);
const int ey = std::min(MAPSIZE - 1, y / SEEY + CAMPSIZE);

for( int ly = sy; ly < ey; ++ly )
{
for( int lx = sx; lx < ex; ++lx )
{
int nonant = lx + ly * my_MAPSIZE;
if (grid[nonant]->camp.is_valid())
{
// we only allow on camp per size radius, kinda
return &(grid[nonant]->camp);
}
}
}

return NULL;
}

void map::add_camp(const std::string& name, const int x, const int y)
{
if (!allow_camp(x, y)) {
dbg(D_ERROR) << "map::add_camp: Attempting to add camp when one in local area.";
return;
}

const int nonant = int(x / SEEX) + int(y / SEEY) * my_MAPSIZE;
grid[nonant]->camp = basecamp(name, x, y);
}

void map::debug()
{
mvprintw(0, 0, "MAP DEBUG");
Expand Down
7 changes: 7 additions & 0 deletions map.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include "graffiti.h"

#define MAPSIZE 11
#define CAMPSIZE 1
#define CAMPCHECK 3

class player;
class item;
Expand Down Expand Up @@ -164,6 +166,11 @@ class map
// Computers
computer* computer_at(const int x, const int y);

// Camps
bool allow_camp(const int x, const int y, const int radius = CAMPCHECK);
basecamp* camp_at(const int x, const int y, const int radius = CAMPSIZE);
void add_camp(const std::string& name, const int x, const int y);

// Graffiti
graffiti graffiti_at(int x, int y);
bool add_graffiti(game *g, int x, int y, std::string contents);
Expand Down
7 changes: 7 additions & 0 deletions mapbuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ void mapbuffer::save()
if (sm->comp.name != "")
fout << "c " << sm->comp.save_data() << std::endl;

// Output base camp if any
if (sm->camp.is_valid())
fout << "B " << sm->camp.save_data() << std::endl;

// Output the graffiti
for (int j = 0; j < SEEY; j++) {
for (int i = 0; i < SEEX; i++) {
Expand Down Expand Up @@ -281,6 +285,9 @@ void mapbuffer::load()
} else if (string_identifier == "c") {
getline(fin, databuff);
sm->comp.load_data(databuff);
} else if (string_identifier == "B") {
getline(fin, databuff);
sm->camp.load_data(databuff);
} else if (string_identifier == "G") {
std::string s;
int j;
Expand Down
2 changes: 2 additions & 0 deletions mapdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "computer.h"
#include "vehicle.h"
#include "graffiti.h"
#include "basecamp.h"
#include <iosfwd>

class game;
Expand Down Expand Up @@ -798,6 +799,7 @@ struct submap {
std::vector<spawn_point> spawns;
std::vector<vehicle*> vehicles;
computer comp;
basecamp camp; // only allowing one basecamp per submap
};

std::ostream & operator<<(std::ostream &, const submap *);
Expand Down
1 change: 1 addition & 0 deletions mapgen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ void map::generate(game *g, overmap *om, int x, int y, int turn)
grid[i]->field_count = 0;
grid[i]->turn_last_touched = turn;
grid[i]->comp = computer();
grid[i]->camp = basecamp();
for (int x = 0; x < SEEX; x++) {
for (int y = 0; y < SEEY; y++) {
grid[i]->ter[x][y] = t_null;
Expand Down
31 changes: 31 additions & 0 deletions npc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1303,6 +1303,37 @@ int npc::player_danger(player *u)
return ret;
}

int npc::vehicle_danger(game *g, int radius)
{
VehicleList vehicles = g->m.get_vehicles(posx - radius, posy - radius, posx + radius, posy + radius);

int danger = 0;

// TODO: check for most dangerous vehicle?
for(size_t i = 0; i < vehicles.size(); ++i)
if (vehicles[i].v->velocity > 0)
{
float facing = vehicles[i].v->face.dir();

int ax = vehicles[i].v->global_x();
int ay = vehicles[i].v->global_y();
int bx = ax + cos (facing * M_PI / 180.0) * radius;
int by = ay + sin (facing * M_PI / 180.0) * radius;

// fake size
int last_part = vehicles[i].v->external_parts.back();
int size = std::max(vehicles[i].v->parts[last_part].mount_dx, vehicles[i].v->parts[last_part].mount_dy);

float normal = sqrt((bx - ax) * (bx - ax) + (by - ay) * (by - ay));
int closest = abs((posx - ax) * (by - ay) - (posy - ay) * (bx - ax)) / normal;

if (size > closest)
danger = i;
}

return danger;
}

bool npc::turned_hostile()
{
return (op_of_u.anger >= hostile_anger_level());
Expand Down
Loading