Skip to content

Instantly share code, notes, and snippets.

@BenDol
Created December 3, 2014 14:25
Show Gist options
  • Save BenDol/a99e6cc4029820f755bb to your computer and use it in GitHub Desktop.
Save BenDol/a99e6cc4029820f755bb to your computer and use it in GitHub Desktop.
onThink Isse
void Npc::onThink(uint32 interval) {
/*Creature::onThink(interval);
if (m_npcEventHandler) {
m_npcEventHandler->onThink();
}*/
std::vector<Player*> list;
Player* player = nullptr;
const SpectatorVec& spectators = g_game.getSpectators(getPosition());
for (SpectatorVec::const_iterator it = spectators.begin(); it != spectators.end(); ++it) {
if ((player = (*it)->getPlayer()) && !player->isRemoved())
list.push_back(player);
}
if(list.size() > 0) { //loop only if there's at least one player
int64 now = OTSYS_TIME();
for(VoiceList::iterator it = voiceList.begin(); it != voiceList.end(); ++it) {
if(now < (lastVoice + it->margin))
continue;
if((uint32)(MAX_RAND_RANGE / it->interval) < (uint32)Tools::random_range(0, MAX_RAND_RANGE))
continue;
player = nullptr;
if(it->randomSpectator) {
size_t random = Tools::random_range(0, (int32)list.size());
if(random < list.size()) //1 slot chance to make it public
player = list[random];
}
doSay(it->text, it->type, player);
lastVoice = now;
break;
}
}
bool idleResponse = false;
if ((uint32)(MAX_RAND_RANGE / idleInterval) >= (uint32)Tools::random_range(0, MAX_RAND_RANGE)) {
idleResponse = true;
}
//if (getTimeSinceLastMove() >= walkTicks) {
// addEventWalk();
//}
isIdle = true;
for(StateList::iterator it = stateList.begin(); it != stateList.end();) {
NpcState* npcState = *it;
const NpcResponse* response = nullptr;
bool closeConversation = false, idleTimeout = false;
Player* player = g_game.getPlayerByCid(npcState->respondToCreature);
if(!npcState->isQueued) {
if(!npcState->prevInteraction)
npcState->prevInteraction = OTSYS_TIME();
if(!queueList.empty() && npcState->isIdle && npcState->respondToText.empty())
closeConversation = true;
else if(idleTime > 0 && (OTSYS_TIME() - npcState->prevInteraction) > (uint64)(idleTime * 1000))
idleTimeout = closeConversation = true;
}
if(idleResponse && player) {
response = getResponse(player, EVENT_IDLE);
executeResponse(player, npcState, response);
idleResponse = false;
}
if(!player || closeConversation) {
if(queueList.empty()) {
if (idleTimeout && player) {
onPlayerLeave(player, npcState);
}
} else {
Player* tmpPlayer = nullptr;
while(!queueList.empty()) {
if((tmpPlayer = g_game.getPlayerByCid(*queueList.begin()))) {
if(NpcState* tmpPlayerState = getState(tmpPlayer, false)) {
tmpPlayerState->respondToText = tmpPlayerState->prevRespondToText;
tmpPlayerState->isQueued = false;
break;
}
}
queueList.erase(queueList.begin());
}
}
delete *it;
it = stateList.erase(it);
continue;
}
if(!npcState->respondToText.empty()) {
if(hasBusyReply && !isIdle) {
//Check if we have a busy reply
if((response = getResponse(player, npcState, EVENT_BUSY)))
executeResponse(player, npcState, response);
} else {
if(npcState->lastResponse) {
//Check previous response chain first
const ResponseList& list = npcState->lastResponse->getResponseList();
response = getResponse(list, player, npcState, npcState->respondToText);
}
if(!response)
response = getResponse(player, npcState, npcState->respondToText);
if(response) {
setCreatureFocus(player);
executeResponse(player, npcState, response);
}
}
npcState->prevRespondToText = npcState->respondToText;
npcState->respondToText = "";
}
response = getResponse(player, npcState, EVENT_THINK);
executeResponse(player, npcState, response);
if(!npcState->isIdle) {
isIdle = false;
if (hasBusyReply) {
setCreatureFocus(player);
}
}
++it;
}
if (isIdle && !hasScriptedFocus) {
setCreatureFocus(nullptr);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment