Files
aliendefender/splashes.cpp
2010-08-31 19:25:29 +04:00

248 lines
7.4 KiB
C++

#include "splashes.h"
#include <cmath>
Splashes::Splashes(Game_Data *gd, QObject *parent) :
QObject(parent)
{
gameData = gd;
nextId = 1;
}
void Splashes::addSplash(int player, int srcTower, int srcId, QPointF pos, QPointF dest, int aim, QPoint curTower)
{
srcSplashType src = gameData->players.at(player)->srcTowers.at(srcTower).splashes.at(srcId);
SplashType spl;
spl.id = nextId;
spl.TowerId = curTower;
spl.srcTower = srcTower;
spl.PlayerId = player;
if (src.autoControl)
{
spl.AlienId = aim;
if (gameData->curAliens.contains(aim))
spl.destination = gameData->curAliens.value(aim).pos+QPointF(0.5,0.5);
else
spl.destination = dest;
} else {
spl.AlienId = -1;
spl.destination = dest;
}
spl.pos = pos;
spl.angle = 180.0f*(- std::atan2(spl.pos.x() - spl.destination.x(),spl.pos.y() - spl.destination.y()))/M_PI;
spl.imgType = src.imgType;
spl.life = 0;
spl.src = srcId;
//TriggerType trig;
srcTriggerType trig;
for(int i=0; i<src.triggerIndexes.size(); i++)
{
TriggerOnDest tod;
TriggerOnAlien toa;
TriggerOnTimer tot;
trig = gameData->players.at(player)->srcTowers.at(srcTower).triggers.at(src.triggerIndexes.at(i));
switch (trig.type)
{
case srcTriggerType::onDestination :
tod.src = src.triggerIndexes.at(i);
spl.trigsOnDest.append(tod);
break;
case srcTriggerType::onAlienInRadius :
toa.src = src.triggerIndexes.at(i);
spl.trigsOnAlien.append(toa);
break;
case srcTriggerType::onTimer :
tot.src = src.triggerIndexes.at(i);
tot.timer = trig.timer;
spl.trigsOnTimer.append(tot);
break;
}
}
//qDebug() << "t=" << src.triggerIndexes.size() << "d=" << spl.trigsOnDest.size();
gameData->curSplashes.insert(spl.id,spl);
nextId++;
}
void Splashes::addSplash(QPoint curTowerId)
{
if (gameData->curTowers.contains(curTowerId))
{
TowerType tw = gameData->curTowers.value(curTowerId);
addSplash(tw.PlayerId,tw.src,0,QPointF(tw.pos+QPoint(1,1)),gameData->curAliens.value(tw.aim).pos+QPointF(0.5,0.5),tw.aim,tw.pos);
}
// TowerType tw = gameData->curTowers.value(curTowerId);
// srcSplashType src = gameData->players.at(tw.PlayerId)->srcTowers.at(tw.src).splashes.at(0);
// SplashType spl;
// spl.id = nextId;
// spl.TowerId = curTowerId;
// spl.srcTower = tw.src;
// spl.PlayerId = tw.PlayerId;
// if (!gameData->curAliens.contains(tw.aim))
// qFatal("Error finding splash aim! Tower has nvalid aim!");
// spl.destination = gameData->curAliens.value(tw.aim).pos;
// if (src.autoControl)
// spl.AlienId = tw.aim;
// else
// spl.AlienId = -1;
// spl.pos = tw.pos+QPointF(0.5,0.5); // FIXME: splash do not create in center or left-angle of tower, it must be in tower's side
// spl.angle = 180.0f*(- std::atan2(spl.pos.x() - spl.destination.x(),spl.pos.y() - spl.destination.y()))/M_PI;
// spl.imgType = src.imgType;
// spl.life = 0;
// spl.src = 0;
// //TriggerType trig;
// for(int i=0; i<src.triggerIndexes.size(); i++)
// {
// srcTriggerType trig;
// TriggerOnDest tod;
// TriggerOnAlien toa;
// TriggerOnTimer tot;
// trig = gameData->players.at(tw.PlayerId)->srcTowers.at(tw.src).triggers.at(src.triggerIndexes.at(i));
// switch (trig.type)
// {
// case srcTriggerType::onDestination :
// tod.src = src.triggerIndexes.at(i);
// spl.trigsOnDest.append(tod);
// break;
// case srcTriggerType::onAlienInRadius :
// toa.src = src.triggerIndexes.at(i);
// spl.trigsOnAlien.append(toa);
// break;
// case srcTriggerType::onTimer :
// tot.src = src.triggerIndexes.at(i);
// tot.timer = trig.timer;
// spl.trigsOnTimer.append(tot);
// break;
// }
// }
// //qDebug() << "t=" << src.triggerIndexes.size() << "d=" << spl.trigsOnDest.size();
// gameData->curSplashes.insert(spl.id,spl);
// nextId++;
// }
}
void Splashes::update()
{
QList <int> deadIndexes;
for (int i=0; i<gameData->curSplashes.size(); i++)
{
float arctg,angl;
SplashType spl = gameData->curSplashes.values().at(i);
//bool isTowerSplash = false;
srcSplashType src;
// FIXME : if splash is not tower's splash, will be some trouble
src = gameData->players.at(spl.PlayerId)->srcTowers.at(spl.srcTower).splashes.at(spl.src);
spl.life++;
if (spl.life > src.lifetime)
deadIndexes.append(spl.id);
//isTowerSplash = true;
//if (!isTowerSplash)
// src = gameData->srcSplashes.at(spl.src);
if (src.autoControl)
{
bool badAl = false;
if (gameData->curAliens.contains(spl.AlienId))
spl.destination = gameData->curAliens.value(spl.AlienId).pos+QPointF(0.5,0.5);
else
badAl = true;
if (distance2(spl.pos, spl.destination) < src.speed*src.speed)
{
if (badAl)
deadIndexes.push_back(spl.id);
spl.pos = spl.destination;
for (int k=0; k<spl.trigsOnDest.size(); k++)
{
// TODO: activate trigger
srcTriggerType strig = gameData->players.at(spl.PlayerId)->srcTowers.at(spl.srcTower).triggers.at(spl.trigsOnDest.at(k).src);
if (strig.delParent) deadIndexes.push_back(spl.id);
if (strig.count > 0 && strig.childId > 0)
{
//qDebug("bvgbjdklbvfjldsk");
addSplash(spl.PlayerId,spl.srcTower,strig.childId,spl.pos,spl.destination,-1,spl.TowerId);
}
if (strig.damage > 0)
{
if (!(strig.radius > 0))
{
if (!badAl)
{
float hh = gameData->curAliens[spl.AlienId].health -= strig.damage;
if (hh < 0)
gameData->curAliens.remove(spl.AlienId);
//qDebug() << "health=" << hh;
}
} else {
processTrigger(strig,spl.pos);
}
}
}
}
arctg = std::atan2(spl.pos.x() - spl.destination.x(),spl.pos.y() - spl.destination.y());
//if (tmpdy < 0) arctg=arctg+M_PI;
angl = 180.0f*(-arctg)/M_PI;
spl.angle = angl;
spl.pos.setX(spl.pos.x()
-src.speed*std::sin(arctg));
spl.pos.setY(spl.pos.y()
-src.speed*std::cos(arctg));
} else {
if (!gameData->map->rect().contains(spl.pos.toPoint()))
deadIndexes.push_back(spl.id);
if (!spl.trigsOnDest.isEmpty())
{
if (distance2(spl.pos, spl.destination) < src.speed*src.speed)
{
spl.pos = spl.destination;
for (int k=0; k<spl.trigsOnDest.size(); k++)
{
srcTriggerType strig = gameData->players.at(spl.PlayerId)->srcTowers.at(spl.srcTower).triggers.at(spl.trigsOnDest.at(k).src);
if (strig.delParent) deadIndexes.push_back(spl.id);
processTrigger(strig,spl.pos);
if (strig.count > 0 && strig.childId > 0)
{
//qDebug("bvgbjdklbvfjldsk");
addSplash(spl.PlayerId,spl.srcTower,strig.childId,spl.pos,spl.destination,-1,spl.TowerId);
}
}
}
}
spl.pos.setX(spl.pos.x()
-src.speed*std::sin(-spl.angle*M_PI/180.f));
spl.pos.setY(spl.pos.y()
-src.speed*std::cos(-spl.angle*M_PI/180.f));
}
// TODO: smooth splash rotate
// TODO: activate trigger and more...
gameData->curSplashes.insert(spl.id,spl);
}
for (int j=0; j<deadIndexes.size(); j++)
delSplash(deadIndexes.at(j));
}
void Splashes::delSplash(int Id)
{
gameData->curSplashes.remove(Id);
}
void Splashes::processTrigger(srcTriggerType srctrig, QPointF pos)
{
//qDebug("trig proc");
QList <int> dead;
for (QHash<int, AlienType>::iterator i = gameData->curAliens.begin(); i != gameData->curAliens.end(); ++i)
{
if (distance2(pos, (*i).pos) < srctrig.radius*srctrig.radius)
{
(*i).health -= srctrig.damage;
//qDebug() << "health=" << hh;
if ((*i).health < 0) dead.append((*i).id);
}
}
for (int i=0; i<dead.size(); ++i)
gameData->curAliens.remove(dead.at(i));
}