//---------------------------- DispatchMessage --------------------------- // // given a message, a receiver, a sender and any time delay , this function // routes the message to the correct agent (if no delay) or stores // in the message queue to be dispatched at the correct time //------------------------------------------------------------------------ void MessageDispatcher::DispatchMessage(double delay, int sender, int receiver, int msg, void* ExtraInfo) { SetTextColor(BACKGROUND_RED|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); //get pointers to the sender and receiver BaseGameEntity* pSender = EntityMgr->GetEntityFromID(sender); BaseGameEntity* pReceiver = EntityMgr->GetEntityFromID(receiver); //make sure the receiver is valid if (pReceiver == NULL) { cout << "\nWarning! No Receiver with ID of " << receiver << " found"; return; } //create the telegram Telegram telegram(0, sender, receiver, msg, ExtraInfo); //if there is no delay, route telegram immediately if (delay <= 0.0f) { SetTextColor(BACKGROUND_RED|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); cout << "\nInstant telegram dispatched at time: " << Clock->GetCurrentTime() << " by " << GetNameOfEntity(pSender->ID()) << " for " << GetNameOfEntity(pReceiver->ID()) << ". Msg is "<< MsgToStr(msg); //send the telegram to the recipient Discharge(pReceiver, telegram); } //else calculate the time when the telegram should be dispatched else { double CurrentTime = Clock->GetCurrentTime(); telegram.DispatchTime = CurrentTime + delay; //and put it in the queue PriorityQ.insert(telegram); SetTextColor(BACKGROUND_RED|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); cout << "\nDelayed telegram from " << GetNameOfEntity(pSender->ID()) << " recorded at time " << Clock->GetCurrentTime() << " for " << GetNameOfEntity(pReceiver->ID()) << ". Msg is "<< MsgToStr(msg); } }
void StateZombieAttackBite::Execute(Zombie* pZombie, u32 elapsedTime) { Animate(pZombie, elapsedTime); //-------------------------------------------- // // use physics model for executing // //-------------------------------------------- // find target object ZombiePhysics* pPhysicsModel = pZombie->GetPhysicsModel(); pPhysicsModel->ResetTarget(); vector2df me(pZombie->Pos().X,pZombie->Pos().Y); std::vector<BaseGameEntity*> enties = EntityMgr.GetEntityListFromGroupID(ENTITY_TYPE_HUMAN); bool isTarget = false; for (std::vector<BaseGameEntity*>::iterator iter = enties.begin(); iter != enties.end(); iter++) { // find out close human, BaseGameEntity* pEntity = *iter; f32 collisiondistance = me.getDistanceFrom(vector2df(pEntity->Pos().X, pEntity->Pos().Y)); if(RANGE_ZOMBIE_ATTACKMEELE_RECOGNITION >= collisiondistance)//±ÙÁ¢ °ø°Ý ¹üÀ§ ¾È¿¡¼ ÀÖ´ÂÁö? { pPhysicsModel->SetTarget(b2Vec2(pEntity->Pos().X, pEntity->Pos().Y)); isTarget = true; #ifdef ZOBIE_AILEVEL_INFECTION_SYSTEM int idAttacked = pEntity->ID(); //sendmessage: human À» °¨¿°»óÅ·Π... Dispatcher->DispatchMsg(SEND_MSG_IMMEDIATELY, // time delay pZombie->ID(), // ID of sender idAttacked, // ID of recipient MSG_TYPE_HUMAN_INFECTION, // the message NO_ADDITIONAL_INFO); #endif break; } } if(!isTarget)//Ÿ°ÙÀ» ³õÄ¡¸é ´Ù½Ã roam »óÅ·Π{ pZombie->GetPhysicsModel()->GetBody()->m_maxForwardSpeed = ZOMBIE_ROAMSTATE_PHYSICS_MAX_FORWARDSPEED; pZombie->GetPhysicsModel()->GetBody()->m_maxDriveForce = ZOMBIE_ROAMSTATE_PHYSICS_MAX_FRONTFORCE; pZombie->GetFSM()->ChangeState(StateZombieRoam::Instance()); } pPhysicsModel->Update(elapsedTime); //-------------------------------------------- // // apply executed result to object property // //-------------------------------------------- b2Vec2 vec = pZombie->GetPhysicsModel()->GetPosition(); f32 angle = pZombie->GetPhysicsModel()->GetAngle(); pZombie->SetPos(vector3df(vec.x, vec.y, 0)); pZombie->SetRotation(vector3df(0.f, 0.f, ANGLE_TO_RADIAN(angle))); }
//---------------------- DispatchDelayedMessages ------------------------- // // This function dispatches any telegrams with a timestamp that has // expired. Any dispatched telegrams are removed from the queue //------------------------------------------------------------------------ void MessageDispatcher::DispatchDelayedMessages() { // cout << "\nDispatch Delayed Message"; //first get current time double CurrentTime = Clock->GetCurrentTime(); //cout << "\nCurrent time" << CurrentTime; //now peek at the queue to see if any telegrams need dispatching. //remove all telegrams from the front of the queue that have gone //past their sell by date /*if(!PriorityQ.empty()){ cout << "\nDispatch time" << PriorityQ.begin()->DispatchTime; }*/ while( !PriorityQ.empty() && (PriorityQ.begin()->DispatchTime < CurrentTime) && (PriorityQ.begin()->DispatchTime > 0) ) { //read the telegram from the front of the queue const Telegram& telegram = *PriorityQ.begin(); //find the recipient BaseGameEntity* pReceiver = EntityMgr->GetEntityFromID(telegram.Receiver); cout << "\nQueued telegram ready for dispatch: Sent to " << GetNameOfEntity(pReceiver->ID()) << ". Msg is " << MsgToStr(telegram.Msg); //send the telegram to the recipient Discharge(pReceiver, telegram); //remove it from the queue PriorityQ.erase(PriorityQ.begin()); } }
//---------------------- DispatchDelayedMessages ------------------------- // // This function dispatches any telegrams with a timestamp that has // expired. Any dispatched telegrams are removed from the queue //------------------------------------------------------------------------ void MessageDispatcher::DispatchDelayedMessages() { //first get current time double CurrentTime = TickCounter->GetCurrentFrame(); //now peek at the queue to see if any telegrams need dispatching. //remove all telegrams from the front of the queue that have gone //past their sell by date while( !PriorityQ.empty() && (PriorityQ.begin()->DispatchTime < CurrentTime) && (PriorityQ.begin()->DispatchTime > 0) ) { //read the telegram from the front of the queue const Telegram& telegram = *PriorityQ.begin(); //find the recipient BaseGameEntity* pReceiver = EntityMgr->GetEntityFromID(telegram.Receiver); #ifdef SHOW_MESSAGING_INFO debug_con << "\nQueued telegram ready for dispatch: Sent to " << pReceiver->ID() << ". Msg is "<< telegram.Msg << ""; #endif //send the telegram to the recipient Discharge(pReceiver, telegram); //remove it from the queue PriorityQ.erase(PriorityQ.begin()); } }
bool Human::Update(u32 elapsedTime) { //-------------------------------------------- // // update entity // //-------------------------------------------- MovingEntity::Update(elapsedTime); #ifdef HUMAN_AILEVEL_STARVATION_SYSTEM //effect which are applied independently of state if(m_fCurrentLifeEnergy>0) m_fCurrentLifeEnergy-= (elapsedTime * HUMAN_ENERGYDECREASE_PER_MILLISECOND); else m_fCurrentLifeEnergy=0; if(m_fCurrentLifeEnergy < HUMAN_THRESHOLD_TO_STARVATION && this-> m_State != HUMAN_STATE_STARVATION && this-> m_State != HUMAN_STATE_DEATH){ m_State = HUMAN_STATE_STARVATION; GetFSM()->ChangeState(StateHumanStarvation::Instance()); } #endif #ifdef HUMAN_AILEVEL_EAT_SYSTEM vector2df me(this->Pos().X,this->Pos().Y); std::vector<BaseGameEntity*> enties = EntityMgr.GetEntityListFromGroupID(ENTITY_TYPE_ITEM_FOOD); //bool isTarget = false; for (std::vector<BaseGameEntity*>::iterator iter = enties.begin(); iter != enties.end(); iter++) { // find out close human, but now just get first human.... BaseGameEntity* pEntity = *iter; f32 collisiondistance = me.getDistanceFrom(vector2df(pEntity->Pos().X, pEntity->Pos().Y)); if(RANGE_HUMAN_EAT_RECOGNITION >= collisiondistance) { //식량 섭취 m_fCurrentLifeEnergy = HUMAN_MAX_LIFE_ENERGY_DEFAULT; HumanPhysics* pPhysicsModel = this->GetPhysicsModel(); pPhysicsModel->ResetTarget(); GetFSM()->ChangeState(StateHumanHide::Instance()); //해당 아이템에 소멸 메세지 전달 int idfood = pEntity->ID(); Dispatcher->DispatchMsg(SEND_MSG_IMMEDIATELY, // time delay ID(), // ID of sender idfood, // ID of recipient MSG_TYPE_FOOD_DISAPPEAR, // the message NO_ADDITIONAL_INFO); //((BaseItem*)pEntity)->GetFSM()->ChangeState(StateBaseItemDisappear::Instance()); break; } } #endif if (m_pStateMachine) { m_pStateMachine->Update(elapsedTime); } //이전 프레임의 위치가 필요하므로 저장한다.(업데이트 되기전의 이전 좌표) m_VecTemporayPos.X = Pos().X; m_VecTemporayPos.Y = Pos().Y; //-------------------------------------------- // // sync property with scene node // //-------------------------------------------- if (m_p2DSprite) { m_p2DSprite->setPosition(Pos()); } return this->IsAlived(); }