Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Plugin para jogar Jogo da Forca 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("forca", "Jogo da Forca 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 da forca", \&commandInform]
- );
- # Variáveis globais
- my ($currentTip, $currentWord, @currentWordHidden, @lettersUsed, @wordListUsed);
- my $type = 2;
- my $inform = 0;
- my $delayPlacar = 0;
- my $datadir = $Plugins::current_plugin_folder;
- my (%scoreboard, %listSkills, %listSkillsHandle, %listItems, %listMonster, %nickListTime);
- my @alphabet = ('a' .. 'z', 'á', 'é', 'í', 'ó', 'ú', 'â', 'ê', 'î', 'ô', 'û', 'à', 'è', 'ì', 'ò', 'ù', 'ã', 'õ', 'ç');
- # 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
- %listSkills = reverse %Skill::StaticInfo::names;
- %listSkillsHandle = reverse %Skill::StaticInfo::handles;
- for (keys %items_lut) {
- $items_lut{$_} = lc($items_lut{$_});
- }
- %listItems = reverse %items_lut;
- open my $fileListMonster,"<" . $datadir . '\listMonsterSpecial.txt' or die $!;
- while (<$fileListMonster>) {
- my $line = $_;
- $line =~ s/\R//g;
- $line =~ /(.*)\t(\d*)\t(.*)\t(.*)\t(\d*)\t(\d*)\t(\d*)\t(\d*)/;
- $listMonster{$1}{name} = $1; $listMonster{$1}{lvl} = $2; $listMonster{$1}{size} = $3;
- $listMonster{$1}{race} = $4; $listMonster{$1}{drop1} = $5; $listMonster{$1}{drop2} = $6;
- $listMonster{$1}{drop3} = $7; $listMonster{$1}{drop4} = $8;
- }
- close $fileListMonster;
- # 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 {
- look(3, 2);
- # Anti-bug
- return 0 if ($currentWord);
- return 0 if ($taskManager->countTasksByName('pluginForcaRecomeçarPart2'));
- # Pegar uma palavra aleatóriamente
- my $attempts = 0;
- chooseWord:
- $type++;
- $type = 0 if ($type > 2);
- if ($type == 2) {
- $currentWord = lc($items_lut{(keys %items_lut)[rand keys %items_lut]});
- } elsif ($type == 1) {
- $currentWord = lc($listSkills{(keys %listSkills)[rand keys %listSkills]});
- } else {
- $currentWord = $listMonster{(keys %listMonster)[rand keys %listMonster]}{name};
- }
- $attempts++;
- # Caso tenha repetido o loop muitas vezes, é provável que já usou todas as palavras possíveis
- @wordListUsed = () if ($attempts > 100);
- message "$currentWord\n";
- goto chooseWord if ($currentWord ~~ @wordListUsed); # Palavra repetida
- push (@wordListUsed, $currentWord);
- # Gerar palavra oculta
- @currentWordHidden = ();
- for (my $i = 0; $i < length($currentWord); $i++) {
- my $key = substr($currentWord, $i, 1);
- if ($key ~~ @alphabet) {
- (substr($currentWord, $i + 1, 1) ~~ @alphabet) ?
- push (@currentWordHidden, '_ ') :
- push (@currentWordHidden, '_');
- } else {
- ($key eq ' ') ?
- push (@currentWordHidden, ' ') :
- push (@currentWordHidden, $key);
- }
- }
- my $count = 0;
- for (my $i = 0; $i <= @currentWordHidden; $i++) {
- $count += length($currentWordHidden[$i]);
- }
- goto chooseWord if ($count + 60 > $config{message_length_max}); # Evitar palavras muito grande que possam quebrar as mensagens em duas
- # Gerar a dica
- $currentTip = '';
- if ($type == 2) {
- my $descItem = $itemsDesc_lut{$listItems{$currentWord}} || 0;
- if ($descItem) {
- message "-> $currentWord\n\n$descItem\n", "list";
- my @num = (0..5);
- while (!$currentTip) {
- my $typeTip = $num[(rand @num)];
- if ($typeTip == 0) {
- $descItem =~ /Tipo: (.+)/i;
- $currentTip = "Item do tipo '$1'" if ($1);
- } elsif ($typeTip == 1) {
- $descItem =~ /Equipa em: (.+)/i;
- $currentTip = "Item que equipa em '$1'" if ($1);
- } elsif ($typeTip == 2) {
- $descItem =~ /Classes que utilizam: (.+?)\./;
- $currentTip = "Item que podem equipar '$1'" if (length($1) < 70 && $1);
- } elsif ($typeTip == 3) {
- $descItem =~ /(.+?)\./i;
- $currentTip = $1 if ($1 && length($1) + length($currentWord) < $config{message_length_max} && !($1 =~ /$currentWord/i));
- } elsif ($typeTip == 4) {
- $descItem =~ /Nível da Arma: (.+?)/i;
- $currentTip = "Equipamento de nível '$1'" if ($1);
- } else {
- $descItem =~ /Nível necess?rio: (.+?)/i;
- $currentTip = "Equipamento que requer nível '$1'" if ($1);
- }
- # Apagar valor do $num que foi usado
- @num = grep($_ != $typeTip, @num);
- if (!@num) {
- $descItem =~ /Peso: (.+)/i;
- if ($1) {
- $currentTip = "Item que pesa '$1'" if ($1);
- } else {
- $currentTip = 'Um item!'
- }
- }
- }
- } else {
- $currentTip = 'Um item';
- }
- } elsif ($type == 1) {
- my $descSkill = $skillsDesc_lut{$listSkillsHandle{$Skill::StaticInfo::names{$currentWord}}} || 0;
- if ($descSkill) {
- message "-> $currentWord\n\n$descSkill\n", "list";
- my @num = (0..2);
- while (!$currentTip) {
- my $typeTip = $num[(rand @num)];
- if ($typeTip == 0) {
- $descSkill =~ /(?:Tipo|Forma de Habilidade)\s*:\s* (.+)/i;
- $currentTip = "Habilidade do tipo '$1'" if ($1);
- } elsif ($typeTip == 1) {
- $descSkill =~ /Alvo\s*:\s* (.+)/i;
- $currentTip = "Habilidade que o alvo é '$1'" if ($1);
- } else {
- $descSkill =~ /(?:Resultado|Descrição|Content|Conteúdo)\s*:\s* (.+)(?:\.|)/i;
- $currentTip = $1 if ($1 && length($1) + length($currentWord) < $config{message_length_max});
- }
- # Apagar valor do $num que foi usado usado
- @num = grep($_ != $typeTip, @num);
- $currentTip = 'Uma habilidade!' if (!@num);
- }
- } else {
- $currentTip = 'Uma habilidade';
- }
- } else {
- message "->$currentWord\n\n$listMonster{$currentWord}{lvl} $listMonster{$currentWord}{size} $listMonster{$currentWord}{race}\n", "list";
- my $typeTip = int(rand(4)) - 1;
- if ($typeTip == 3) {
- $currentTip = "Monstro de nível '$listMonster{$currentWord}{lvl}'";
- } elsif ($typeTip == 2) {
- $currentTip = "Monstro de tamanho '$listMonster{$currentWord}{size}'";
- } elsif ($typeTip == 1) {
- $currentTip = "Monstro da raça '$listMonster{$currentWord}{race}'";
- } else {
- my $randDrop = 0;
- $randDrop++ if ($items_lut{$listMonster{$currentWord}{drop1}});
- $randDrop++ if ($items_lut{$listMonster{$currentWord}{drop2}});
- $randDrop++ if ($items_lut{$listMonster{$currentWord}{drop3}});
- $randDrop++ if ($items_lut{$listMonster{$currentWord}{drop4}});
- message "randDrop: $randDrop\n";
- $randDrop = int(rand($randDrop));
- if ($randDrop == 1) {
- $currentTip = "Monstro que dropa '" . $items_lut{$listMonster{$currentWord}{drop1}} . "'";
- } elsif ($randDrop == 2) {
- $currentTip = "Monstro que dropa '" . $items_lut{$listMonster{$currentWord}{drop2}} . "'";
- } elsif ($randDrop == 3) {
- $currentTip = "Monstro que dropa '" . $items_lut{$listMonster{$currentWord}{drop3}} . "'";
- } elsif ($randDrop == 4) {
- $currentTip = "Monstro que dropa '" . $items_lut{$listMonster{$currentWord}{drop4}} . "'";
- } else {
- $currentTip = "Monstro de nível '$listMonster{$currentWord}{lvl}'";
- }
- }
- }
- # Enviar mensagens informando
- Commands::run("c Dica: $currentTip!");
- Commands::run("e heh") if $config{sendEmoticon};
- $taskManager->add(Task::Timeout->new(
- name => 'pluginForcaRecomeçarPart2',
- inGame => 1,
- function => sub {
- Commands::run("c Palavra atual: @currentWordHidden");
- @lettersUsed = ();
- $hooks = Plugins::addHooks(
- ['packet_pubMsg', \&analyzeResponse],
- );
- },
- seconds => 2,
- ));
- $inform = 0;
- }
- ################################
- # Verificar mensagem pública
- sub analyzeResponse {
- my $hookname = shift;
- my $args = shift;
- return 0 if (!$currentWord);
- # Recolhendo variáveis...
- my $nickPlayer = $args->{pubMsgUser};
- my $chatMessage = lc($args->{Msg});
- my $initialLetter = substr($chatMessage, 0, 1);
- return 0 if !($initialLetter ~~ @alphabet);
- # Palavras-chaves de comandos
- if ($chatMessage eq "dica") {
- Commands::run("c Dica: $currentTip!");
- return 0;
- } elsif ($chatMessage eq "palavra") {
- Commands::run("c Palavra: @currentWordHidden");
- return 0;
- }
- # Verificar respostas
- if (length($chatMessage) != 1 &&
- ((length($chatMessage) + 2) < length($currentWord)) ||
- (length($currentWord) < (length($chatMessage) - 2))) {
- # Ignorar mensagens com tamanho muito diferente da palavra secreta
- return 0;
- } elsif (length($chatMessage) > 1 && $chatMessage ne $currentWord) {
- # Errou a palavra
- if (27 + length($chatMessage) + length($currentTip) >= $config{message_length_max}) {
- Commands::run("c A palavra não é '$chatMessage'!");
- } else {
- Commands::run("c A palavra não é '$chatMessage'! Dica: $currentTip");
- }
- Commands::run("e ??") if $config{sendEmoticon};
- return 0;
- } elsif ($chatMessage eq $currentWord) {
- # Acertou palavra inteira
- # Calcular pontos ganhos e amarzena-lo
- my $hiddenLetters = 0;
- for (@currentWordHidden) {
- $hiddenLetters++ if ($_ eq '_ ' || $_ eq '_');
- }
- my $pointsEarned = 5 + int($hiddenLetters/2);
- &saveScores($nickPlayer, $pointsEarned);
- # Informar
- Commands::run("c $nickPlayer, parabéns! Acertou a palavra! +$pointsEarned pontos! Você tem $scoreboard{$nickPlayer} pontos!");
- Commands::run("e e11") if $config{sendEmoticon};
- # Iniciar nova partida
- undef $currentWord;
- Plugins::delHook('packet_pubMsg', $hooks);
- unless ($taskManager->countTasksByName('pluginForcaRecomeçarPart1')) {
- $taskManager->add(Task::Timeout->new(
- name => 'pluginForcaRecomeçarPart1',
- inGame => 1,
- function => sub {&startGame;},
- seconds => 5,
- ));
- }
- $inform = 0;
- return 1;
- }
- # Verificar se esta repetindo letra
- my $contidion = $initialLetter;
- $contidion = "/|ã|á|à|â|a|/" if ($initialLetter eq 'a'); $contidion = "/|é|è|ê|e|/" if ($initialLetter eq 'e');
- $contidion = "/|í|ì|î|i|/" if ($initialLetter eq 'i'); $contidion = "/|õ|ó|ò|ô|o|/" if ($initialLetter eq 'o');
- $contidion = "/|ú|ù|u|/" if ($initialLetter eq 'u');
- my $i = 0;
- my $repeatingLetter = 0;
- for (@lettersUsed) {
- if ($contidion =~ $lettersUsed[$i]) {
- $repeatingLetter = 1;
- last;
- }
- $i++;
- }
- if ($repeatingLetter) {
- # Esta repetindo letra
- exists $scoreboard{$nickPlayer} ?
- Commands::run("c $nickPlayer, '$initialLetter' já foi usado! (Você tem $scoreboard{$nickPlayer} ponto(s))") :
- Commands::run("c $nickPlayer, '$initialLetter' já foi usado! (Para ver o placar, basta me mandar PM!)");
- Commands::run("e !") if $config{sendEmoticon};
- $inform = 0;
- return 0;
- } else {
- # Não esta repetindo letra
- push (@lettersUsed, $initialLetter);
- }
- # Verificar se acertou alguma letra
- my $pointsEarned = 0;
- for (my $i = 0; $i < length($currentWord); $i++) {
- my $letter = substr($currentWord, $i, 1);
- if ($letter ~~ @alphabet) {
- if ($contidion =~ $letter) {
- $pointsEarned++;
- $currentWordHidden[$i] = substr($currentWord, $i, 1);
- }
- }
- }
- if ($pointsEarned) {
- # Acertou uma letra ou mais
- # Salvar pontos ganhos
- &saveScores($nickPlayer, $pointsEarned);
- # Verificar se completou a palavra
- my $incompleteWord = 0;
- for (@currentWordHidden) {
- $incompleteWord = 1 if ($_ eq '_ ' || $_ eq '_');
- }
- if ($incompleteWord) {
- Commands::run("c Certo, $nickPlayer! +$pointsEarned! Palavra esta: @currentWordHidden");
- Commands::run("e ok") if $config{sendEmoticon};
- } else {
- Commands::run("c Certo, $nickPlayer! +$pointsEarned! Palavra concluída: @currentWordHidden");
- Commands::run("e ok") if $config{sendEmoticon};
- # Iniciar nova partida
- undef $currentWord;
- Plugins::delHook('packet_pubMsg', $hooks);
- unless ($taskManager->countTasksByName('pluginForcaRecomeçarPart1')) {
- $taskManager->add(Task::Timeout->new(
- name => 'pluginForcaRecomeçarPart1',
- inGame => 1,
- function => sub {&startGame;},
- seconds => 5,
- ));
- }
- }
- } else {
- # Não acertou
- exists $scoreboard{$nickPlayer} ?
- Commands::run("c $nickPlayer, '$initialLetter' não consta no nome! (Você tem $scoreboard{$nickPlayer} ponto(s))") :
- Commands::run("c $nickPlayer, '$initialLetter' não consta no nome! (Para ver o placar, basta me mandar PM!)");
- Commands::run("e ??") if $config{sendEmoticon};
- }
- # Finalizar
- $inform = 0; # Evitar flood
- }
- ################################
- # 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;
- }
- }
- ################################
- # Informar que esta tendo Jogo da Forca
- sub informPublic {
- $inform++;
- if ($inform == 3) { # Evitar flood
- my $count = 0;
- for (my $i = 0; $i <= @currentWordHidden; $i++) {
- $count += length($currentWordHidden[$i]);
- }
- Commands::run("c Jogue Jogo da Forca! Cada letra vale 1 ponto; acertar a palavra valem 5 ou mais!");
- Commands::run("c Para ver o placar e como participar, basta me enviar PM!");
- if (length($currentTip) + $count + 22 > $config{message_length_max}) {
- Commands::run("c Dica: $currentTip!");
- Commands::run("c Palavra atual: @currentWordHidden");
- } else {
- Commands::run("c Dica: $currentTip! Palavra atual: @currentWordHidden");
- }
- $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++;
- 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 forca_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 forca_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 é possivel 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 Jogo da Forca, basta você descobrir a palavra enviando a letra (apenas a letra) ou palavra que acredita que seja!");
- Commands::run("pm \"$nick\" ENVIE A MENSAGEM PELO CHAT PÚBLICO, não por PM! Pelo chat pública!!");
- Commands::run("pm \"$nick\" Quanto mais incompleta estiver a palavra, mais pontos ganha ao acerta-la!");
- Commands::run("pm \"$nick\" -------------------");
- Commands::run("pm \"$nick\" Dica: Envie, pelo chat público (NÃO por PM):");
- Commands::run("pm \"$nick\" * 'dica' -> para exibir a dica da palavra atual");
- Commands::run("pm \"$nick\" * 'palavra' -> para exibir o estado atual da palavra");
- 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++;
- 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 da forca é 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 Jogo da Forca atual', 50, '-') . "\n";
- $message .= "Palavra atual: $currentWord\n";
- $message .= "Estado atual: @currentWordHidden\n";
- $message .= "Letras já usadas: @lettersUsed\n";
- $message .= "Dica atual: $currentTip\n";
- message $message, "list";
- }
- 1;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement