예제 #1
0
void
SWFTextField_setScaledLineSpacing(SWFTextField field, int lineSpacing)
{
	field->lineSpacing = lineSpacing;
	field->flags |= SWFTEXTFIELD_HASLAYOUT;
	resetBounds(field);
}
예제 #2
0
void
SWFTextField_setScaledBounds(SWFTextField field, int width, int height)
{
	field->width = width;
	field->fieldHeight = height;
	resetBounds(field);
}
예제 #3
0
int
completeSWFTextField(SWFBlock block)
{
	SWFTextField field = (SWFTextField)block;

	/* we're guessing how big the block's going to be.. */
	SWFOutput out =
		newSizedSWFOutput(42 
			+ ((field->varName)?strlen(field->varName):0) 
			+ ((field->string)?strlen(field->string):0));

	field->out = out;

	resetBounds(field);

	SWFOutput_writeUInt16(out, CHARACTERID(field));
	SWFOutput_writeRect(out, CHARACTER(field)->bounds);
	SWFOutput_writeUInt16(out, field->flags);

	if(field->flags & SWFTEXTFIELD_HASFONT)
	{
		SWFOutput_writeUInt16(out, CHARACTERID(field->font.fontchar));
		SWFOutput_writeUInt16(out, field->fontHeight);
	}

	if(field->flags & SWFTEXTFIELD_HASCOLOR)
	{
		SWFOutput_writeUInt8(out, field->r);
		SWFOutput_writeUInt8(out, field->g);
		SWFOutput_writeUInt8(out, field->b);
		SWFOutput_writeUInt8(out, field->a);
	}

	if ( field->flags & SWFTEXTFIELD_HASLENGTH )
		SWFOutput_writeUInt16(out, field->length);

	if(field->flags & SWFTEXTFIELD_HASLAYOUT)
	{
		SWFOutput_writeUInt8(out, field->alignment);
		SWFOutput_writeUInt16(out, field->leftMargin);
		SWFOutput_writeUInt16(out, field->rightMargin);
		SWFOutput_writeUInt16(out, field->indentation);
		SWFOutput_writeUInt16(out, field->lineSpacing);
	}

	SWFOutput_writeString(out, (byte*) field->varName);
	if ( field->flags & SWFTEXTFIELD_HASTEXT )
		SWFOutput_writeString(out, (byte*)field->string);

	/*
		XXX - if font is a real font, do we need to talk to it?
		flash 4 just makes a browser font for (editable) textfields for all fonts
	*/

	SWFOutput_byteAlign(out);
	return SWFOutput_getLength(out);
}
예제 #4
0
void RenderTerrainNode::updateVertexBuffer( RenderVertexBuffer* posbuf,const Rect& rect )
{
	ph_assert (rect.left >= m_offsetX && rect.right <= m_boundaryX && 
		rect.top >= m_offsetY && rect.bottom <= m_boundaryY);

	resetBounds(rect);

	long destOffsetX = rect.left <= m_offsetX ? 0 : (rect.left - m_offsetX);
	long destOffsetY = rect.top	 <= m_offsetY ? 0 : (rect.top  - m_offsetY);

	scalar uvScale = 1.0f / (m_terrain->getSize() - 1);
	const float* pBaseHeight = m_terrain->getHeightData(rect.left, rect.top);
	uint16 rowskip = m_terrain->getSize();
	uint16 destPosRowSkip = 0, destDeltaRowSkip = 0;
	unsigned char* pRootPosBuf	= 0;
	unsigned char* pRowPosBuf	= 0;

	if (posbuf)
	{
		destPosRowSkip	= m_terrain->getBatchSize() * posbuf->getVertexSize();
		pRootPosBuf		= static_cast<unsigned char*>(posbuf->lock());
		pRowPosBuf		= pRootPosBuf;
		pRowPosBuf		+= destOffsetY * destPosRowSkip + destOffsetX * posbuf->getVertexSize();
	}

	Vector3 pos;
	bool vcompress = m_terrain->getUseVertexCompression();

	for (long y = rect.top; y < rect.bottom; y ++)
	{
		const float* pHeight = pBaseHeight;
		float* pPosBuf = static_cast<float*>(static_cast<void*>(pRowPosBuf));
		for (long x = rect.left; x < rect.right; x ++)
		{
			if (pPosBuf)
			{
				m_terrain->getPoint(x, y, *pHeight, &pos);

				mergeIntoBounds(x, y, pos);
				//pos -= m_localCentre;

				writePosVertex(vcompress, (uint16)x, (uint16)y, *pHeight, pos, uvScale, &pPosBuf);
				pHeight ++;
			}
		}
		pBaseHeight += rowskip;
		if (pRowPosBuf)
		{
			pRowPosBuf += destPosRowSkip;
		}
	}

	if (posbuf)
	{
		posbuf->unlock();
	}
}
예제 #5
0
static void
SWFTextField_addStringOnly(SWFTextField field, const char *string)
{
	int l;

	for ( l=0; string[l]!='\0'; ++l )
	{
		if ( string[l] == '\n' )
			++field->nLines;
	}

	if ( field->string )
	{
		field->string = (char*)realloc(field->string, strlen(field->string)+l+1);
		strcat(field->string, string);
	}
	else
		field->string = strdup(string);
	field->flags |= SWFTEXTFIELD_HASTEXT;
	resetBounds(field);
}
예제 #6
0
Creep::Creep(float x, float y, float width, float height, float initialSpeed, int maxHealth, int pointValue, int levelIndex, int spawnPointIndex, bool isUsingAltPath) : PhysicalEntity (x, y, width, height, 0)
{
    m_fAlpha = 1.0f;
    m_fRed = 1.0f;
    m_fGreen = 1.0f;
    m_fBlue = 1.0f;
    m_defaultSize = width;
    m_halfSize = width / 2;
    m_maxSize = width * 1.15f;
    m_initialSpeed = initialSpeed;
    m_speed = initialSpeed;
    m_maxHealth = maxHealth;
    m_pointValue = pointValue;
    
    m_rollOverDistance = std::unique_ptr<Vector2D>(new Vector2D());
    m_timeToShowHealthBar = 0;
    m_frozenTime = 0;
    m_burnTime = 0;
    m_electrifiedTime = 0;
    m_poisonedTime = 0;
    m_poisonTime = 0;
    m_health = maxHealth;
    m_creepCondition = HEALTHY;
    m_healthBarFrame = 15;
    m_pathIndex = 0;
    m_direction = calculateInitialDirection();
    m_stickyCount = 0;
    m_levelIndex = levelIndex;
    m_spawnPointIndex = spawnPointIndex;
    m_isUsingAltPath = isUsingAltPath;
    m_state = ALIVE;
    m_fStateTime = 0;
    m_isUsingAltPathOnHullDamage = m_levelIndex == 2 && m_isUsingAltPath == false && (rand() % 2) == 0;
    
    resetBounds(width * SIZE_TO_BOUNDS_RATIO, height * SIZE_TO_BOUNDS_RATIO);
}
예제 #7
0
void
SWFTextField_setScaledPadding(SWFTextField field, int padding)
{
	field->padding = padding;
	resetBounds(field);
}
예제 #8
0
void
SWFTextField_setScaledWidth(SWFTextField field, int width)
{
	field->width = width;
	resetBounds(field);
}
예제 #9
0
void
SWFTextField_setScaledFieldHeight(SWFTextField field, int height)
{
	field->fieldHeight = height;
	resetBounds(field);
}
void CyclicCoordinateDescent::findMode(
		int maxIterations,
		int convergenceType,
		double epsilon
		) {

	if (convergenceType < GRADIENT || convergenceType > ZHANG_OLES) {
	    std::ostringstream stream;
		stream << "Unknown convergence criterion: " << convergenceType;
		error->throwError(stream);
	}

	if (!validWeights || hXI.getTouchedY() // || hXI.getTouchedX()
		) {
		computeNEvents();
		computeFixedTermsInLogLikelihood();
		computeFixedTermsInGradientAndHessian();
		validWeights = true;
		hXI.clean();
	}

	if (!xBetaKnown) {
		computeXBeta();
		xBetaKnown = true;
		sufficientStatisticsKnown = false;
	}

	if (!sufficientStatisticsKnown) {
		computeRemainingStatistics(true, 0); // TODO Check index?
		sufficientStatisticsKnown = true;
	}

	resetBounds();

	bool done = false;
	int iteration = 0;
	double lastObjFunc = 0.0;

	if (convergenceType < ZHANG_OLES) {
		lastObjFunc = getObjectiveFunction(convergenceType);
	} else { // ZHANG_OLES
		saveXBeta();
	}

	while (!done) {

		// Do a complete cycle
		for(int index = 0; index < J; index++) {

			if (!fixBeta[index]) {
				double delta = ccdUpdateBeta(index);
				delta = applyBounds(delta, index);
				if (delta != 0.0) {
					sufficientStatisticsKnown = false;
					updateSufficientStatistics(delta, index);
				}
			}

			if ( (noiseLevel > QUIET) && ((index+1) % 100 == 0)) {
			    std::ostringstream stream;
			    stream << "Finished variable " << (index+1);
			    logger->writeLine(stream);
			}

		}

		iteration++;
//		bool checkConvergence = (iteration % J == 0 || iteration == maxIterations);
		bool checkConvergence = true; // Check after each complete cycle

		if (checkConvergence) {

			double conv;
			bool illconditioned = false;
			if (convergenceType < ZHANG_OLES) {
 				double thisObjFunc = getObjectiveFunction(convergenceType);
				if (thisObjFunc != thisObjFunc) {
				    std::ostringstream stream;
					stream << "\nWarning: problem is ill-conditioned for this choice of\n"
                           << "\t prior (" << jointPrior->getDescription() << ") or\n"
                           << "\t initial bounding box (" << initialBound << ")\n"
                           << "Enforcing convergence!";
					logger->writeLine(stream);
					conv = 0.0;
					illconditioned = true;
				} else {
					conv = computeConvergenceCriterion(thisObjFunc, lastObjFunc);
				}
				lastObjFunc = thisObjFunc;
			} else { // ZHANG_OLES
				conv = computeZhangOlesConvergenceCriterion();
				saveXBeta();
			} // Necessary to call getObjFxn or computeZO before getLogLikelihood,
			  // since these copy over XBeta

			double thisLogLikelihood = getLogLikelihood();
			double thisLogPrior = getLogPrior();
			double thisLogPost = thisLogLikelihood + thisLogPrior;

            std::ostringstream stream;
			if (noiseLevel > QUIET) {
			    stream << "\n";
				printVector(&hBeta[0], J, stream);
				stream << "\n";
				stream << "log post: " << thisLogPost
						<< " (" << thisLogLikelihood << " + " << thisLogPrior
						<< ") (iter:" << iteration << ") ";
			}

			if (epsilon > 0 && conv < epsilon) {
				if (illconditioned) {
					lastReturnFlag = ILLCONDITIONED;
				} else {
					if (noiseLevel > SILENT) {
						stream << "Reached convergence criterion";
					}
					lastReturnFlag = SUCCESS;
				}
				done = true;
			} else if (iteration == maxIterations) {
				if (noiseLevel > SILENT) {
					stream << "Reached maximum iterations";
				}
				done = true;
				lastReturnFlag = MAX_ITERATIONS;
			}
			if (noiseLevel > QUIET) {
                logger->writeLine(stream);
			}

			logger->yield();
		}
	}
	lastIterationCount = iteration;
	updateCount += 1;

	modelSpecifics.printTiming();

	fisherInformationKnown = false;
	varianceKnown = false;
}
예제 #11
0
	//----------------------------------------------------------------------
	void TerrainQuadTreeNode::updateVertexBuffer(const Rect& rect)
	{
		_AST (rect.left >= mOffsetX && rect.right <= mBoundaryX && 
			rect.top >= mOffsetY && rect.bottom <= mBoundaryY);

		// potentially reset our bounds depending on coverage of the update
		resetBounds(rect);

		// Main data
		uint16 inc = (mTerrain->getSize()-1) / (mVertexDataRecord->resolution-1);
		long destOffsetX = rect.left <= mOffsetX ? 0 : (rect.left - mOffsetX) / inc;
		long destOffsetY = rect.top <= mOffsetY ? 0 : (rect.top - mOffsetY) / inc;

		// Fill the buffers
		float uvScale = 1.0f / (mTerrain->getSize() - 1);
		const float* pBaseHeight = mTerrain->getHeightData(rect.left, rect.top);
		const float* pBaseDelta = mTerrain->getDeltaData(rect.left, rect.top);
		uint16 rowskip = mTerrain->getSize() * inc;
		uint16 destPosRowSkip = 0, destDeltaRowSkip = 0;
		unsigned char* pRootPosBuf = 0;
		unsigned char* pRootDeltaBuf = 0;
		unsigned char* pRowPosBuf = 0;
		unsigned char* pRowDeltaBuf = 0;
		const uint32 nVertSizePos = sizeof(uint16) * 2 + sizeof(float);
		const uint32 nVertSizeDelta = sizeof(float) * 2;

		if (mVertexDataRecord->cpuVertexPosData)
		{
			destPosRowSkip = mVertexDataRecord->size * nVertSizePos;
			pRootPosBuf = static_cast<unsigned char*>(mVertexDataRecord->cpuVertexPosData);
			pRowPosBuf = pRootPosBuf;
			// skip dest buffer in by left/top
			pRowPosBuf += destOffsetY * destPosRowSkip + destOffsetX * nVertSizePos;
		}
		if (mVertexDataRecord->cpuVertexDeltaData)
		{
			destDeltaRowSkip = mVertexDataRecord->size * nVertSizeDelta;
			pRootDeltaBuf = static_cast<unsigned char*>(mVertexDataRecord->cpuVertexDeltaData);
			pRowDeltaBuf = pRootDeltaBuf;
			// skip dest buffer in by left/top
			pRowDeltaBuf += destOffsetY * destDeltaRowSkip + destOffsetX * nVertSizeDelta;
		}
		VEC3 pos;
		
		for (uint16 y = rect.top; y < rect.bottom; y += inc)
		{
			const float* pHeight = pBaseHeight;
			const float* pDelta = pBaseDelta;
			float* pPosBuf = static_cast<float*>(static_cast<void*>(pRowPosBuf));
			float* pDeltaBuf = static_cast<float*>(static_cast<void*>(pRowDeltaBuf));
			for (uint16 x = rect.left; x < rect.right; x += inc)
			{
				if (pPosBuf)
				{
					mTerrain->getPoint(x, y, *pHeight, &pos);

					// Update bounds *before* making relative
					mergeIntoBounds(x, y, pos);
					// relative to local centre
					pos -= mLocalCentre;
			
					writePosVertex(x, y, *pHeight, pos, uvScale, &pPosBuf);
					pHeight += inc;
					

				}

				if (pDeltaBuf)
				{
					// delta, and delta LOD threshold
					// we want delta to apply to LODs no higher than this value
					// at runtime this will be combined with a per-renderable parameter
					// to ensure we only apply morph to the correct LOD
					writeDeltaVertex(x, y, *pDelta, 
						(float)mTerrain->getLODLevelWhenVertexEliminated(x, y) - 1.0f, 
						&pDeltaBuf);
					pDelta += inc;

				}

				
			}
			pBaseHeight += rowskip;
			pBaseDelta += rowskip;
			if (pRowPosBuf)
				pRowPosBuf += destPosRowSkip;
			if (pRowDeltaBuf)
				pRowDeltaBuf += destDeltaRowSkip;

		}

		// Skirts now
		// skirt spacing based on top-level resolution (* inc to cope with resolution which is not the max)
		uint16 skirtSpacing = mVertexDataRecord->skirtRowColSkip * inc;
		VEC3 skirtOffset;
		mTerrain->getVector(0, 0, -mTerrain->getSkirtSize(), &skirtOffset);

		// skirt rows
		// clamp rows to skirt spacing (round up)
		long skirtStartX = rect.left;
		long skirtStartY = rect.top;
		// for rows, clamp Y to skirt frequency, X to inc (LOD resolution vs top)
		if (skirtStartY % skirtSpacing)
			skirtStartY += skirtSpacing - (skirtStartY % skirtSpacing);
		if (skirtStartX % inc)
			skirtStartX += inc - (skirtStartX % inc);
		skirtStartY = std::max(skirtStartY, (long)mOffsetY);
		pBaseHeight = mTerrain->getHeightData(skirtStartX, skirtStartY);

		if (mVertexDataRecord->cpuVertexPosData)
		{
			// position dest buffer just after the main vertex data
			pRowPosBuf = pRootPosBuf + nVertSizePos * mVertexDataRecord->size * mVertexDataRecord->size;
			// move it onwards to skip the skirts we don't need to update
			pRowPosBuf += destPosRowSkip * ((skirtStartY - mOffsetY) / skirtSpacing);
			pRowPosBuf += nVertSizePos * (skirtStartX - mOffsetX) / inc;
		}
		if (mVertexDataRecord->cpuVertexDeltaData)
		{
			// position dest buffer just after the main vertex data
			pRowDeltaBuf = pRootDeltaBuf + nVertSizeDelta * mVertexDataRecord->size * mVertexDataRecord->size;
			// move it onwards to skip the skirts we don't need to update
			pRowDeltaBuf += destDeltaRowSkip * (skirtStartY - mOffsetY) / skirtSpacing;
			pRowDeltaBuf += nVertSizeDelta * (skirtStartX - mOffsetX) / inc;
		}
		for (uint16 y = skirtStartY; y < rect.bottom; y += skirtSpacing)
		{
			const float* pHeight = pBaseHeight;
			float* pPosBuf = static_cast<float*>(static_cast<void*>(pRowPosBuf));
			float* pDeltaBuf = static_cast<float*>(static_cast<void*>(pRowDeltaBuf));
			for (uint16 x = skirtStartX; x < rect.right; x += inc)
			{
				if (mVertexDataRecord->cpuVertexPosData)
				{
					mTerrain->getPoint(x, y, *pHeight, &pos);
					// relative to local centre
					pos -= mLocalCentre;
					pos += skirtOffset;
					writePosVertex(x, y, *pHeight - mTerrain->getSkirtSize(), pos, uvScale, &pPosBuf);

					pHeight += inc;

					

				}

				if (mVertexDataRecord->cpuVertexDeltaData)
				{
					// delta (none)
					// delta threshold (irrelevant)
					writeDeltaVertex(x, y, 0, 99, &pDeltaBuf);
				}
			}
			pBaseHeight += mTerrain->getSize() * skirtSpacing;
			if (pRowPosBuf)
				pRowPosBuf += destPosRowSkip;
			if (pRowDeltaBuf)
				pRowDeltaBuf += destDeltaRowSkip;
		}

		// skirt cols
		// clamp cols to skirt spacing (round up)
		skirtStartX = rect.left;
		if (skirtStartX % skirtSpacing)
			skirtStartX += skirtSpacing - (skirtStartX % skirtSpacing);
		// clamp Y to inc (LOD resolution vs top)
		skirtStartY = rect.top;
		if (skirtStartY % inc)
			skirtStartY += inc - (skirtStartY % inc);
		skirtStartX = std::max(skirtStartX, (long)mOffsetX);

		if (mVertexDataRecord->cpuVertexPosData)
		{
			// position dest buffer just after the main vertex data and skirt rows
			pRowPosBuf = pRootPosBuf + nVertSizePos * mVertexDataRecord->size * mVertexDataRecord->size;
			// skip the row skirts
			pRowPosBuf += mVertexDataRecord->numSkirtRowsCols * mVertexDataRecord->size * nVertSizePos;
			// move it onwards to skip the skirts we don't need to update
			pRowPosBuf += destPosRowSkip * (skirtStartX - mOffsetX) / skirtSpacing;
			pRowPosBuf += nVertSizePos * (skirtStartY - mOffsetY) / inc;
		}
		if (mVertexDataRecord->cpuVertexDeltaData)
		{
			// Delta dest buffer just after the main vertex data and skirt rows
			pRowDeltaBuf = pRootDeltaBuf + nVertSizeDelta * mVertexDataRecord->size * mVertexDataRecord->size;
			// skip the row skirts
			pRowDeltaBuf += mVertexDataRecord->numSkirtRowsCols * mVertexDataRecord->size * nVertSizeDelta;
			// move it onwards to skip the skirts we don't need to update
			pRowDeltaBuf += destDeltaRowSkip * (skirtStartX - mOffsetX) / skirtSpacing;
			pRowDeltaBuf += nVertSizeDelta * (skirtStartY - mOffsetY) / inc;
		}
		
		for (uint16 x = skirtStartX; x < rect.right; x += skirtSpacing)
		{
			float* pPosBuf = static_cast<float*>(static_cast<void*>(pRowPosBuf));
			float* pDeltaBuf = static_cast<float*>(static_cast<void*>(pRowDeltaBuf));
			for (uint16 y = skirtStartY; y < rect.bottom; y += inc)
			{
				if (mVertexDataRecord->cpuVertexPosData)
				{
					float height = mTerrain->getHeightAtPoint(x, y);
					mTerrain->getPoint(x, y, height, &pos);
					// relative to local centre
					pos -= mLocalCentre;
					pos += skirtOffset;
					
					writePosVertex(x, y, height - mTerrain->getSkirtSize(), pos, uvScale, &pPosBuf);

				}
				if (mVertexDataRecord->cpuVertexDeltaData)
				{
					// delta (none)
					// delta threshold (irrelevant)
					writeDeltaVertex(x, y, 0, 99, &pDeltaBuf);
				}
			}
			if (pRowPosBuf)
				pRowPosBuf += destPosRowSkip;
			if (pRowDeltaBuf)
				pRowDeltaBuf += destDeltaRowSkip;
		}
	}
예제 #12
0
void Creep::update(float deltaTime)
{
    m_fStateTime += deltaTime;
    
    m_healthBarFrame = m_health * 16 / m_maxHealth - 1;
    m_healthBarFrame = m_healthBarFrame < 0 ? 0 : m_healthBarFrame;
    
    m_timeToShowHealthBar -= deltaTime;
    
    if (FlagUtil::isFlagSet(m_creepCondition, ELECTRIFIED))
    {
        if (m_electrifiedTime > 0)
        {
            m_electrifiedTime -= deltaTime;
        }
        else
        {
            m_creepCondition = FlagUtil::removeFlag(m_creepCondition, ELECTRIFIED);
            m_speed = m_initialSpeed;
            
            if (FlagUtil::isFlagSet(m_creepCondition, FROZEN))
            {
                m_speed /= 3;
            }
        }
    }
    
    if (FlagUtil::isFlagSet(m_creepCondition, POISONED))
    {
        if (m_poisonedTime > 0)
        {
            bool isFrozen = FlagUtil::isFlagSet(m_creepCondition, FROZEN);
            
            m_poisonedTime -= deltaTime;
            m_poisonTime += deltaTime;
            
            while (m_poisonTime > TIME_FOR_POISON_DAMAGE)
            {
                m_poisonTime -= TIME_FOR_POISON_DAMAGE;
                takeDamage(m_poisonDamage, Damage_Type::ACID);
            }
            
            if (m_isGrowingDueToPoison)
            {
                m_fWidth += deltaTime * (isFrozen ? 0.1f : 0.5f);
                m_fHeight += deltaTime * (isFrozen ? 0.1f : 0.5f);
                if (m_fWidth > m_maxSize)
                {
                    m_fWidth = m_maxSize;
                    m_fHeight = m_maxSize;
                    m_isGrowingDueToPoison = false;
                }
            }
            else
            {
                m_fWidth -= deltaTime * (isFrozen ? 0.1f : 0.5f);
                m_fHeight -= deltaTime * (isFrozen ? 0.1f : 0.5f);
                if (m_fWidth < m_halfSize)
                {
                    m_fWidth = m_halfSize;
                    m_fHeight = m_halfSize;
                    m_isGrowingDueToPoison = true;
                }
            }
        }
        else
        {
            m_creepCondition = FlagUtil::removeFlag(m_creepCondition, POISONED);
            m_fWidth = m_defaultSize;
            m_fHeight = m_defaultSize;
        }
        
        resetBounds(m_fWidth * SIZE_TO_BOUNDS_RATIO, m_fHeight * SIZE_TO_BOUNDS_RATIO);
    }
    
    if (FlagUtil::isFlagSet(m_creepCondition, FROZEN))
    {
        if (m_frozenTime > 0)
        {
            m_frozenTime -= deltaTime;
            m_fRed += m_frozenRecoveryRate * deltaTime;
            m_fGreen = m_fRed;
        }
        else
        {
            thaw();
        }
    }
    else if (FlagUtil::isFlagSet(m_creepCondition, ON_FIRE))
    {
        if (m_burnTime > 0)
        {
            m_burnTime -= deltaTime;
        }
        else
        {
            m_creepCondition = FlagUtil::removeFlag(m_creepCondition, ON_FIRE);
            m_creepCondition = FlagUtil::setFlag(m_creepCondition, FIRE_RECOVERY);
        }
    }
    else if (FlagUtil::isFlagSet(m_creepCondition, FIRE_RECOVERY))
    {
        m_fRed += 1.5f * deltaTime;
        m_fGreen = m_fRed;
        m_fBlue = m_fRed;
        
        if (m_fRed > 1)
        {
            m_creepCondition = FlagUtil::removeFlag(m_creepCondition, FIRE_RECOVERY);
            resetColor();
        }
    }
    
    m_deltaX = m_velocity->getX() * deltaTime;
    m_deltaY = m_velocity->getY() * deltaTime;
    m_position->add(m_deltaX, m_deltaY);
    m_direction = calcDirection();
    updateBounds();
}