summaryrefslogtreecommitdiff
path: root/src/organism.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/organism.cpp')
-rw-r--r--src/organism.cpp193
1 files changed, 193 insertions, 0 deletions
diff --git a/src/organism.cpp b/src/organism.cpp
new file mode 100644
index 0000000..27f6f8a
--- /dev/null
+++ b/src/organism.cpp
@@ -0,0 +1,193 @@
+#include "organism.hpp"
+
+Organism::Organism(Rectangle r, DNA d)
+{
+ rect = r;
+ myDNA = d;
+
+ if(rect.x == 0 && rect.y == 0){
+ rect.x = getRandom(30);
+ rect.y = getRandom(30);
+ }
+
+ health = myDNA.maxHealth/2;
+ gender = rand() % 2;
+ age = 0;
+ pregnancyTime = 0;
+ pregnancyReady = false;
+ pregnate = false;
+ hasTarget = false;
+ wander = false;
+
+ if(myDNA.type == CREATURE_TYPE){
+ if(gender)
+ gfxData = GraphicsData(rect.x, rect.y, 1, 0, 0, CREATURE_SIDES);
+ else
+ gfxData = GraphicsData(rect.x, rect.y, 0, 0, 1, CREATURE_SIDES);
+ }
+ else
+ gfxData = GraphicsData(rect.x, rect.y, 0, 1, 0, RESOURCE_SIDES);
+}
+
+void Organism::Behavior()
+{
+ health-=1;
+
+ this->Priority();
+
+ if(!hasTarget)
+ this->setTarget();
+ else
+ this->checkTarget();
+
+ this->Action();
+
+ if(pregnate){
+ pregnancyTime++;
+ if(pregnancyTime > myDNA.expectedPregnancyTime)
+ pregnancyReady = true;
+ }
+
+ age++;
+ if(age > myDNA.expectedAge)
+ health = 0;
+}
+
+void Organism::Priority()
+{
+ if(health < myDNA.maxHealth / 2){
+ hungry = true;
+ able = false;
+ }
+ else{
+ hungry = false;
+ able = true;
+ }
+}
+
+void Organism::setTarget()
+{
+ std::random_shuffle(nearMe.begin(),nearMe.end());
+
+ for(std::vector<Organism*>::iterator it = nearMe.begin(); it!=nearMe.end(); it++){
+ if( (*it)->getType() == RESOURCE_TYPE && hungry){
+ target = *it;
+ hasTarget = true;
+ wander = false;
+ break;
+ }
+ if( (*it)->getType() == CREATURE_TYPE && able && (*it)->getGender() != gender ){
+ target = *it;
+ hasTarget = true;
+ wander = false;
+ break;
+ }
+ }
+
+ if(!hasTarget&&!wander){
+ wander = true;
+ Rectangle tmp(getRandom(30),getRandom(30),0,0);
+ wTarget = tmp;
+ }
+}
+
+void Organism::checkTarget()
+{
+ for(std::vector<Organism*>::iterator it = nearMe.begin(); it!=nearMe.end(); it++)
+ if( target == *it )
+ return;
+
+ hasTarget = false;
+}
+
+
+void Organism::Action()
+{
+ if(hasTarget){
+ if(Distance(rect,target->getRectangle()) < myDNA.reach){
+ if(target->getType() == RESOURCE_TYPE){
+ target->takeBite(myDNA.bite);
+ health+=myDNA.bite;
+ if(target->getHealth()<=0)
+ hasTarget = false;
+ }
+ else if (target->getType() == CREATURE_TYPE){
+ if(target->getGender() != gender){
+ target->passDNA(myDNA);
+ }
+ hasTarget = false;
+ }
+
+ }
+ else
+ moveTowards(target->getRectangle());
+ }
+ else if(wander){
+ if(Distance(rect,wTarget) < myDNA.reach)
+ wander = false;
+ else
+ moveTowards(wTarget);
+ }
+}
+
+void Organism::moveTowards(Rectangle t)
+{
+ if( rect.x == t.x ){
+ if( rect.y < t.y )
+ rect.y+=myDNA.speed;
+ else
+ rect.y-=myDNA.speed;
+ }
+ else if( rect.y == t.y ){
+ if( rect.x < t.x )
+ rect.x+=myDNA.speed;
+ else
+ rect.x-=myDNA.speed;
+ }
+ else if( rect.x < t.x ){
+ if( rect.y < t.y ){
+ rect.x+=myDNA.speed;
+ rect.y+=myDNA.speed;
+ }
+ else{
+ rect.x+=myDNA.speed;
+ rect.y-=myDNA.speed;
+ }
+ }
+ else if ( rect.x > t.x ){
+ if( rect.y < t.y ){
+ rect.x-=myDNA.speed;
+ rect.y+=myDNA.speed;
+ }
+ else{
+ rect.x-=myDNA.speed;
+ rect.y-=myDNA.speed;
+ }
+ }
+}
+
+void Organism::passDNA(DNA d)
+{
+ if(!pregnate){
+ pregnate = true;
+ pregnancyTime = 0;
+ childsDNA = myDNA.combine(d);
+ }
+}
+
+void Organism::grow()
+{
+ if(health < myDNA.maxHealth)
+ health+=myDNA.growAmount;
+}
+
+void Organism::takeBite(int bite)
+{
+ health-=bite;
+}
+
+void Organism::Place()
+{
+ gfxData.x = rect.x;
+ gfxData.y = rect.y;
+}