Commits

Mihael Peklar committed 69a9890 Draft

Added basic attack (no damage yet). AI will follow target if it goes out of range.

  • Participants
  • Parent commits cc72f9c

Comments (0)

Files changed (8)

     this->units = this->map->getUnits();
     this->selectedUnit=NULL;
 
-	unit = new Unit();
+	unit = new Unit(getPathfinder());
 	this->units->addUnit(unit);
-	unit = new Unit();
+	unit = new Unit(getPathfinder());
 	unit->setX(90);
 	unit->setY(10);
 	this->units->addUnit(unit);
 							this->selectedUnit->setOrders(this->map->path_order(unit->getX(), unit->getY(), adjustedMouseX, adjustedMouseY));
 						else //TODO: Do this the right way!
 						{
+							this->selectedUnit->addWatch(target);
 							this->selectedUnit->attackOrder(target);
 						}
 					}
 	}
 }
 
+Pathfinder* GM_Battle::getPathfinder()  {return this->map->getPathfinder();}
+
 /*
 void GM_Battle::_paintSelector(float _x, float _y, float w, float h)
 {
 class Map;
 class Button;
 class UnitContainer;
+class Pathfinder;
 
 class GM_Battle : public GameMode
 {
 	void updateSelf(float k);
 	void paintSelf();
 	void handleEvent(SDL_Event &event);
+	Pathfinder* getPathfinder() ;
 
 	private:
 	Unit* selectedUnit;
 	ORDER_NONE=0,
 	ORDER_MOVE,
 	ORDER_ATTACK,
+	ORDER_NEW_ATTACK
 };
 
 class Unit;
 
-union OrderDetails
+struct OrderDetails
 {
 	struct OrderDetailsMove
 	{
 
 extern vector<int> drawThis;
 
-std::deque<Order> Pathfinder::path_order(float px, float py, float ex, float ey)
+std::deque<Order> Pathfinder::path_order(float px, float py, float ex, float ey, OrderType t, Unit* targ)
 {
 	map->boundFix(ex, ey);
 	int s=this->map->findTile(px, py), e=this->map->findTile(ex, ey);
 	for(std::vector<int>::iterator i=++x.begin(); i<x.end(); ++i)
 	{
 		nx=*i%this->map->getTilesPerRow()*TILE_WIDTH, ny=-*i/this->map->getTilesPerRow()*TILE_HEIGHT;
-		o.order=ORDER_MOVE;
+		o.order=t;
+		if(t==ORDER_ATTACK)
+			o.details.attack.target=targ;
 		//o.details.move=(struct OrderDetailsMove){ .srcx=px, .srcy=py, .dstx=nx, .dsty=ny, .progress=0.0}; //problem?
 		o.details.move.srcx=px;
 		o.details.move.srcy=py;
 
 #include<vector>
 #include<queue>
+#include "order.h"
 
 class Map;
 class Order;
 
+
 class Pathfinder
 {
 	public:
 	Pathfinder(Map* map);
     std::vector<int> find_path(int st, int et);
-    std::deque<Order> path_order(float px, float py, float ex, float ey);
+    std::deque<Order> path_order(float px, float py, float ex, float ey, OrderType t=ORDER_MOVE, Unit* targ=NULL);
 
 	private:
     bool siri(int x, int y);

pathfinder.o

Binary file removed.
 #include<cstdio>
 #include <math.h>
 #include<cstdlib>
+#include"gm_battle.h"
 #include "unit.h"
 #include "texture.h"
 #include "texture_manager.h"
 #include"order.h"
+#include "pathfinder.h"
 
 #define SGN(x) ((x) ? (x)/(x) : 0)
 
+extern GameMode* game;
+
 Unit::Unit()
 {
+	printf("game: %d\n", game);
+	this->pathfinder = ((GM_Battle*)game)->getPathfinder(); //TODO: There has to be a better way to do this!
 	this->tex = TextureManager::getInstance()->getTexture("zombie.png");
 	this->attacking_tex = TextureManager::getInstance()->getTexture("zombie_attacking.png");
 
 	this->x = 0;
 	this->y = 0;
 
+	this->range=100;
+
+	this->currentlySelected = false;
+	this->activeState = STATE_STANDING;
+}
+
+Unit::Unit(Pathfinder* x)
+{
+	printf("game: %d\n", game);
+	this->pathfinder = x;
+	this->tex = TextureManager::getInstance()->getTexture("zombie.png");
+	this->attacking_tex = TextureManager::getInstance()->getTexture("zombie_attacking.png");
+
+	this->selector = TextureManager::getInstance()->getTexture("selector.png");
+	this->aniProgress = 0;
+	this->dir = 6;
+
+	this->x = 0;
+	this->y = 0;
+
+	this->range=100;
+
 	this->currentlySelected = false;
 	this->activeState = STATE_STANDING;
 }
 
 Unit::~Unit()
 {
+	disappear();
 	delete this->tex;
 }
 
 		case ORDER_NONE:
 		{
 			activeState = STATE_STANDING;
+			this->nextOrder();
 		}
 		break;
 
 		case ORDER_MOVE:
+		case ORDER_ATTACK:
 		switch(activeState)
 		{
 			case STATE_STANDING:
-			case STATE_ATTACKING:
 			activeState = STATE_MOVING;
 			break;
 
+			case STATE_ATTACKING:
+			break;
 			default:
 			break;
 		}
 		break;
-		case ORDER_ATTACK:
+		case ORDER_NEW_ATTACK:
 		{
-			activeState = STATE_ATTACKING;
-			//assert(0);
-			break;	
+			this->attackOrder(activeOrder.details.attack.target);
+			this->nextOrder();
 		}
+		break;
 	}
 
 	switch(activeState)
 
 		case STATE_MOVING:
 		{
+			//in attack range?
+			if(this->activeOrder.order==ORDER_ATTACK)
+			{
+				//printf("Attack order given\n");
+				if(checkRange(this->activeOrder.details.attack.target))
+				{
+					printf("InRange\n");
+					this->activeState=STATE_ATTACKING;
+					break;
+				}
+			}
+
 			float speed = 70;
 
 			this->aniProgress += speed / 5 * k;
 		
 		case STATE_ATTACKING:
 		{
+			if(!checkRange(this->activeOrder.details.attack.target))
+			{
+				this->attackOrder(this->activeOrder.details.attack.target);
+				return;
+			}
 			Unit* target=this->activeOrder.details.attack.target;
 
 			float speed = 70;
 			this->dir = circleToDir(newDir);
 		}
 		break;
+	}
+}
 
+bool Unit::checkRange(Unit* targ)
+{
+	if(!this->reg.count(targ))
+	{
+		printf("Noreg!");
+		return false;
 	}
-
+	float x=targ->x-this->x, y=targ->y-this->y;
+	return range*range >= ((x*x)+(y*y)); //square comparison
 }
 
 bool Unit::distanceCompare(Unit *a, Unit *b)
 
 void Unit::attackOrder(Unit* target)
 {
-	this->activeState=STATE_ATTACKING;
-	this->activeOrder.order=ORDER_ATTACK;
-	this->activeOrder.details.attack.target=target;
+	this->clearOrders();
+	if(!this->reg.count(target))
+	{
+		this->nextOrder();
+		return;
+	}
+	this->setOrders(this->pathfinder->path_order(this->x, this->y, target->x, target->y, ORDER_ATTACK, target));
+	Order x;
+	x.order=ORDER_NEW_ATTACK;
+	x.details.attack.target=target;
+	this->addOrder(x);
 }
 
 void Unit::setOrders(OrderList x)
 {
+	this->clearOrders();
 	this->list=x;
+	//this->nextOrder();
+}
+
+void Unit::clearOrders()
+{
+	this->list.clear();
 	this->nextOrder();
 }
 
+void Unit::addOrder(Order x)
+{
+	this->list.push_back(x);
+}
+
 void Unit::movementOrder(float mapX, float mapY)
 {
 	this->activeOrder.order = ORDER_MOVE;
 }
 
 
+void Unit::addWatch(Unit* x)
+{
+	this->addSW(x);
+	x->addSW(this);
+}
 
+void Unit::addSW(Unit* x)
+{
+	this->reg.insert(x);
+}
+
+void Unit::unWatch(Unit* x)
+{
+	this->reg.erase(x);
+	if(this->activeOrder.order = ORDER_ATTACK)
+		if(this->activeOrder.details.attack.target==x)
+			this->nextOrder();
+}
+
+void Unit::disappear()
+{
+	for(std::set<Unit*>::iterator i=reg.begin(); i!=reg.end(); ++i)
+		(*i)->unWatch(this);
+}
 
 void Unit::_paintSelector(float _x, float _y, float w, float h)
 {
 #define UNIT_H_INCLUDED
 
 class Texture;
+class Pathfinder;
 
 #include "order.h"
+#include <set>
 
 class Unit
 {
 	};
 
 	Unit();
+	Unit(Pathfinder*);
 	~Unit();
 
 	void updateSelf(float k);
 
 	//orders
 	void setOrders(OrderList x);
+	void addOrder(Order);
+	void clearOrders();
 	// obsolete:
 	void defaultOrder(float mapX, float mapY);
 	void movementOrder(float mapX, float mapY);
 	// debug only:
 	void _setSelected(bool selection) { currentlySelected = selection; }
 
+	void addWatch(Unit*); //adds watch to both units
+	void unWatch(Unit*); //also stops order pertaining to chosen unit
+	void disappear(); //removes unit from all watches
+
+
 	private:
 	void nextOrder();
+	void addSW(Unit* x);
 	void _paintSelector(float _x, float _y, float w, float h);
 	static int dirToCircle(int);
 	static int circleToDir(int);
 	Texture *selector;
 	Texture *attacking_tex;
 	
+	float range;
+	bool checkRange(Unit* targ);
+
 	float aniProgress;
 	int dir;
 	float x, y;
 	Order activeOrder;
 	OrderList list;
 
+	Pathfinder* pathfinder; //to get in range again.
+
+	std::set<Unit*> reg;
+
+
 	bool currentlySelected;
 };