void CMerchantObject::RunRace()
{
	if ((rand() % 40) == 0)
		TurnTo(rand() % 8);
	else if ((rand() % 50) == 0)
		AddRefMsg(RM_HIT, m_nDirection, m_nCurrX, m_nCurrY, 0, NULL);
}
Beispiel #2
0
void Boid::Tick()
{
	const float rangesq = 50.0f*50.0f;

	std::vector< const Boid* > neighbours;
	neighbours.reserve(100);
	DudeList& dudes = g_Agents->Dudes();
	DudeList::const_iterator it;
	vec2 const& pos = Pos();
	for( it=dudes.begin(); it!=dudes.end(); ++it )
	{
		if( *it == this )
			continue;
		vec2 d = (*it)->Pos()-pos;
		if( d.LenSq() < rangesq )
		{
			// DANGER DANGER!!! (need to sort out better casting!)
			neighbours.push_back( (const Boid*)*it );
		}
	}

	vec2 groupingacc = CalcGroupingAcc( neighbours );
	vec2 velmatchacc = CalcVelMatchAcc( neighbours );
	// TODO: separation!

	vec2 attackacc = g_Player->Pos() - Pos();
	if( attackacc.LenSq() < 80*80 )
		attackacc.Normalise();
	else
		attackacc = vec2::ZERO;

	vec2 avoidboundaryacc = vec2::ZERO;
	float bound = g_CurrentLevel->ArenaRadius()-20.0f;
	if( Pos().LenSq() > bound*bound )
	{
		avoidboundaryacc = -Pos();
		avoidboundaryacc.Normalise();
		avoidboundaryacc *= 0.1f;
	}

	vec2 acc = 0.3f*groupingacc + 0.6f*velmatchacc + 0.1f*attackacc + 0.4*avoidboundaryacc;
	m_Vel += acc;

	const float maxvel=1.0f;
	if( m_Vel.LenSq() > maxvel )
	{
		m_Vel.Normalise();
		m_Vel *= maxvel;
	}

	MoveBy(m_Vel);

	TurnTo( atan2(m_Vel.x,m_Vel.y) );
}
void CAdActor::InitLine(CBPoint StartPt, CBPoint EndPt)
{
	m_PFCount = max( (abs(EndPt.x - StartPt.x)) , (abs(EndPt.y - StartPt.y)) );

	m_PFStepX = (double)(EndPt.x - StartPt.x) / m_PFCount;
	m_PFStepY = (double)(EndPt.y - StartPt.y) / m_PFCount;

	m_PFX = StartPt.x;
	m_PFY = StartPt.y;

	int angle = (int)(atan2((double)(EndPt.y - StartPt.y), (double)(EndPt.x - StartPt.x)) * (180/3.14));

	m_NextState = STATE_FOLLOWING_PATH;

	TurnTo(AngleToDirection(angle));
}
Beispiel #4
0
	virtual void MoveAndTurnTo(entity_pos_t x, entity_pos_t z, entity_angle_t ry)
	{
		m_X = x;
		m_Z = z;

		if (!m_InWorld)
		{
			m_InWorld = true;
			m_LastX = m_PrevX = m_X;
			m_LastZ = m_PrevZ = m_Z;
			m_LastYDifference = entity_pos_t::Zero();
		}

		// TurnTo will advertise the position changes
		TurnTo(ry);

		AdvertiseInterpolatedPositionChanges();
	}
Beispiel #5
0
UpdateResult Turret::update2(int ms, GlobalState &GS)
{
	bool Firing = false;
	Vector2d ShootingDirection = Vector2d(0,0);
	Grid* G = GS.TheGrid;
	std::list<Cell*> NearbyCells;
	G->get_nearby_cells(NearbyCells, Pos, CellSize * 12);
	for (auto itr = NearbyCells.begin(); itr != NearbyCells.end(); ++itr)
	{
		for (auto itr2 = (*itr)->CreepList.begin(); itr2 != (*itr)->CreepList.end(); ++itr2)
		{
			if(CheckVisibility(Pos, (*itr)->getPos()))
				ShootingDirection += GetForce(Pos, (*itr)->getPos());
		}
	}
	if(ShootingDirection.x != 0 && ShootingDirection.y != 0)
	{
		Firing = true;
		TurnTo(Rot, atan2(ShootingDirection.y, ShootingDirection.x), 8 * (ms / 1000.0));
	}
	FireTimer -= ms;
	if(FireTimer < 0)
	{
		if(Firing)
		{

			FireTimer += FireRate;
			Projectile* new_projectile = ProjectileToFireOnDeath->clone();
			new_projectile->setPos(Pos);
			new_projectile->setRot(Rot);
			Parent->AddChild (new_projectile);
			//Out of ammo
			if(--Ammo == 0)
				return UPDATE_DELETE;
		}
		else
		{
			FireTimer = 0;
		}
	}

	return UPDATE_REDRAW;
}
void CAdActor::FollowPath()
{
	// skip current position
	m_Path->GetFirst();
	while(m_Path->GetCurrent()!=NULL)
	{
		if(m_Path->GetCurrent()->x != m_PosX || m_Path->GetCurrent()->y != m_PosY) break;
		m_Path->GetNext();
	}

	// are there points to follow?
	if(m_Path->GetCurrent() != NULL)
	{
		m_State = STATE_FOLLOWING_PATH;;
		InitLine(CBPoint(m_PosX, m_PosY), *m_Path->GetCurrent());
	}
	else
	{
		if(m_AfterWalkDir!=DI_NONE) TurnTo(m_AfterWalkDir);
		else m_State = STATE_READY;
	}
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
HRESULT CAdActor::ScCallMethod(CScScript* Script, CScStack *Stack, CScStack *ThisStack, char *Name)
{
	//////////////////////////////////////////////////////////////////////////
	// GoTo / GoToAsync
	//////////////////////////////////////////////////////////////////////////
	if(strcmp(Name, "GoTo")==0 || strcmp(Name, "GoToAsync")==0)
	{
		Stack->CorrectParams(2);
		int X = Stack->Pop()->GetInt();
		int Y = Stack->Pop()->GetInt();
		GoTo(X, Y);
		if(strcmp(Name, "GoToAsync")!=0) Script->WaitForExclusive(this);
		Stack->PushNULL();
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GoToObject / GoToObjectAsync
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GoToObject")==0 || strcmp(Name, "GoToObjectAsync")==0)
	{
		Stack->CorrectParams(1);
		CScValue* Val = Stack->Pop();
		if(!Val->IsNative())
		{
			Script->RuntimeError("actor.%s method accepts an entity refrence only", Name);
			Stack->PushNULL();
			return S_OK;
		}
		CAdObject* Obj = (CAdObject*)Val->GetNative();
		if(!Obj || Obj->m_Type != OBJECT_ENTITY)
		{
			Script->RuntimeError("actor.%s method accepts an entity refrence only", Name);
			Stack->PushNULL();
			return S_OK;
		}
		CAdEntity* Ent = (CAdEntity*)Obj;
		if(Ent->m_WalkToX==0 && Ent->m_WalkToY==0) GoTo(Ent->m_PosX, Ent->m_PosY);
		else GoTo(Ent->m_WalkToX, Ent->m_WalkToY, Ent->m_WalkToDir);
		if(strcmp(Name, "GoToObjectAsync")!=0) Script->WaitForExclusive(this);
		Stack->PushNULL();
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// TurnTo / TurnToAsync
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "TurnTo")==0 || strcmp(Name, "TurnToAsync")==0)
	{
		Stack->CorrectParams(1);
		int dir;
		CScValue* val = Stack->Pop();
		
		// turn to object?
		if(val->IsNative() && Game->ValidObject((CBObject*)val->GetNative()))
		{
			CBObject* obj = (CBObject*)val->GetNative();
			int angle = (int)(atan2((double)(obj->m_PosY - m_PosY), (double)(obj->m_PosX - m_PosX)) * (180/3.14));
			dir = (int)AngleToDirection(angle);
		}
		// otherwise turn to direction
		else dir = val->GetInt();

		if(dir >= 0 && dir < NUM_DIRECTIONS)
		{
			TurnTo((TDirection)dir);
			if(strcmp(Name, "TurnToAsync")!=0) Script->WaitForExclusive(this);
		}
		Stack->PushNULL();
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// IsWalking
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "IsWalking")==0)
	{
		Stack->CorrectParams(0);
		Stack->PushBool(m_State==STATE_FOLLOWING_PATH);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// MergeAnims
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "MergeAnims")==0)
	{
		Stack->CorrectParams(1);
		Stack->PushBool(SUCCEEDED(MergeAnims(Stack->Pop()->GetString())));
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// UnloadAnim
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "UnloadAnim")==0)
	{
		Stack->CorrectParams(1);
		char* AnimName = Stack->Pop()->GetString();

		bool Found = false;
		for(int i=0; i<m_Anims.GetSize(); i++)
		{
			if(stricmp(m_Anims[i]->m_Name, AnimName)==0)
			{
				// invalidate sprites in use
				if(m_Anims[i]->ContainsSprite(m_TempSprite2)) m_TempSprite2 = NULL;
				if(m_Anims[i]->ContainsSprite(m_CurrentSprite)) m_CurrentSprite = NULL;
				if(m_Anims[i]->ContainsSprite(m_AnimSprite2)) m_AnimSprite2 = NULL;

				SAFE_DELETE(m_Anims[i]);
				m_Anims.RemoveAt(i);
				i--;
				Found = true;
			}
		}
		Stack->PushBool(Found);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// HasAnim
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "HasAnim")==0)
	{
		Stack->CorrectParams(1);
		char* AnimName = Stack->Pop()->GetString();
		Stack->PushBool(GetAnimByName(AnimName) != NULL);
		return S_OK;
	}

	else return CAdTalkHolder::ScCallMethod(Script, Stack, ThisStack, Name);
}
void CAdActor::GetNextStep()
{
	if(m_WalkSprite)
	{
		m_CurrentSprite = m_WalkSprite->GetSprite(m_Dir);
	}
	else
	{
		CAdSpriteSet* Anim = GetAnimByName(m_WalkAnimName);
		if(Anim) m_CurrentSprite = Anim->GetSprite(m_Dir);
	}
	
	if(!m_CurrentSprite) return;

	m_CurrentSprite->GetCurrentFrame(m_Zoomable?((CAdGame*)Game)->m_Scene->GetZoomAt(m_PosX, m_PosY):100, m_Zoomable?((CAdGame*)Game)->m_Scene->GetZoomAt(m_PosX, m_PosY):100);
	if(!m_CurrentSprite->m_Changed) return;

		
	int MaxStepX, MaxStepY;
	MaxStepX = abs(m_CurrentSprite->m_MoveX);
	MaxStepY = abs(m_CurrentSprite->m_MoveY);

	MaxStepX = max(MaxStepX, MaxStepY);
	MaxStepX = max(MaxStepX, 1);

	while(m_PFCount > 0 && MaxStepX >= 0)
	{
		m_PFX += m_PFStepX;
		m_PFY += m_PFStepY;

		m_PFCount--;
		MaxStepX--;
	}

	if(((CAdGame*)Game)->m_Scene->IsBlockedAt(m_PFX, m_PFY, true, this))
	{
		if(m_PFCount==0)
		{
			m_State = m_NextState;
			m_NextState = STATE_READY;
			return;
		}
		GoTo(m_TargetPoint->x, m_TargetPoint->y);
		return;
	}


	m_PosX = (int)m_PFX;
	m_PosY = (int)m_PFY;

	AfterMove();
	

	if(m_PFCount == 0)
	{
		if(m_Path->GetNext()==NULL)
		{
			m_PosX = m_TargetPoint->x;
			m_PosY = m_TargetPoint->y;

			m_Path->Reset();
			if(m_AfterWalkDir!=DI_NONE) TurnTo(m_AfterWalkDir);
			else
			{
				m_State = m_NextState;
				m_NextState = STATE_READY;
			}
		}
		else InitLine(CBPoint(m_PosX, m_PosY), *m_Path->GetCurrent());
	}
}