void Effect::update(unsigned int elapsedMillis) { switch (effectType_) { case TYPE_SOURCE_TO_TARGET: { boost::shared_ptr<IngameObject> targetObj = targetObject_.lock(); boost::shared_ptr<IngameObject> sourceObj = sourceObject_.lock(); if (!targetObj || !sourceObj) { expired_ = true; break; } if (exploding_) { if (getLocation() != targetObj->getLocation()) { setLocation(targetObj->getLocation()); } } else { // interpolate // movement is not exactly like osi, but close enough float timeFactor = elapsedMillis / 1000.f * speedPerSecond_; CL_Vec3f targetLoc = targetObj->getLocation(); CL_Vec3f selfLoc = getLocation(); CL_Vec3f totalDistance = targetLoc - selfLoc; if (totalDistance.length() <= timeFactor) { // reached target setLocation(targetLoc); lifetimeMillisLeft_ = -1; fixedAngle_ = true; currentAngle_ = 0; shouldExpireMoving_ = true; } else { CL_Vec3f step = totalDistance.normalize() * timeFactor; selfLoc += step; setLocation(selfLoc); // does not expire while moving shouldExpireMoving_ = false; if (!fixedAngle_) { // this has to be in screen coordinates totalDistance -= step; float screenDiffX = (totalDistance.x - totalDistance.y) * 44; float screenDiffY = (totalDistance.x + totalDistance.y) * 44 + totalDistance.z * 4; currentAngle_ = atan2(screenDiffY, screenDiffX) + 3.14159265;; } } } break; } case TYPE_LIGHTNING: break; case TYPE_AT_POSITION: break; case TYPE_AT_SOURCE: { boost::shared_ptr<IngameObject> obj = sourceObject_.lock(); if (!obj) { expired_ = true; } else { if (getLocation() != obj->getLocation()) { setLocation(obj->getLocation()); } } break; } } // check expire time lifetimeMillisLeft_ -= elapsedMillis; if (shouldExpireMoving_) { if (shouldExplode_) { exploding_ = true; shouldExplode_ = false; lifetimeMillisLeft_ = startExplosion(); } if (shouldExpireTimeout()) { expired_ = true; } } }
void Bomb::moveToCollisionPoint(float lamda) { currentPosition = oldPosition + velocity*lamda; startExplosion(); setLifeStatus(false); }