#include "common.hpp"
#include <iostream>
Avatar::Avatar(INETsocket controller){
sock=controller;
health=(float)0x100;
}
bool Avatar::Move(string destination, Container&location, unsigned int myindex) {
map<string,weak_ptr<Room> >* links=location.exits();
map<string,weak_ptr<Room> >::iterator where=links->find(destination);
if (where!=links->end()) {
where->second.lock()->getThing(myindex,location);
return true;
}
return false;
}
void Avatar::privateMessage(SENSES sense,std::string message) {
size_t len=messge.length()+1;
unsigned char csense[5]{len%256,(len/256)%256,(len/65536)%256,sense};
INET_Write(sock,&csense,4);
INET_Write(sock,message.data(),message.length());
}
void Avatar::tick(shared_ptr<Thing>&location, unsigned int myindex) {
Container::tick(location,myindex);
float tmp1=(float)floor(health);
health-=1.0f/1024.0f;
float tmp2=(float)floor(health);
if (tmp1!=tmp2) {
static std::string hungry("hungry");
privateMessage(FEEL,hungry);
}
Container * place=static_cast<Container*>(location->get());
if (INET_BytesToRead(sock)) {
char cmd[4];
int arg;
INET_Read(sock,cmd,1);
switch(cmd[0]) {
case 'g'://get
arg=getSArg(sock);
for (int index=0;index<place->numItems();++index) {
if (index!=myindex&&(arg=="all"||place->examineItem(index)->description()==arg)) {
if (!getThing(*place,index)) {
//return failure
}
}
}
break;
case 'm'://move
if (!Move(getSArg(sock),*place,myindex)) {
//return failure
}
break;
case 'e'://eat
if (!Eat(getSArg(sock))) {
//return failure
}
break;
case 'i'://inventory
getSArg(sock);
//FIXME
break;
case 'r'://reproduce
arg=getSArg(sock);
for (int index=0;index<location->numItems();++index) {
if (index!=myindex&&(arg=="all"||place->examineItem(index)->description()==arg)) {
if (!reproduce(*this,location)) {
//return failure
}
}
}
break;
case 'd'://change description
desc=getSArg(sock);
break;
}
}
//FIXME process client commands
//FIXME send update to client
}
void Avatar::addHealth(float health) {
this->health+=health;
if (health>0) {
privateMessage(TASTE,"tasty");
}else {
privateMessage(TASTE,"foul");
}
}
map <Avatar*,Avatar*> consent;
vector<std::pair<GeneticCode,shared_ptr<Container> > >newlyborngrue;
vector<std::pair<GeneticCode,shared_ptr<Container> > >newlybornsnark;
bool Grue::canConnect() {
return newlyborngrue().size()>1
}
bool Snark::canConnect() {
return newlybornsnark().size()>1
}
bool Grue::reproduce(Avatar&who, shared_ptr<Container>¤tLocation) {
Grue*partner;
if (!(partner=dynamic_cast<Grue*>(&who))) {
return false;
}
if (consent[partner]==this) {
consent.erase(consent.find(partner));
newlyborngrue.push_back(std::pair<GeneticCode,shared_ptr<Container> >(GeneticCode(code,partner->code),currentLocation));
}else {
consent[this]=partner;
}
}
bool Snark::reproduce(Avatar&who, shared_ptr<Container>¤tLocation) {
Snark*partner;
if (!(partner=dynamic_cast<Snark*>(&who))) {
return false;
}
if (consent[partner]==this) {
consent.erase(consent.find(partner));
newlybornsnark.push_back(std::pair<GeneticCode,shared_ptr<Container> >(GeneticCode(code,partner->code),currentLocation));
}else {
consent[this]=partner;
}
}
bool Avatar::Eat(string desc) {
bool all=(desc=="all");
for (std::vector<shared_ptr<Thing> >::iterator it=items.begin(),end=items.end();
it!=end;
++it) {
if (desc==it->get()->description()||all) {
if (it->get()->EatMe(*this)) {
*it=items.back();
items.pop_back();
if (!all)
return true;
}
}
}
return false;
}
Avatar::~Avatar() {
std::cout << description()<<" died\n";
}
Grue::~Grue(){}
Snark::~Snark(){}
bool Grue::getThing(unsigned int thingindex, Container&previous) {
Thing* item=previous.examineItem(thingindex);
Grue * tmp=dynamic_cast<Grue*> (item);
if (tmp) return false;
Avatar * tmp1=dynamic_cast<Avatar*> (item);
if (tmp1&&previous.lightness()>.5) {
return false;
}
if (!tmp1) return false;//carnivore
return this->Avatar::getThing(thingindex,previous);
}
bool Grue::takeMe(Container& destination, Container& currentLocation) {
return false;///impervious to attack
}
bool Snark::EatMe(Avatar& thing) {
thing.addHealth(100);
}
bool Snark::getThing(unsigned int thingindex, Container&previous) {
Thing* item=previous.examineItem(thingindex);
Avatar * tmp=dynamic_cast<Avatar*> (item);
if (tmp)return false;
return Avatar::getThing(thingindex,previous);
}
bool Snark::takeMe(Container& destination, Container& currentLocation) {
for (std::vector<shared_ptr<Thing> >::iterator it=currentLocation.items.begin(),end=currentLocation.items.end();
it!=end;
++it) {
Thing*tmp=it->get();
if (dynamic_cast<Snark*>(tmp)) return false;
}
return Avatar::takeMe(destination,currentLocation);
}
Grue::Grue (INETsocket controller):Avatar(controller) {
static string grue("Grue");
desc=grue;
if (newlyborngrue.size()) {
code=newlyborngrue.back().first;
}
}
Snark::Snark (INETsocket controller):Avatar(controller) {
static string snark("Snark");
desc=snark;
if (newlybornsnark.size()) {
code=newlybornsnark.back().first;
}
}