Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Plugin para jogar Caça Palavras no Ragnarok
- # by KeplerBR
- package forca;
- use strict;
- use warnings;
- use Plugins;
- use Globals;
- use Skill;
- use Misc qw(look center);
- use Log qw(message);
- use Commands;
- use DBI;
- # Register Plugin and Hooks
- Plugins::register("wordFinder", "Jogo de Caça Palavras no Ragnarok!", \&on_unload);
- my $hooks = Plugins::addHooks(
- ['start3', \&start],
- ['packet/received_sync', \&informPublic],
- ['packet_privMsg', \&informPM],
- ['packet/map_loaded', \&startGame],
- #['packet_pubMsg', \&analyzeResponse],
- );
- my $commandHangmanGame = Commands::register(
- ["inform", "Informa o placar e sobre o atual jogo de caça palavras", \&commandInform]
- );
- # Variáveis globais
- my (@currentsWords, @totalWordListSkill, @wordListSkill, @wordListMonster, @totalWordListMonster, @totalWordListItem, @wordListItem, @scenery, @placePosition, @placeX, @placeY,
- $wordsFound, $totalWords, $tip, $remainingTime, %scoreboard, %nickListTime);
- my @alphabet = ('a' .. 'z'); my $row = 6; my $column = 9; my $inform = 0;
- my $datadir = $Plugins::current_plugin_folder;
- # Database info
- my $hostname= "127.0.0.1";
- my $port = 3306;
- my $user = "ragnarok";
- my $password = "ragnarok";
- my $database = "ragna4fun";
- my $dsn = "DBI:mysql:database=$database;host=$hostname;port=$port;mysql_enable_utf8=1";
- my $dbh = DBI->connect($dsn, $user, $password); # Connect to the database
- ################################
- #On Unload code
- sub on_unload {
- Plugins::delHooks($hooks);
- Commands::unregister($commandHangmanGame);
- }
- ################################
- # Carregar lista de palavras e placar
- sub start {
- # Carregar palavras
- &loadWordList;
- # Carregar placar
- my $sth = $dbh->prepare("SELECT * FROM $config{table}");
- $sth->execute();
- while (my $ref = $sth->fetchrow_hashref()) {
- $scoreboard{$ref->{nick}} = $ref->{points};
- }
- $sth->finish();
- }
- ################################
- # Iniciar partida de Jogo da Forca
- sub startGame {
- return if (@scenery);
- srand;
- look(3, 2);
- $wordsFound = 0;
- # Pegar as palavras aleatorialmente
- if (scalar(@wordListItem) + scalar(@wordListSkill) + scalar(@wordListMonster) < 6) {
- @wordListSkill = @totalWordListSkill;
- @wordListItem = @totalWordListItem;
- @wordListMonster = @totalWordListMonster;
- }
- # TODO: Deixar essa parte mais legível
- $totalWords = int(rand(5));
- my $rand; my $countItem = 0; my $countMonster = 0; my $countSkill = 0;
- for (my $i = 0; $i <= $totalWords; $i++) {
- my $type = int(rand(3));
- if ($type == 2 && @wordListSkill) {
- $rand = int(rand scalar(@wordListSkill));
- $currentsWords[$i] = $wordListSkill[$rand];
- delete $wordListSkill[$rand];
- if ($currentsWords[$i]) {
- $countSkill++;
- } else {
- $i--
- }
- } elsif ($type == 1 && @wordListMonster) {
- $rand = int(rand scalar(@wordListMonster));
- $currentsWords[$i] = $wordListMonster[$rand];
- delete $wordListMonster[$rand];
- if ($currentsWords[$i]) {
- $countMonster++;
- } else {
- $i--
- }
- } elsif (@wordListItem) {
- $rand = int(rand scalar(@wordListItem));
- $currentsWords[$i] = $wordListItem[$rand];
- delete $wordListItem[$rand];
- if ($currentsWords[$i]) {
- $countItem++;
- } else {
- $i--
- }
- }
- }
- # Gerer dica
- message "countItem: $countItem | countSkill: $countSkill | countMonter: $countMonster\n";
- $tip = 'Há ';
- if ($countItem > 1) {
- $tip .= "$countItem itens";
- if ($countSkill && $countMonster) {
- $tip .= ', ';
- } elsif ($countSkill || $countMonster) {
- $tip .= ' e ';
- }
- } elsif ($countItem == 1) {
- $tip .= '1 item';
- if ($countSkill && $countMonster) {
- $tip .= ', ';
- } elsif ($countSkill || $countMonster) {
- $tip .= ' e ';
- }
- }
- if ($countSkill > 1) {
- $tip .= "$countSkill skills ";
- $tip .= 'e ' if ($countMonster);
- } elsif ($countSkill == 1) {
- $tip .= '1 skill ';
- $tip .= 'e ' if ($countMonster);
- }
- if ($countMonster > 1) {
- $tip .= "$countMonster monstros ";
- } elsif ($countMonster == 1) {
- $tip .= "1 monstro ";
- }
- # Criar cenário do caça palavras
- for (my $i = 0; $i <= $totalWords; $i++) {
- positionWord:
- # Randomizar os lugares das palavras
- $placePosition[$i] = int(rand(2)) - 1; # 1 -> Em pé |:| 0 -> Deitado
- my ($coordinatesPossibleX, $coordinatesPossibleY);
- if ($placePosition[$i]) {
- $coordinatesPossibleX = $column - length($currentsWords[$i]);
- $coordinatesPossibleY = $row;
- } else {
- $coordinatesPossibleX = $row - length($currentsWords[$i]);
- $coordinatesPossibleY = $column;
- }
- $placeX[$i] = int(rand($coordinatesPossibleX)); $placeY[$i] = int(rand($coordinatesPossibleY));
- # Verificar se uma palavra não se sobressaindo de outra sem que a letra da interceção seja igual
- if ($i) { # Não precisa analisar caso só tenha no cenário uma única palavra
- for (my $i2 = 0; $i2 <= length($currentsWords[$i]); $i2++) {
- if ($placePosition[$i]) {
- # Em pé
- goto positionWord if ($scenery[$placeX[$i]][$placeY[$i] + $i2] &&
- $scenery[$placeX[$i]][$placeY[$i] + $i2] ne substr($currentsWords[$i], $i2, 1));
- } else {
- # Deitado
- goto positionWord if ($scenery[$placeX[$i] + $i2][$placeY[$i]] &&
- $scenery[$placeX[$i] + $i2][$placeY[$i]] ne substr($currentsWords[$i], $i2, 1));
- }
- }
- }
- # Colocar a palavra no cenário
- for (my $i2 = 0; $i2 <= length($currentsWords[$i]); $i2++) {
- if ($placePosition[$i]) {
- # Em pé
- $scenery[$placeX[$i]][$placeY[$i] + $i2] = substr($currentsWords[$i], $i2, 1);
- } else {
- # Deitado
- $scenery[$placeX[$i] + $i2][$placeY[$i]] = substr($currentsWords[$i], $i2, 1);
- }
- }
- }
- # Os espaços que sobraram serão preenchidos com letras aleatórias
- for (my $X = 0; $X < $row; $X++) {
- for (my $Y = 0; $Y < $column; $Y++) {
- chooseRandomLetter:
- $scenery[$X][$Y] = $alphabet[rand( scalar @alphabet)] if (!$scenery[$X][$Y]);
- # Verificar se irá gerar um falso positivo
- # my $analysisLine = '';
- # for (my $analysisX = 0; $analysisX < $X; $analysisX++) {
- # $analysisLine .= $scenery[$analysisX][$Y];
- # }
- # my $analysisColumn = '';
- # for (my $analysisY = 0; $analysisY < $Y; $analysisY++) {
- # $analysisColumn .= $scenery[$X][$analysisY];
- # }
- # message "ALIASE...\n";
- # while (<@totalWordListSkill>) {
- # next if ($_ ~~ @currentsWords);
- # if (((length($analysisLine) >= length($_)) && $_ =~ /$analysisLine/) || ((length($analysisColumn) >= length($_)) && $_ =~ /$analysisColumn/)) {
- # message "[REPETIDA SKILL] $_ - $analysisLine - $analysisColumn\n";
- # goto chooseRandomLetter;
- # }
- # #goto chooseRandomLetter if ($_ =~ /$analysisLine/ || $_ =~ /analysisColumn/);
- # }
- # while (<@totalWordListItem>) {
- # next if ($_ ~~ @currentsWords);
- # if (((length($analysisLine) >= length($_)) && $_ =~ /$analysisLine/) || ((length($analysisColumn) >= length($_)) && $_ =~ /$analysisColumn/)) {
- # message "[REPETIDA ITEM] $_ - $analysisLine - $analysisColumn\n";
- # goto chooseRandomLetter;
- # }
- # #goto chooseRandomLetter if ($_ =~ /$analysisLine/ || $_ =~ /$analysisColumn/);
- # }
- }
- }
- # Tempo da partida
- $remainingTime = time + ($totalWords + 1) * 20 + 300;
- $taskManager->add(Task::Timeout->new(
- name => 'pluginPalavrasTempoLimite',
- function => sub {
- Commands::run("c Tempo da partida encerrado! As palavras eram: @currentsWords");
- @scenery = (); @currentsWords = (); $inform = 0;
- Plugins::delHook('packet_pubMsg', $hooks);
- sleep 2; # MUDAR PARA TASK DEPOIS!
- &startGame;
- },
- seconds => $remainingTime - time,
- ));
- # Enviar mensagens informando sobre a partida
- message "Palavras: @currentsWords\n", "list";
- &sendScenario;
- Commands::run("e heh") if $config{sendEmoticon};
- $hooks = Plugins::addHooks(
- ['packet_pubMsg', \&analyzeResponse],
- );
- $inform = 0;
- }
- ################################
- # Verificar mensagem pública
- sub analyzeResponse {
- my $hookname = shift;
- my $args = shift;
- # Recolhendo variáveis...
- my $nickPlayer = $args->{pubMsgUser};
- my $chatMessage = lc($args->{Msg});
- my $initialLetter = substr($chatMessage, 0, 1);
- return if (length($chatMessage) == 1);
- for (my $i = 0; $i < length($chatMessage); $i++) {
- return unless (substr($chatMessage, $i, 1) ~~ @alphabet);
- }
- $inform = 0; # Evitar flood
- # Palavras-chaves de comandos
- if ($chatMessage eq "jogo") {
- &sendScenario;
- return;
- }
- # Verificar respostas
- my $answer = -1;
- for (my $i = 0; $i <= $totalWords; $i++) {
- if (lc($currentsWords[$i]) eq lc($chatMessage)) {
- if ($currentsWords[$i] =~ /[A-Z]+/) {
- Commands::run("c A palavra '$chatMessage' já foi encontrada no caça-palavras!");
- Commands::run("e ??") if $config{sendEmoticon};
- return;
- } else {
- $answer = $i;
- last;
- }
- }
- }
- if ($answer == -1) {
- # Errou
- Commands::run("c No Caça Palavras não tem '$chatMessage'!");
- Commands::run("e ??") if $config{sendEmoticon};
- return;
- } else {
- # Acertou
- $wordsFound++;
- # Dando pontos
- my $pointsEarned = 5; # TODO: Precisa mesmo dessa variável??
- &saveScores($nickPlayer, $pointsEarned);
- # Atualizando cenário
- for (my $i = 0; $i < length($currentsWords[$answer]); $i++) {
- if ($placePosition[$answer]) {
- # Em pé
- $scenery[$placeX[$answer]][$placeY[$answer] + $i] = uc($scenery[$placeX[$answer]][$placeY[$answer] + $i]);
- } else {
- # Deitado
- $scenery[$placeX[$answer] + $i][$placeY[$answer]] = uc($scenery[$placeX[$answer] + $i][$placeY[$answer]]);
- }
- $currentsWords[$answer] = uc($currentsWords[$answer]);
- }
- # Informar
- if ($wordsFound != $totalWords + 1) {
- Commands::run("c $nickPlayer, parabéns! Acertou uma palavra! +$pointsEarned pontos! Você tem $scoreboard{$nickPlayer} pontos!");
- $remainingTime += 15;
- &sendScenario;
- } else {
- &sendScenario;
- # Iniciar nova partida, caso todas as palavras tenham sido encontradas
- Commands::run("c $nickPlayer, parabéns! Caça Palavras concluído! +$pointsEarned! Você tem $scoreboard{$nickPlayer} pontos!");
- Plugins::delHook('packet_pubMsg', $hooks);
- @scenery = (); @currentsWords = (); $inform = 0;
- $taskManager->add(Task::Timeout->new(
- name => 'pluginPalavrasRecomeçarPart1',
- function => sub {&startGame;},
- seconds => 5,
- ));
- }
- # Finalizar
- Commands::run("e e11") if $config{sendEmoticon};
- return 1;
- }
- }
- ################################
- # Misc: Salvar pontos dos players
- sub saveScores {
- my ($nickPlayer, $pointsEarned) = @_;
- if (exists $scoreboard{$nickPlayer}) {
- # Atualizar placar
- $scoreboard{$nickPlayer} += $pointsEarned;
- my $sth = $dbh->prepare("UPDATE $config{table} SET points = ? WHERE nick = ?")
- or die "Couldn't prepare statement";
- $sth->execute($scoreboard{$nickPlayer}, $nickPlayer)
- or die "Couldn't execute the query";
- $sth->finish;
- } else {
- # Adicionar player
- $scoreboard{$nickPlayer} = $pointsEarned;
- my $sth = $dbh->prepare("INSERT into $config{table}(nick, points) values(?,?)")
- or die "Couldn't prepare statement";
- $sth->execute($nickPlayer, $scoreboard{$nickPlayer})
- or die "Couldn't execute the query";
- $sth->finish;
- }
- }
- ################################
- # Misc: Carregar lista de palavras
- sub loadWordList {
- my $limit;
- ($row > $column) ? $limit = $column : $limit = $row;
- open my $fileListSkill,"<" . $datadir . '\listSkill.txt' or die $!;
- while (<$fileListSkill>) {
- my $jump = 0;
- my $word = lc($_);
- $word =~ s/\R//g;
- next if (length($word) >= $limit);
- for (my $i = 0; $i < length($word); $i++) {
- unless (substr($word, $i, 1) ~~ @alphabet) {
- $jump = 1;
- last;
- }
- }
- push (@totalWordListSkill, $word) if (!$jump);
- }
- close $fileListSkill;
- open my $fileListMonster,"<" . $datadir . '\listMonster.txt' or die $!;
- while (<$fileListMonster>) {
- my $jump = 0;
- my $word = lc($_);
- $word =~ s/\R//g;
- next if (length($word) >= $limit);
- for (my $i = 0; $i < length($word); $i++) {
- unless (substr($word, $i, 1) ~~ @alphabet) {
- $jump = 1;
- last;
- }
- }
- push (@totalWordListMonster, $word) if (!$jump);
- }
- close $fileListMonster;
- for (keys %items_lut) {
- my $jump = 0;
- my $word = lc($items_lut{$_});
- next if (length($word) >= $limit);
- for (my $i = 0; $i < length($word); $i++) {
- unless (substr($word, $i, 1) ~~ @alphabet) {
- $jump = 1;
- last;
- }
- }
- push (@totalWordListItem, $word) if (!$jump);
- }
- @wordListSkill = @totalWordListSkill;
- @wordListMonster = @totalWordListMonster;
- @wordListItem = @totalWordListItem;
- }
- ################################
- # Misc: Enviar cenário
- sub sendScenario {
- my $messageRemainingTime = $remainingTime - time;
- Commands::run("c § ################################ Caça Palavras:");
- if (($totalWords + 1 - $wordsFound) > 1) {
- Commands::run("c § #### Essa partida irá durar mais $messageRemainingTime segundos!");
- Commands::run("c § #### Faltam " . scalar($totalWords + 1 - $wordsFound) . " palavras! $tip");
- } elsif (($totalWords + 1 - $wordsFound) == 1) {
- Commands::run("c § #### Essa partida irá durar mais $messageRemainingTime segundos!\"");
- Commands::run("c § #### Caça Palavras: Falta " . scalar($totalWords + 1 - $wordsFound) . " palavra! $tip");
- } else {
- Commands::run("c § #### Concluído enquanto restava mais $messageRemainingTime segundos!! Parabéns!!!");
- }
- my %spacing = (
- 'a' => ' ',
- 'b' => ' ',
- 'c' => ' ',
- 'd' => ' ',
- 'e' => ' ',
- 'f' => ' ',
- 'g' => ' ',
- 'h' => ' ',
- 'i' => ' ',
- 'j' => ' ',
- 'k' => ' ',
- 'l' => ' ',
- 'm' => ' ',
- 'n' => ' ',
- 'o' => ' ',
- 'p' => ' ',
- 'q' => ' ',
- 'r' => ' ',
- 's' => ' ',
- 't' => ' ',
- 'u' => ' ',
- 'v' => ' ',
- 'x' => ' ',
- 'w' => ' ',
- 'y' => ' ',
- 'z' => ' ',
- 'A' => ' ',
- 'B' => ' ',
- 'C' => ' ',
- 'D' => ' ',
- 'E' => ' ',
- 'F' => ' ',
- 'G' => ' ',
- 'H' => ' ',
- 'I' => ' ',
- 'J' => ' ',
- 'K' => ' ',
- 'L' => ' ',
- 'M' => ' ',
- 'N' => ' ',
- 'O' => ' ',
- 'P' => ' ',
- 'Q' => ' ',
- 'R' => ' ',
- 'S' => ' ',
- 'T' => ' ',
- 'U' => ' ',
- 'V' => ' ',
- 'X' => ' ',
- 'W' => ' ',
- 'Y' => ' ',
- 'Z' => ' ',
- );
- for (my $X = 0; $X < $row; $X++) {
- my $message = '';
- for (my $Y = 0; $Y < $column; $Y++) {
- $message .= $scenery[$X][$Y] . $spacing{$scenery[$X][$Y]} . '|';
- }
- Commands::run("c $message");
- }
- }
- ################################
- # Informar que esta tendo Jogo da Forca
- sub informPublic {
- $inform++;
- if ($inform == 4) { # Evitar flood
- Commands::run("c Jogue Caça Palavras do Ragnarok! Cada acerto vale 5 ponto!");
- Commands::run("c Para ver o placar e como participar, basta me enviar PM!");
- &sendScenario;
- $inform = 0;
- }
- }
- ################################
- # Ao receber uma PM, irá da umas infos
- sub informPM {
- my $hookname = shift;
- my $args = shift;
- my $nick = $args->{privMsgUser};
- my $message = $args->{privMsg};
- # Anti-Spam
- if ((time - $nickListTime{$nick}) < 10) {
- Commands::run("pm \"$nick\" Desculpe-me, você mandou PM a pouco tempo! Tente daqui a 10s!");
- return;
- }
- $nickListTime{$nick} = time;
- # Analisando PM
- if ($message =~ /placar completo/i) {
- my $i = 0;
- for ( sort {$scoreboard{$b} <=> $scoreboard{$a}} keys %scoreboard) {
- $i++;
- last if (!$_);
- Commands::run("pm \"$nick\" * $i° - $_ - $scoreboard{$_} pontos");
- last if ($i == 100);
- }
- } elsif ($message =~ /comentário:/i || $message =~ /comentario:/i) {
- # Anti-flood
- my $sth = $dbh->prepare("SELECT * FROM palavras_comment WHERE nick = ?")
- or die "Couldn't prepare statement";
- $sth->execute($nick)
- or die "Couldn't execute the query";
- $sth->finish;
- if ($sth->rows < 2) {
- $message =~ s/comentário://i;
- my $sth = $dbh->prepare("INSERT into palavras_comment(server, nick, comment) value(?,?,?)")
- or die "Couldn't prepare statement";
- $sth->execute($config{master}, $nick, $message)
- or die "Couldn't execute the query";
- $sth->finish;
- Commands::run("pm \"$nick\" Obrigado, $nick! Seu comentário foi enviado com sucesso! Irei lê-lo depois.");
- } else {
- Commands::run("pm \"$nick\" Desculpe, $nick, mas não é possível enviar mais que 2 comentários por personagem...");
- }
- } elsif ($scoreboard{$message}) {
- my $i = 0;
- for (sort {$scoreboard{$b} <=> $scoreboard{$a}} keys %scoreboard) {
- $i++;
- last if ($_ eq $message);
- }
- Commands::run("pm \"$nick\" $message tem $scoreboard{$message} pontos e esta em $i° lugar!");
- } else {
- Commands::run("pm \"$nick\" Para participar do Caça Palavras, basta você buscar e dizer a(s) palavras escondidas!");
- Commands::run("pm \"$nick\" ENVIE A MENSAGEM PELO CHAT PÚBLICO, não por PM!! Envie pelo chat pública!!");
- Commands::run("pm \"$nick\" Cada partida tem um tempo para terminar! Cada acerto aumenta em +15s o tempo");
- Commands::run("pm \"$nick\" -------------------");
- Commands::run("pm \"$nick\" Dica: Envie, pelo chat público (NÃO por PM):");
- Commands::run("pm \"$nick\" * 'jogo' -> para exibir o cenário onde estão as palavras que devem ser achadas");
- Commands::run("pm \"$nick\" -------------------");
- Commands::run("pm \"$nick\" Placar dos 15 primeiros lugares:");
- my $i = 0;
- for ( sort {$scoreboard{$b} <=> $scoreboard{$a}} keys %scoreboard) {
- $i++;
- last if (!$_);
- Commands::run("pm \"$nick\" * $i° - $_ - $scoreboard{$_} pontos");
- last if ($i == 15);
- }
- Commands::run("pm \"$nick\" Total de jogadores: " . scalar (keys %scoreboard));
- Commands::run("pm \"$nick\" -------------------");
- Commands::run("pm \"$nick\" Se quiser me enviar um comentário, mande PM com o texto e escrito 'Comentário:'");
- Commands::run("pm \"$nick\" Exemplo: 'Comentário: O jogo caça palavras é muito legal =)'");
- Commands::run("pm \"$nick\" -------------------");
- Commands::run("pm \"$nick\" Para visualizar a pontuação específica de um jogador, envie, por PM, o nick dele");
- Commands::run("pm \"$nick\" Para visualizar os 100 primeiros lugares, envie, por PM, 'placar completo'!");
- }
- }
- ################################
- # Função do comando "inform"
- sub commandInform {
- my $message;
- $message = center('Placar atual', 50, '-') . "\n";
- my $i = 0;
- for ( sort {$scoreboard{$b} <=> $scoreboard{$a}} keys %scoreboard) {
- $i++;
- $message .= "* $i° - $_ - $scoreboard{$_} pontos\n";
- last if ($i == 50);
- }
- $message .= "Total: " . scalar (keys %scoreboard) . "\n";
- $message .= center('Informações do Caça Palavras', 50, '-') . "\n";
- $message .= "Dica: $tip\n";
- $message .= "Palavras escondidas: @currentsWords\n";
- my $messageRemainingTime = $remainingTime - time;
- $message .= "Tempo restante: $messageRemainingTime\n";
- $message .= "Cenário: \n";
- for (my $X = 0; $X < $row; $X++) {
- my $messageScenery = '';
- for (my $Y = 0; $Y < $column; $Y++) {
- $messageScenery .= $scenery[$X][$Y] . ' ';
- }
- $message .= $messageScenery . "\n";
- }
- message $message, "list";
- }
- 1;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement