Commit aaa9a335 authored by louiz’'s avatar louiz’

Add a BUILD network command, and send it to the server and back to the clients.

parent ea9847dc
......@@ -72,4 +72,22 @@ DoEntityEvent::DoEntityEvent(const Command* command):
this->valid = true;
}
BuildEvent::BuildEvent(const Command* command)
{
if (this->from_string(std::string(command->body,
command->body_size).c_str()) == false)
this->valid = false;
else
this->valid = true;
}
DoBuildEvent::DoBuildEvent(const Command* command):
ActionEvent("BUILD")
{
if (this->from_string(std::string(command->body,
command->body_size).c_str()) == false)
this->valid = false;
else
this->valid = true;
}
unsigned long int Event::current_id = 0;
......@@ -86,7 +86,7 @@ public:
* Just an event containing a turn number, saying that
* the action generated by this event must be scheduled for this turn.
*/
class ActionEvent: public Event
class ActionEvent: virtual public Event
{
public:
ActionEvent(const std::string& name):
......@@ -169,8 +169,12 @@ private:
class DoMoveEvent: public ActionEvent
{
public:
DoMoveEvent():
ActionEvent("PATH")
DoMoveEvent(const Command*);
DoMoveEvent(const MoveEvent& e):
ActionEvent("PATH"),
actors_ids(e.actors_ids),
x(e.x),
y(e.y)
{}
virtual void serialize(boost::archive::text_oarchive& ar, const unsigned int v)
......@@ -184,17 +188,78 @@ public:
ar & actors_ids & x & y;
}
DoMoveEvent(const Command*);
DoMoveEvent(const MoveEvent& e):
ActionEvent("PATH"),
actors_ids(e.actors_ids),
x(e.x),
y(e.y)
{}
std::vector<unsigned short> actors_ids;
uint x;
uint y;
};
class BuildEvent: virtual public Event
{
public:
BuildEvent(): Event() {}
BuildEvent(const Command*);
BuildEvent(const BuildEvent& e):
Event(),
type_id(e.type_id),
x(e.x),
y(e.y),
actor(e.actor)
{ }
virtual void serialize(boost::archive::text_oarchive& ar, const unsigned int v)
{
Event::serialize(ar, v);
ar & type_id & x & y & actor;
}
virtual void serialize(boost::archive::text_iarchive& ar, const unsigned int v)
{
Event::serialize(ar, v);
ar & type_id & x & y & actor;
}
/**
* The type_id of the building to build.
*/
unsigned short type_id;
/**
* The top left cell on which the building is to be placed.
*/
short x;
short y;
/**
* The id of the unit thas has to build the unit.
*/
unsigned short actor;
private:
BuildEvent& operator=(const BuildEvent&);
};
class DoBuildEvent: public ActionEvent, public BuildEvent
{
public:
DoBuildEvent(const Command*);
DoBuildEvent(const BuildEvent& o):
ActionEvent("BUILD"),
BuildEvent(o)
{
}
~DoBuildEvent() {};
virtual void serialize(boost::archive::text_oarchive& ar, const unsigned int v)
{
BuildEvent::serialize(ar, v);
}
virtual void serialize(boost::archive::text_iarchive& ar, const unsigned int v)
{
BuildEvent::serialize(ar, v);
}
private:
DoBuildEvent(const DoBuildEvent&);
DoBuildEvent& operator=(const DoBuildEvent&);
};
#endif // __EVENT_HPP__
/**@}*/
......@@ -8,6 +8,7 @@ namespace cursor
Normal,
Select,
Move,
Build,
Aim,
Cast,
// Just keep track of the possible number of cursors
......@@ -19,6 +20,7 @@ namespace cursor
"gui_cursor.png",
"gui_cursor.png",
"move_cursor.png",
"build_cursor.png",
"gui_cursor.png",
"gui_cursor.png"
};
......
......@@ -37,22 +37,26 @@ ActionPanelTable::ActionPanelTable(Screen* screen):
page->add_button(new ActionPanelButton("./data/images/actions/stop.png",
0, 1, null_left, cursor::Normal),
1);
page->add_button(new ActionPanelButton("./data/images/actions/keep_position.png",
0, 2, null_left, cursor::Normal),
2);
page->add_button(new ActionPanelButton("./data/images/actions/patrol.png",
0, 3, null_left, cursor::Normal),
3);
page->add_button(new ActionPanelButton("./data/images/actions/attack.png",
0, 4, null_left, cursor::Normal),
4);
page = new ActionPanelPage();
this->pages.push_back(page);
t_left_click_callback build_callback = boost::bind(&ClientWorld::action_build, world, _1, _2, _3);
t_left_click left_click_build;
left_click_build.callback = build_callback;
left_click_build.id = 0;
ActionPanelButton* building_button = new ActionPanelButton("./data/images/actions/build_archive.png",
boost::bind(&Screen::set_left_click_callback, screen, _1, _2), 1, left_click_build, cursor::Build);
page->add_button(building_button, 1);
}
......
......@@ -26,6 +26,7 @@ void RemoteGameClient::install_callbacks()
this->install_callback("OK", boost::bind(&RemoteGameClient::ok_callback, this, _1));
this->install_callback("T", boost::bind(&RemoteGameClient::turn_callback, this, _1));
this->install_callback("MOVE", boost::bind(&ServerWorld::move_callback, world, _1));
this->install_callback("BUILD", boost::bind(&ServerWorld::build_callback, world, _1));
}
boost::asio::io_service& RemoteGameClient::get_io_service()
......
......@@ -115,6 +115,12 @@ void ClientWorld::path_callback(Command* command)
this->insert_received_action(action, e);
}
void ClientWorld::build_callback(Command* command)
{
DoBuildEvent* e = new DoBuildEvent(command);
log_info("Build_callback: " << e->actor << " " << e->x << ":" << e->y);
}
void ClientWorld::insert_received_action(Action* action, ActionEvent* event)
{
this->turn_handler->insert_action(action, event->turn);
......@@ -148,6 +154,19 @@ void ClientWorld::on_next_turn(unsigned long turn)
this->confirm_turn(turn+1);
}
bool ClientWorld::action_build(const unsigned int x, const unsigned y, const std::size_t id)
{
log_info("action_build: " << x << ":" << y << "=" << id);
assert(this->current_selection.is_empty() == false);
BuildEvent event;
event.actor = this->current_selection.get_entities().front()->id;
Position pos(x, y);
this->get_cell_at_position(pos, event.x, event.y);
event.type_id = id;
this->generate_command("BUILD", event.to_string());
return true;
}
bool ClientWorld::action_move(const unsigned int x, const unsigned y, const std::size_t)
{
MoveEvent event;
......
......@@ -57,6 +57,10 @@ public:
* The server gives a path to follow, to one or more entities.
*/
void path_callback(Command*);
/**
* The server tells one unit to build the given building
*/
void build_callback(Command*);
/**
* Insert an action, built from a command we received, into the turn handler,
* and confirm it or validate it, depending on if the game is started or not
......@@ -79,6 +83,7 @@ public:
* world coordinates.
*/
bool action_move(const unsigned int x, const unsigned y, const std::size_t=0);
bool action_build(const unsigned int, const unsigned int, const std::size_t);
/**
* Give the order to all selected and movable units to move to the given
* world coordinates with an attack order (will attack all encountered
......
......@@ -57,8 +57,6 @@ void ServerWorld::init()
void ServerWorld::move_callback(Command* command)
{
// TODO, do an actuall path finding, and other stuff, and
// generate a DoMoveEvent, instead of a MoveEvent.
MoveEvent event(command);
if (event.is_valid() == false)
{
......@@ -76,6 +74,23 @@ void ServerWorld::move_callback(Command* command)
this->turn_handler->insert_action(action, path_event->turn);
}
void ServerWorld::build_callback(Command* command)
{
BuildEvent event(command);
if (event.is_valid() == false)
{
log_warning("Invalid data for BUILD command");
return ;
}
// Here check for command validity etc etc.
// if the command is valid, just return a DoBuildEvent with the same value
DoBuildEvent* doevent = new DoBuildEvent(event);
doevent->turn = this->turn_handler->get_current_turn() + 2;
this->generate_command("BUILD", doevent->to_string());
Action* action = new Action(0, doevent, this->occupants.size());
this->turn_handler->insert_action(action, doevent->turn);
}
bool ServerWorld::validate_action(const unsigned int id, const unsigned long int by)
{
log_debug("Action " << id << " validated by " << by);
......
......@@ -27,6 +27,11 @@ public:
* send that path action to all clients.
*/
void move_callback(Command*);
/**
* Called whenever we receive a BUILD command from one client.
* Check if the position is valid and the building can be built (money, the unit actually has this ability, etc).
*/
void build_callback(Command*);
bool validate_action(const unsigned int id, const unsigned long int by);
bool validate_turn(const unsigned int id, const unsigned long int by);
/**
......
......@@ -34,6 +34,8 @@ int main()
boost::bind(&ClientWorld::turn_callback, world, _1));
c->install_callback("PATH",
boost::bind(&ClientWorld::path_callback, world, _1));
c->install_callback("BUILD",
boost::bind(&ClientWorld::build_callback, world, _1));
// c->connect("88.190.23.192", 7879);
c->connect("127.0.0.1", 7879);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment