Пример #1
0
bool BattleManagerScreen::GetVecBetween( ICastEntity* from, ICastEntity* to, kmVec2& distVec )
{
	CastWorldModel* world = CastWorldModel::get();

	if( !world->isValid(from) || !world->isValid(to) ) return false;

	kmVec2 pFrom;
	pFrom.x = pFrom.y = 0;
	GameEntityView* fromView = getViewForEntity(from);
	if( fromView != NULL ) 
	{
		pFrom.x = fromView->getPositionX();
		pFrom.y = fromView->getPositionY();
	}
	
	kmVec2 pTo;
	pTo.x = pTo.y = 0;
	GameEntityView* toView = getViewForEntity(to);
	if( toView != NULL ) 
	{
		pTo.x = toView->getPositionX();
		pTo.y = toView->getPositionY();
	}else {
		CCLog("uhoh..");
	}

	kmVec2Subtract( &distVec, &pFrom, &pTo );
	kmVec2Scale(&distVec, &distVec, GAME_UNIT_CONVERSION ); //safe to operate on same vector

	return true;
}
Пример #2
0
void CastCommandState::spawnChannelEffects()
{
	//CCLog("spawn channel tick effect");

		//spawn effects
	CastTarget* target = m_iOwner->getTarget();
	target->validateTargets();

	
	for( int i=0; i< m_pModel->getNumEffectsOnChannel(); i++ )
	{
		CastEffect* effect = new CastEffect( );
		effect->init(this, i, m_iOwner, true );
		
		//TODO: send all effects as one array so only one "packet" has to travel

		CastWorldModel* world = CastWorldModel::get();
		world->addEffectInTransit(m_iOwner, effect, m_iOwner->getTarget(), CastCommandTime::get());
	}
}
Пример #3
0
void CastEffect::doEffect()
{
	CastWorldModel* world = CastWorldModel::get();

	if( ! world->isValid( m_pTarget ) ) return;

	if( m_startTime == 0 ) m_startTime = CastCommandTime::get();

	Json::Value json = getDescriptor();

	if( json.isMember("react") ) {
		m_pTarget->handleEffectReaction( json["react"], this );
	}
	
	CCLog("on tick %d", m_numTicksCompleted);
	switch( m_type ) 
	{
	case CET_DAMAGE_STAT:
		m_pTarget->incProperty( m_targetStat, -1* m_value );
		break;

	case CET_HEAL_STAT:
		m_pTarget->incProperty( m_targetStat,  m_value );
		break;

	case CET_SUPPRESS_STAT:
		m_pTarget->startBuffProperty( m_targetStat, -1* m_value, this );
		CCLog("cast at %f - lifetime %f", CastCommandTime::get(), m_lifeTime );
		CastCommandScheduler::get()->scheduleSelector( schedule_selector(CastEffect::onTick), this, m_lifeTime, 0, 0.0f, false);
		break;
				
	case CET_BUFF_STAT:
		m_pTarget->startBuffProperty( m_targetStat, m_value, this );
		CastCommandScheduler::get()->scheduleSelector( schedule_selector(CastEffect::onTick), this, m_lifeTime, 0, 0.0f, false);
		break;

	default:
		CCLOG("TODO: handle effect type");
	}

	//check for return effect


	if( json.isMember("returnEffect") )
	{
		json = json["returnEffect"];

		//validate 
		if( ! world->isValid( m_pOrigin ) ) return;

		CastEffect* bounce = new CastEffect();
		bounce->initReturnEffect(this);

		bounce->m_value = m_value;

		//swap direction
		ICastEntity* from = m_pTarget;
		ICastEntity* to = m_pOrigin;

		CastTarget* ghostTarget = new CastTarget();
		ghostTarget->addTargetEntity(to);

		world->addEffectInTransit(from, bounce, ghostTarget, CastCommandTime::get());

		CC_SAFE_RELEASE_NULL(ghostTarget);
	}


}
Пример #4
0
void CastCommandState::onCastComplete()
{
	if( m_state != CCS_CASTING ) return;

	CastWorldModel* world = CastWorldModel::get();
	if( !world->isValid( m_iOwner ) ) return;

	//check for cost (but dont apply it yet)
	if( m_costVal != 0 ) {
		float res = m_iOwner->getProperty( m_costStat );

		//checking cost>0 so that if a tricky user wants cost to be 'negative' to 'add' value
		//  we can do that even if it is below resource (ex: cost = increased heat)
		if( m_costVal > 0 && m_costVal > res ) {
			//not enough of resource to cast spell, so abort
			//todo: send aborted cast because of no resource
			CCLog("CCS: could not pay %f of %s to cast, aborting", m_costVal, m_costStat.c_str() );
			onCooldownStart();
			return;
		}

	}

	double currTime = CastCommandTime::get();
	m_timeStart = currTime;
	
	//spawn effects
	CastTarget* target = m_iOwner->getTarget();
	//target->validateTargets();
	bool hasTargetInRange = target->hasTargetsAtRangeFromEntity(m_pModel->getRange(), m_iOwner);
	if(!hasTargetInRange) {
		CCLOG("CCS: no targets in range on cast of %s", m_pModel->getName().c_str() );
		onCooldownStart();
		return;
	}


	bool foundTarget = false; //ensure we actually reach at least one target



	for( int i=0; i< m_pModel->getNumEffectsOnCast(); i++ )
	{
		//TODO: check for range
		//world->getPhysicsInterface()->GetVecBetween( m_iOwner, 

		

		CastEffect* effect = new CastEffect( );
		effect->init(this, i, m_iOwner, false );

		
		
		//TODO: send all effects as one array so only one "packet" has to travel? //[Optimisation]

		world->addEffectInTransit(m_iOwner, effect, m_iOwner->getTarget(), CastCommandTime::get());

		foundTarget = true;
	}

	if( foundTarget && m_costVal != 0 ) {
		//apply cost
		m_iOwner->incProperty( m_costStat, -1*m_costVal, NULL );
	}

	if( m_pModel->channelTime > 0.0f ) {
		//begin channeling
		m_state = CCS_CHANNELING;
		int numTicks = (m_pModel->channelTime / m_pModel->channelFreq) + 1;
		CastCommandScheduler::get()->scheduleSelector( schedule_selector(CastCommandState::onSchedulerTick), this, m_pModel->channelFreq, numTicks, 0.0f, false);
	}else {
		//CCLog("Cast %s complete!", m_pModel->getName().c_str());
		onCooldownStart();
	}
}