Graal Forums

Graal Forums (https://forums.graalonline.com/forums/index.php)
-   Code Gallery (https://forums.graalonline.com/forums/forumdisplay.php?f=179)
-   -   NPC Trivia Host Bot (https://forums.graalonline.com/forums/showthread.php?t=134264831)

0PiX0 10-19-2011 06:35 PM

NPC Trivia Host Bot
 
Trivia files are text files which use the same format as HamFon's Trivia Bot. Each line of the file is defined as follows.
  • The first character of the line defines what the line's separator is.
  • The first token of the line is the category.
  • The second token is the best answer.
  • The remaining tokens until the first double separator, are other possible answers.
  • Between the first double separator and either the end of the line or the second double separator, is the question.
  • Remaining tokens separated by any separators are extra parameters, which are not used as of yet.
For example, all of the following lines are valid.
NPC Code:
/Sports&Leisure/Indianapolis Motor Speedway/Indianapolis/Indy//Where is Gasoline Alley?
/GraalOnline/Classic iPhone/Classic//What was the first successful iPhone Graal server?//parameters/that/are/not/used/(yet)
\Graal\graalonline.com/downloads\\Where can you download the GraalOnline client?


Some example trivia files are available here.

All trivia text files should be placed in trivia/ .
The (npcserver) requires read rights to the trivia files.
r trivia/*

By default, chat commands are:
!trivia [rounds] (staff rights required)
!stoptrivia - stop the trivia (staff rights required)
!leader - who is winning the current game
!points - how many points you have this game
!correct - how many correct answers you have this game

To join a game, or answer a question, you just say an answer. If it is a correct answer, you should see something like this...
http://img197.imageshack.us/img197/9...efantrivia.png
(trivia Stefan ftw?)

Note that answers are not case or context sensitive. If an answer is Billie Jean, and someone says "It might be billie jean, but idk!", that would be considered a correct answer.

npc script:
PHP Code:

function onCreated() {
  
join("trivia");
  
loadTriviaFile("your_trivia_file.txt"); // located at trivia/your_trivia_file.txt
  
showcharacter();
  
this.head "head19.png";
  
this.body "body2.png";
  
this.dir 2;
  
this.colors[0] = "orange";
  
this.colors[1] = "darkgreen";
  
this.colors[2] = "brown";
  
this.colors[3] = "red";
  
this.colors[4] = "green";


class "trivia":
PHP Code:

const DEFAULT_ROUNDS 10;
const 
START_MESSAGE "Starting %1$s rounds of trivia! Get ready!";
const 
STOP_MESSAGE "Stopping the trivia.";
const 
CATEGORY_MESSAGE "The next question is categorized as '%1$s'.";
const 
CORRECT_ANSWER_MESSAGE "The first correct answer was given by '%1$s'! (%2$s seconds)";
const 
NO_CORRECT_ANSWER_MESSAGE "Nobody was able to give a correct answer!";
const 
CORRECT_MESSAGE "The correct answer was '%1$s'.";
const 
LEADER_MESSAGE "Currently, '%1$s' is in the lead, with %2$s points!";
const 
ROUNDS_REMAINING_MESSAGE "There are %1$s rounds remaining in this trivia game.";
const 
WINNER_MESSAGE "This trivia game's winner is '%1$s'!";
const 
MESSAGE_TIMEOUT 5;
const 
TRIVIA_TIMEOUT 30;
const 
TRIVIA_POINTS 50;

/**
 events
 */
function onCreated() {
  
stopTrivia();
}

function 
onPlayerChats() {
  
temp.tokens player.chat.tokenize();
  switch (
temp.tokens[0].lower()) {
    case 
"!trivia":
      if (
player.communityname in serveroptions.staff.tokenize(","))
        
startTrivia(temp.tokens[1]);
      break;
    case 
"!stoptrivia":
      if (
player.communityname in serveroptions.staff.tokenize(","))
        
stopTrivia();
      break;
    case 
"!leader":
      
player.chat getLeaderNick();
      break;
    case 
"!points":
      
player.chat this.triviaPlayers.(@player.account).points;
      break;
    case 
"!correct":
      
player.chat this.triviaPlayers.(@player.account).correctAnswers;
      break;
    default:
      if (
this.roundStarted)
        
triviaAnswer();
      break;
  }
}

function 
onRoundStart() {
  
this.triviaIndex int(random(0this.trivia.size()));
  
this.chat format2(CATEGORY_MESSAGE, {this.trivia[this.triviaIndex].category});
  
scheduleevent(MESSAGE_TIMEOUT"onAskQuestion"NULL);
}

function 
onAskQuestion() {
  
this.chat this.trivia[this.triviaIndex].question;
  
this.questionTime timevar2;
  
scheduleevent(TRIVIA_TIMEOUT"onTriviaTimeout"NULL);
  
this.roundStarted true;
}

function 
onTriviaTimeout() {
  
this.roundStarted false;
  
this.chat NO_CORRECT_ANSWER_MESSAGE;
  
scheduleevent(MESSAGE_TIMEOUT"onAnnounceAnswer"NULL);
}

function 
onAnnounceAnswer() {
  
this.chat format2(CORRECT_MESSAGE, {this.trivia[this.triviaIndex].answers[0]});
  
scheduleevent(MESSAGE_TIMEOUT"onAnnounceLeader"NULL);
}

function 
onAnnounceLeader() {
  if (
this.leaderAccount != NULL)
    
this.chat format2(LEADER_MESSAGE, {getLeaderNick(), this.triviaPlayers.(@this.leaderAccount).points});
  
scheduleevent(MESSAGE_TIMEOUT"onRoundEnd"NULL);
}

function 
onRoundEnd() {
  if (--
this.rounds 0) {
    
this.chat format2(ROUNDS_REMAINING_MESSAGE, {this.rounds});
    
scheduleevent(MESSAGE_TIMEOUT"onRoundStart"NULL);
  } else {
    if (
this.leaderAccount == NULL) {
      
stopTrivia();
    } else {
      
this.chat format2(WINNER_MESSAGE, {getLeaderNick()});
      
scheduleevent(MESSAGE_TIMEOUT"onStopTrivia"NULL);
    }
  }
}

function 
onClearChat() {
  
this.chat "";
}

function 
onStopTrivia() {
  
stopTrivia();
}

/**
 functions
 */
function loadTriviaFile(temp.s) {
  
this.trivia "";
  
temp.lines.loadlines("trivia/" temp.s);
  for (
temp.linetemp.lines) {
    if (
temp.line.trim() == "")
      continue;
    
temp.separator temp.line.substring(01);
    
temp.sepPositions temp.line.positions(temp.separator temp.separator);
    
temp.obj = new TStaticVar();
    if (
temp.sepPositions.size() > 1) {
      
temp.obj.question temp.line.substring(temp.sepPositions[0] + 2temp.sepPositions[1]);
      
temp.obj.params temp.line.substring(temp.sepPositions[1] + 2).tokenize(temp.separator);
    } else {
      
temp.obj.question temp.line.substring(temp.sepPositions[0] + 2);
    }
    
temp.tokens temp.line.substring(0temp.sepPositions[0]).tokenize(temp.separator);
    
temp.obj.category temp.tokens[0];
    
temp.obj.answers temp.tokens.subarray(1);
    
this.trivia.add(temp.obj);
  }
  if (
this.trivia.size() == 0) {
    
this.chat "Unable to load trivia data. Make sure the specified file exists, and is a valid trivia text file.";
    
this.triviaLoaded false;
  } else {
    
this.chat "Trivia loaded!";
    
this.triviaLoaded true;
  }
}

function 
startTrivia(temp.rounds) {
  if (
this.triviaStarted)
    
stopTrivia();
  if (!
this.triviaLoaded)
    return;
  if (
temp.rounds <= 0)
    
temp.rounds DEFAULT_ROUNDS;
  
this.rounds temp.rounds;
  
cancelevents("onClearChat");
  
this.chat format2(START_MESSAGE, {temp.rounds});
  if (
this.triviaPlayers != NULL)
    
this.triviaPlayers.destroy();
  
this.triviaPlayers = new TStaticVar();
  
this.leaderAccount "";
  
scheduleevent(5"onRoundStart"NULL);
  
this.triviaStarted true;
}

function 
stopTrivia() {
  if (
this.triviaStarted)
    
this.chat STOP_MESSAGE;
  
scheduleevent(MESSAGE_TIMEOUT"onClearChat"NULL);
  
cancelevents("onTriviaUpdate");
  
cancelevents("onRoundStart");
  
cancelevents("onAskQuestion");
  
cancelevents("onTriviaTimeout");
  
cancelevents("onAnnounceAnswer");
  
cancelevents("onAnnounceLeader");
  
cancelevents("onRoundEnd");
  
cancelevents("onStopTrivia");
  
this.triviaStarted false;
}

function 
triviaAnswer() {
  if (
this.triviaPlayers.(@player.account) == NULL)
    
this.triviaPlayers.(@player.account) = new TStaticVar();
  for (
temp.answerthis.trivia[this.triviaIndex].answers) {
    if (
player.chat.lower().pos(temp.answer.lower()) == -1)
      continue;
    
this.roundStarted false;
    
this.triviaPlayers.(@player.account).correctAnswers++;
    
this.triviaPlayers.(@player.account).points += TRIVIA_POINTS;
    
this.chat format2(CORRECT_ANSWER_MESSAGE, {player.nickint(timevar2 this.questionTime)});
    if (
this.triviaPlayers.(@player.account).points this.triviaPlayers.(@this.leaderAccount).points)
      
this.leaderAccount player.account;
    
cancelevents("onTriviaTimeout");
    
scheduleevent(MESSAGE_TIMEOUT"onAnnounceAnswer"NULL);
    return;
  }
}

function 
getLeaderNick() {
  
temp.pl findplayer(this.leaderAccount);
  if (
temp.pl == NULL)
    
temp.pl = new TServerPlayer(@this.leaderAccount);
  
temp.leaderNick temp.pl.nick;
  
temp.pl.destroy();
  return 
temp.leaderNick;


Please report any bugs you find, and comment with any ideas you have, so I can improve it for anyone that might use this.

Enjoy! ^^

xAndrewx 10-19-2011 07:17 PM

cool - is it fun?

Emera 10-19-2011 07:18 PM

Nicely done ^_^ + Green pepper

xXziroXx 10-19-2011 07:19 PM

Nicely done.

Tolnaftate2004 10-19-2011 07:35 PM

I'd consider format/2 in place of the various replacetext calls.

0PiX0 10-19-2011 08:10 PM

Quote:

Originally Posted by xAndrewx (Post 1671270)
cool - is it fun?

I hope so! :0 It would be neat to see some server-specific trivia, or trivia about GraalOnline altogether.
Quote:

Originally Posted by Emera (Post 1671271)
Nicely done ^_^ + Green pepper

Quote:

Originally Posted by xXziroXx (Post 1671272)
Nicely done.

Thanks!
Quote:

Originally Posted by Tolnaftate2004 (Post 1671273)
I'd consider format/2 in place of the various replacetext calls.

Thanks; I updated it. :)

Gunderak 10-20-2011 11:45 AM

nice.


All times are GMT +2. The time now is 01:24 PM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2026, vBulletin Solutions Inc.
Copyright (C) 1998-2019 Toonslab All Rights Reserved.