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); }
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)); }
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(); }
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()); } }