Skip to content

Commit

Permalink
Merge pull request #120 from benjamg/feature/npc
Browse files Browse the repository at this point in the history
Can't really be any more broken, right?
Feature/npc
  • Loading branch information
kevingranade committed Mar 19, 2013
2 parents 5ef8bca + 575ea54 commit e9b91cd
Show file tree
Hide file tree
Showing 18 changed files with 374 additions and 35 deletions.
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 @@ -4776,17 +4776,26 @@ void game::examine()
} while (u.cash >= 10 && query_yn(this->VIEWX, this->VIEWY, "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 @@ -2410,6 +2410,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

0 comments on commit e9b91cd

Please sign in to comment.