Graal Forums  

Go Back   Graal Forums > Development Forums > NPC Scripting > Code Gallery
FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 10-19-2011, 06:35 PM
0PiX0 0PiX0 is offline
Coder
0PiX0's Avatar
Join Date: Jan 2011
Posts: 130
0PiX0 is a jewel in the rough0PiX0 is a jewel in the rough
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...

(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(0, this.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.line: temp.lines) {
    if (
temp.line.trim() == "")
      continue;
    
temp.separator = temp.line.substring(0, 1);
    
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] + 2, temp.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(0, temp.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.answer: this.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.nick, int(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!
__________________

Last edited by 0PiX0; 10-19-2011 at 08:06 PM..
Reply With Quote
  #2  
Old 10-19-2011, 07:17 PM
xAndrewx xAndrewx is offline
Registered User
xAndrewx's Avatar
Join Date: Sep 2004
Posts: 5,260
xAndrewx has much to be proud ofxAndrewx has much to be proud ofxAndrewx has much to be proud ofxAndrewx has much to be proud ofxAndrewx has much to be proud ofxAndrewx has much to be proud ofxAndrewx has much to be proud of
cool - is it fun?
__________________
Reply With Quote
  #3  
Old 10-19-2011, 07:18 PM
Emera Emera is offline
Delterian Hybrid
Emera's Avatar
Join Date: Mar 2011
Location: Newcastle Upon-Tyne
Posts: 1,704
Emera is a jewel in the roughEmera is a jewel in the rough
Nicely done ^_^ + Green pepper
__________________
Reply With Quote
  #4  
Old 10-19-2011, 07:19 PM
xXziroXx xXziroXx is offline
Malorian
xXziroXx's Avatar
Join Date: May 2004
Posts: 5,289
xXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant future
Nicely done.
__________________
Follow my work on social media post-Graal:Updated august 2025.
Reply With Quote
  #5  
Old 10-19-2011, 07:35 PM
Tolnaftate2004 Tolnaftate2004 is offline
penguin.
Join Date: Jul 2004
Location: Berkeley, CA
Posts: 534
Tolnaftate2004 is a jewel in the roughTolnaftate2004 is a jewel in the rough
Send a message via AIM to Tolnaftate2004
I'd consider format/2 in place of the various replacetext calls.
__________________
◕‿‿◕ · pfa · check yer syntax! · src

Killa Be: when i got that locker in 6th grade the only thing in it was a picture of a midget useing a firehose :/
Reply With Quote
  #6  
Old 10-19-2011, 08:10 PM
0PiX0 0PiX0 is offline
Coder
0PiX0's Avatar
Join Date: Jan 2011
Posts: 130
0PiX0 is a jewel in the rough0PiX0 is a jewel in the rough
Quote:
Originally Posted by xAndrewx View Post
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 View Post
Nicely done ^_^ + Green pepper
Quote:
Originally Posted by xXziroXx View Post
Nicely done.
Thanks!
Quote:
Originally Posted by Tolnaftate2004 View Post
I'd consider format/2 in place of the various replacetext calls.
Thanks; I updated it.
__________________
Reply With Quote
  #7  
Old 10-20-2011, 11:45 AM
Gunderak Gunderak is offline
Coder
Gunderak's Avatar
Join Date: Jun 2011
Location: Australia
Posts: 795
Gunderak is on a distinguished road
nice.
__________________

Gund for president.

Remote PM {P*}x (Graal813044) from eraiphone -> Stefan: I hav 1 qustion
*Gunderak: he hav 1
*Gunderak: qustion
Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 08:23 AM.


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