#include "splashes.h" #include Splashes::Splashes(Game_Data *gd, QObject *parent) : QObject(parent) { gameData = gd; nextId = 1; } void Splashes::addSplash(int player, srcSplashType *src, QPointF pos, QPointF dest, int aim) { SplashType spl; spl.id = nextId; spl.towerId = QPoint(-1,-1); spl.srcTow = 0; spl.PlayerId = player; spl.AlienId = 0; spl.pos = pos; spl.destination = dest; spl.AlienId = aim; spl.angle = 180.0f*(- std::atan2(spl.pos.x() - spl.destination.x(),spl.pos.y() - spl.destination.y()))/M_PI; spl.life = 0; spl.src = src; addSplash(&spl); } void Splashes::addSplash(const TowerType &tower) { SplashType spl; spl.src = &(tower.src->splashes[0]); spl.id = nextId; spl.towerId = tower.pos; spl.PlayerId = tower.PlayerId; spl.AlienId = tower.aim; spl.srcTow = tower.src; spl.pos = QPointF(tower.pos); if (gameData->aliens->curAliens.contains(spl.AlienId)) spl.destination = gameData->aliens->curAliens.value(spl.AlienId).pos+QPointF(0.5,0.5); else {qCritical("aim alien not exists(!)");return;} spl.angle = 180.0f*(- std::atan2(spl.pos.x() - spl.destination.x(),spl.pos.y() - spl.destination.y()))/M_PI; spl.life = 0; addSplash(&spl); } void Splashes::addSplash(srcTowerType *srctower, int id, QPointF pos, QPointF dest, int aim, QPoint towerId) { SplashType spl; if (srctower != 0) spl.src = &(srctower->splashes[id]); else spl.src = &(gameData->srcSplashes[id]); spl.id = nextId; spl.towerId = towerId; spl.PlayerId = srctower->PlayerId; spl.AlienId = aim; spl.pos = pos; spl.destination = dest; spl.angle = 180.0f*(- std::atan2(spl.pos.x() - spl.destination.x(),spl.pos.y() - spl.destination.y()))/M_PI; spl.life = 0; spl.srcTow = srctower; addSplash(&spl); } void Splashes::addSplash(SplashType * spl) { srcTriggerType * trig; for(int i=0; isrc->triggerIndexes.size(); i++) { TriggerOnDest tod; TriggerOnAlien toa; TriggerOnTimer tot; if (spl->srcTow != 0) trig = &(spl->srcTow->triggers[spl->src->triggerIndexes.at(i)]); else {qDebug("no parent tower"); trig = &(gameData->srcTriggers[spl->src->triggerIndexes.at(i)]);} switch (trig->type) { case srcTriggerType::onDestination : tod.src = trig; spl->trigsOnDest.append(tod); break; case srcTriggerType::onAlienInRadius : toa.src = trig; spl->trigsOnAlien.append(toa); break; case srcTriggerType::onTimer : tot.src = trig; tot.timer = 0; spl->trigsOnTimer.append(tot); break; } } spl->item = new ADItem(spl->id, ADItem::Splash, spl->src->images); spl->item->setPos(spl->pos*cellSize); spl->item->setRotation(spl->angle); scene->addItem(spl->item); gameData->curSplashes.insert(spl->id,*spl); nextId++; } void Splashes::update() { QList deadIndexes; for (QHash::iterator spl = gameData->curSplashes.begin(); spl != gameData->curSplashes.end(); ++spl) { spl->life++; if (spl->life > spl->src->lifetime) deadIndexes.append(spl->id); if (!spl->trigsOnTimer.isEmpty()) doTriggerOnTimer(spl,&deadIndexes); float arctg; float speed = spl->src->speed; float speed2 = speed*speed; if (spl->src->autoControl && spl->AlienId != -1) { bool badAl = false; if (gameData->aliens->curAliens.contains(spl->AlienId)) spl->destination = gameData->aliens->curAliens.value(spl->AlienId).pos+QPointF(0.5,0.5); else { badAl = true; spl->AlienId = -1; } if (distance2(spl->pos, spl->destination) < speed2) { if (badAl) deadIndexes.push_back(spl->id); spl->pos = spl->destination; doTriggerOnDest(spl,&deadIndexes,badAl); } arctg = std::atan2(spl->pos.x() - spl->destination.x(),spl->pos.y() - spl->destination.y()); spl->angle = 180.0f*(-arctg)/M_PI; } else { if (!gameData->map->rect().contains(spl->pos.toPoint())) deadIndexes.push_back(spl->id); if (!spl->trigsOnDest.isEmpty()) { if (distance2(spl->pos, spl->destination) < speed2) { spl->pos = spl->destination; doTriggerOnDest(spl,&deadIndexes,true); } } arctg = -spl->angle*M_PI/180.f; } spl->pos.rx() -= speed*std::sin(arctg); spl->pos.ry() -= speed*std::cos(arctg); /// TODO: smooth splash rotate spl->item->setPos(spl->pos*cellSize); spl->item->setRotation(spl->angle); if (speed == 0) spl->item->next(1.f); else spl->item->next(speed*cellSize); } for (int j=0; j::iterator j = dead.begin(); j != dead.end(); ++j) emit killAlien(j->player,j->id); dead.clear(); } void Splashes::delSplash(int Id) { scene->removeItem(gameData->curSplashes[Id].item); delete gameData->curSplashes[Id].item; gameData->curSplashes.remove(Id); } /// FIXME : correct onTrigTimer() void Splashes::doTriggerOnTimer(QHash::iterator spl, QList *deadIndexes) { for(QList::iterator i = spl->trigsOnTimer.begin(); i != spl->trigsOnTimer.end(); ++i) { srcTriggerType * strig = i->src; i->timer++; if (i->timer >= strig->timer) { /// TODO : add damage and other effects i->timer = 0; if (strig->delParent) deadIndexes->append(spl->id); if (strig->count > 0 && strig->childId > 0) { int aim; switch(strig->childAim) { /// TODO : othet aim types case srcTriggerType::parentAim : aim = spl->AlienId; break; case srcTriggerType::noAim : aim = -1; break; default : aim = -1; } for (int j=0; jcount; ++j) { /// TODO: randomRadiusPos addSplash(spl->srcTow, strig->childId, spl->pos, spl->destination, aim, spl->towerId); } } } } } void Splashes::doTriggerOnDest(QHash::iterator spl, QList *deadIndexes, bool badAl) { foreach(TriggerOnDest t, spl->trigsOnDest) { /// TODO: different aims for childs if (t.src->delParent) deadIndexes->append(spl->id); int aim; switch(t.src->childAim) { case srcTriggerType::parentAim : aim = spl->AlienId; break; /// TODO : other aim types case srcTriggerType::noAim : aim = -1; break; default : aim = -1; } if (t.src->count > 0 && t.src->childId > 0) { for (int j=0; jcount; ++j) { /// TODO: randomRadiusPos addSplash(spl->srcTow,t.src->childId, spl->pos,spl->destination,aim,spl->towerId); } } float dmg = t.src->damage; float rad = t.src->radius; if (dmg > 0) { float hh; if (!(rad > 0)) { if (!badAl) { hh = gameData->aliens->curAliens[spl->AlienId].health -= dmg; if (hh <= 0) dead.insert(spl->AlienId, DeadAlienIndex(spl->AlienId, spl->PlayerId)); } } else { for (QHash::iterator i = gameData->aliens->curAliens.begin(); i != gameData->aliens->curAliens.end(); ++i) { if (distance2(spl->pos, i->pos) < rad*rad) { hh = i->health -= dmg; if (hh <= 0) dead.insert(i->id, DeadAlienIndex(i->id, spl->PlayerId)); } } } } } }