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(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!
__________________

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
Master of Puppets
xXziroXx's Avatar
Join Date: May 2004
Location: Sweden
Posts: 5,288
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
Send a message via AIM to xXziroXx Send a message via MSN to xXziroXx
Nicely done.
__________________

"A delayed game is eventually good, but a rushed game is forever bad." - Shigeru Miyamoto
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 01:54 AM.


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