{ "cells": [ { "cell_type": "markdown", "id": "aware-playing", "metadata": {}, "source": [ "# Instruções\n", "\n", "A partir dessas instruções espero que se torne fácil o processo de criar uma macro seguindo esses passos. \n", "Recomendo que leia todas as instruções antes de verificar os exemplos e templates.\n", "\n", "Pequenas definições antes de começar:\n", "\n", "### Macro\n", "\n", "Conjunto de ações a serem performadas pelo computador.
\n", "No caso da descrição a macro retornada informa, o nome da ação e sua descrição, com o nome em negrito.
\n", "No caso do template_rolagem, principalmente a ser utilizado com ataques, a macro retorna o nome, a rolagem de ataque e dano, com o dano crítico calculado caso necessário, e sua descrição. Ao colar o resultado da descrição obtida através de uma das funções deste notebook no espaço de macros do ataque, esta descrição será formatada para ser impressa ao fim do ataque.\n", "\n", "Seguem exemplo de alguns resultados a seguir:\n", "\n", "| ![Rolagem de Ataque com Macro](images/ataque.png \"Rolagem de Ataque com Macro\") | ![Descrição com Macro](images/descricao.png \"Descrição com Macro\") | ![Spell com Macro](images/inventor.png \"Spell com Macro\") |\n", "|:---:|:---:|:---:|\n", "| Rolagem de Ataque com Macro | Descrição com Macro | Spell com Macro |\n", "\n", "Como podem ver a partir da última imagem essas macros podem gerar implicações bastante interessantes para as suas habilidades, automatizando uma boa parte do processo.\n", "\n", "\n", "### Template\n", "\n", "Um template, nesse notebook, significa uma função tal que os valores estão dispostos de forma que, ao substituirmos os valores nos espaços reservados, ela retorna o valor desejado pelo usuário.\n", "\n", "Então, quando temos \"{espaco_reservado}\" o usuário deve substituir {espaco_reservado} pelo valor desejado.\n", "\n", "No caso por exemplo de \"{tipo_acao}\", em que tipo_acao pode tomar qualquer um dos valores (ability, attack, power, spell), caso seja de nosso interesse criar uma ação do tipo *attack* substituiremos *{tipo_acao}* por *attack*.\n", "\n", "\"{tipo_acao}\" -> \"attack\"\n", "\n", "## Primeiros Passos\n", "\n", "A não ser que você tenha conhecimento prévio de programação, recomendo que sejam executadas todas as células antes que comecem a utilizar o caderno. Isto fará com que não haja nenhuma dependência não instalada ou função não declarada. \n", "Para isso recomendo que clique em Kernel, entre *Cell* e *Widjets*, na barra abaixo do logo do Jupyter e, em seguida, *Restart & Run All*. \n", "\n", "## Entendendo os Exemplos\n", "\n", "Além dos exemplos padrão, que utilizarei para demonstrar o funcionamento do programa, também deixarei comentados templates de chamada de função, que vocês utilizarão para criar suas próprias macros!\n", "\n", "Um exemplo consiste em uma chamada de função com os valores já postos que retorna um resultado provavelmente muito próximo dos seus próprios resultados. Para executar um exemplo vá até a célula onde ele está e aperte CTRL+Enter, o resultado aparecerá abaixo da célula\n", "\n", "## Entendendo os Templates\n", "\n", "Os templates estão aqui para guiar vocês a montarem suas próprias chamas de funções para criar macros pras suas fichas. Templates estão organizados da seguinte forma:\n", "\n", "```cria_descricao(\"{tipo_acao}\", \"{id_acao}\")``` \n", "```cria_template_rolagem(\"{tipo_acao}\", \"{id_acao}\")``` \n", "-> Para ações Habilidade e Poder \n", "\n", "```cria_descricao(\"spell\", \"{id_acao}\", circulo=\"{circulo_magia}\")``` \n", "```cria_template_rolagem(\"spell\", \"{id_acao}\", circulo=\"{circulo_magia}\")``` \n", "-> Para ações de Magia\n", "\n", "```cria_descricao(\"attack\", \"{id_acao}\")``` \n", "```cria_template_rolagem(\"attack\", \"{id_acao}\", critico=\"{tipo_critico}\")``` \n", "-> Para ações de Ataque\n", "\n", "Os tipo de ação aceita são:\n", " \n", " * ability\n", " * attack\n", " * power\n", " * spell\n", " \n", "Os tipos de critico aceitos são:\n", "\n", " * DANO\n", " > Multiplicando o valor dos dados pelo multiplicador de crítico\n", " * DADO\n", " > Multiplicando o número de dados do ataque\n", " \n", "Os circulos de magia vão de 1 até 5.\n", " \n", "O ID da ação é o ID armazenado pelo Roll 20. Para acessá-lo, clique com o botão direito na linha que contem a acão para qual você deseja criar a macro e procurar a div com classe ```rep_item```. Em seguida copie o valor sob o atributo ```data-reprowid```, este é seu ID.\n", "\n", "Recomendo, como antes, caso ainda esteja confuso sobre como acessar o ID da ação, que assista o vídeo https://youtu.be/dGK5eYLgz3E?t=549, do Vinícius silva para mais informações.\n", "PS: Isso é bem mais simples do que parece, e já posicionei o vídeo no momento que ele fala como pegar esse ID, que é a única coisa necessária para nossos objetivos.\n", " \n", "## Criando uma Macro\n", "\n", "Para criar uma macro, realize as substituições indicadas no tópico anterior e role sua célula com a chamada de função apertando CTRL+Enter enquanto estiver com ela selecionada.\n", "\n", "\n", "## Finalizações\n", "\n", "Com o tempo vocês se tornarão mais familiarizados com os notebooks pra perceber que podem realizar pequenas alterações nos templates fornecidos são apenas sujestões e que vocês podem criar seus próprios templates.\n", "Espero que consigam utilizar com facilidade esse notebook!\n", "\n", "##### Que Nimb guie seus dados!" ] }, { "cell_type": "code", "execution_count": 1, "id": "unavailable-sequence", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Requirement already satisfied: regex in /home/caioc/.pyenv/versions/3.9.2/lib/python3.9/site-packages (2021.3.17)\n", "Requirement already satisfied: typing in /home/caioc/.pyenv/versions/3.9.2/lib/python3.9/site-packages (3.7.4.3)\n", "Note: you may need to restart the kernel to use updated packages.\n" ] } ], "source": [ "pip install regex typing" ] }, { "cell_type": "code", "execution_count": 2, "id": "theoretical-senator", "metadata": {}, "outputs": [], "source": [ "import base\n", "\n", "from functools import partial\n", "from typing import Callable, Tuple" ] }, { "cell_type": "code", "execution_count": 3, "id": "universal-challenge", "metadata": {}, "outputs": [], "source": [ "def pega_atributos (tipo_acao: str) -> list:\n", " if tipo_acao == \"ataque\":\n", " return [ \"nome{}\".format(tipo_acao), \"descricao{}\".format(tipo_acao) ]\n", " else:\n", " return [ \"name{}\".format(tipo_acao), \"{}description\".format(tipo_acao) ]\n", " \n", "def pega_funcao (tipo_funcao: int, tipo_acao: str, circulo: str, critico: base.CriticalTypes = None) -> Callable:\n", " if tipo_acao == \"ability\":\n", " return base.rpt_ability if tipo_funcao == 1 else base.create_ability_template\n", " elif tipo_acao == \"power\":\n", " return base.rpt_power if tipo_funcao == 1 else base.create_power_template\n", " elif tipo_acao == \"spell\":\n", " return (\n", " partial(base.rpt_spell, spell_circle=circulo)\n", " if tipo_funcao == 1\n", " else partial(base.create_spell_template, spell_circle=circulo)\n", " )\n", " elif tipo_acao == \"attack\":\n", " if critico is None:\n", " return base.rpt_attack if tipo_funcao == 1 else base.create_attack_template\n", " else:\n", " return (\n", " partial(base.rpt_attack, critical=critico)\n", " if tipo_funcao == 1\n", " else partial(base.create_attack_template, critical=critico)\n", " )\n", " \n", " return None\n", " \n", "def repete_acao (tipo_acao: str, circulo: str) -> Tuple[Callable, list]:\n", " atributos = pega_atributos(tipo_acao)\n", " funcao = pega_funcao(1, tipo_acao, circulo)\n", " \n", " return funcao, atributos\n", "\n", "def macroniza_acao (tipo_acao: str, circulo: str, critico: base.CriticalTypes) -> Callable:\n", " funcao = pega_funcao(0, tipo_acao, circulo, critico) \n", " return funcao" ] }, { "cell_type": "code", "execution_count": 4, "id": "charitable-trace", "metadata": {}, "outputs": [], "source": [ "def cria_descricao (tipo_acao: str, id_acao: str, circulo: str = \"1\") -> str:\n", " descreve, atributos = repete_acao(tipo_acao, circulo)\n", " if descreve is None:\n", " print(\"Tipo Inválido de Ação: Ações válidas (ability, attack, power, spell)\")\n", " return \"TIPO INVÁLIDO DE AÇÃO\"\n", " \n", " descricao = base.describe(*descreve(id_acao, rpt_attrs=atributos))\n", " \n", " print(descricao)\n", " return descricao" ] }, { "cell_type": "code", "execution_count": 5, "id": "further-referral", "metadata": {}, "outputs": [], "source": [ "def cria_template_rolagem (tipo_acao: str, id_acao: str, circulo: str = \"1\", critico: str = \"DANO\") -> str:\n", " funcao = macroniza_acao(\n", " tipo_acao, str(circulo), base.CriticalTypes.DAMAGE if critico == \"DANO\" else base.CriticalTypes.DICE\n", " )\n", " if funcao is None:\n", " print(\"Tipo Inválido de Ação: Ações válidas (ability, attack, power, spell)\")\n", " return \"TIPO INVÁLIDO DE AÇÃO\"\n", " \n", " template_rolagem = funcao(id_acao)\n", " \n", " print(template_rolagem)\n", " return funcao(id_acao)" ] }, { "cell_type": "markdown", "id": "minute-belfast", "metadata": {}, "source": [ "## Início dos Templates\n", "\n", "Caso não tenha ficado claro o funcionamento dos templates, recomendo fortemente que olhe os exemplos, na próxima seção, isto tornará muito mais fácil a compreensão.\n", "\n", "Remova os # do início da linha que deseja e realize as alterações indicadas em ***Entendendo os Templates***.
\n", "Em seguida pressione CTRL+Enter para receber o resultado da função." ] }, { "cell_type": "code", "execution_count": 6, "id": "verbal-liabilities", "metadata": {}, "outputs": [], "source": [ "#desc = cria_descricao(\"{tipo_acao}\", \"{id_acao}\")\n", "#temp_rol = cria_template_rolagem(\"{tipo_acao}\", \"{id_acao}\")" ] }, { "cell_type": "code", "execution_count": 7, "id": "wired-reserve", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "&{template:spell}{{character=@{character_name}}}{{spellname=@{repeating_spells1_-MWqT416CtCovnpvtL7D_namespell}}}{{type=@{repeating_spells1_-MWqT416CtCovnpvtL7D_spelltipo}}}{{execution=@{repeating_spells1_-MWqT416CtCovnpvtL7D_spellexecucao}}}{{duration=@{repeating_spells1_-MWqT416CtCovnpvtL7D_spellduracao}}}{{range=@{repeating_spells1_-MWqT416CtCovnpvtL7D_spellalcance}}}{{targetarea=@{repeating_spells1_-MWqT416CtCovnpvtL7D_spellalvoarea}}}{{resistance=@{repeating_spells1_-MWqT416CtCovnpvtL7D_spellresistencia}}}{{description=@{repeating_spells1_-MWqT416CtCovnpvtL7D_spelldescription}}}{{cd=@{repeating_spells1_-MWqT416CtCovnpvtL7D_spellcd}}}\n" ] } ], "source": [ "#desc = cria_descricao(\"spell\", \"{id_acao}\", circulo=\"{circulo_magia}\")\n", "temp_rol = cria_template_rolagem(\"spell\", \"-MWqT416CtCovnpvtL7D\", circulo=\"1\")" ] }, { "cell_type": "code", "execution_count": 8, "id": "filled-weather", "metadata": {}, "outputs": [], "source": [ "#temp_rol = cria_template_rolagem(\"attack\", \"{id_acao}\", critico=\"{tipo_critico}\")" ] }, { "cell_type": "markdown", "id": "southeast-boost", "metadata": {}, "source": [ "## Início dos Exemplos" ] }, { "cell_type": "code", "execution_count": 9, "id": "adopted-priority", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "**@{repeating_abilities_-MWol3wUlwt1di-xQWnZ_nameability}**: @{repeating_abilities_-MWol3wUlwt1di-xQWnZ_abilitydescription}\n" ] } ], "source": [ "desc = cria_descricao(\"ability\", \"-MWol3wUlwt1di-xQWnZ\")" ] }, { "cell_type": "code", "execution_count": 10, "id": "further-central", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "**@{repeating_powers_-MWokal-6PQ7hFQQITAE_namepower}**: @{repeating_powers_-MWokal-6PQ7hFQQITAE_powerdescription}\n" ] } ], "source": [ "desc = cria_descricao(\"power\", \"-MWokal-6PQ7hFQQITAE\")" ] }, { "cell_type": "code", "execution_count": 11, "id": "conservative-animation", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "&{template:t20-attack}{{character=@{character_name}}}{{attackname=@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_nomeataque}}}{{attackroll=[[1d20cs>@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_margemcriticoataque}+[[@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_ataquepericia}]]+@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_bonusataque}]]}} {{damageroll=[[@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_danoataque}+@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_modatributodano}+@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_danoextraataque}]]}} {{criticaldamageroll=[[@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_danoataque}*@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_multiplicadorcriticoataque}+@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_modatributodano}+@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_danoextraataque}]]}}{{typeofdamage=@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_ataquetipodedano}}}{{description=@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_ataquedescricao}}}\n" ] } ], "source": [ "temp_rol = cria_template_rolagem(\"attack\", \"-MX-d2s12Nz2i6J6qbQY\", critico=\"DANO\") # Multiplicando o dano dos dados" ] }, { "cell_type": "code", "execution_count": 12, "id": "abstract-liquid", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "&{template:t20-attack}{{character=@{character_name}}}{{attackname=@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_nomeataque}}}{{attackroll=[[1d20cs>@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_margemcriticoataque}+[[@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_ataquepericia}]]+@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_bonusataque}]]}} {{damageroll=[[@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_danoataque}+@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_modatributodano}+@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_danoextraataque}]]}} {{criticaldamageroll=[[@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_danocriticoataque}+@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_modatributodano}+@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_danoextraataque}]]}}{{typeofdamage=@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_ataquetipodedano}}}{{description=@{repeating_attacks_-MX-d2s12Nz2i6J6qbQY_ataquedescricao}}}\n" ] } ], "source": [ "temp_rol = cria_template_rolagem(\"attack\", \"-MX-d2s12Nz2i6J6qbQY\", critico=\"DADO\") # Multiplicando o número de dados" ] }, { "cell_type": "code", "execution_count": 13, "id": "vanilla-galaxy", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "&{template:spell}{{character=@{character_name}}}{{spellname=@{repeating_spells1_-MWojXgYrdLO17N5ljE8_namespell}}}{{type=@{repeating_spells1_-MWojXgYrdLO17N5ljE8_spelltipo}}}{{execution=@{repeating_spells1_-MWojXgYrdLO17N5ljE8_spellexecucao}}}{{duration=@{repeating_spells1_-MWojXgYrdLO17N5ljE8_spellduracao}}}{{range=@{repeating_spells1_-MWojXgYrdLO17N5ljE8_spellalcance}}}{{targetarea=@{repeating_spells1_-MWojXgYrdLO17N5ljE8_spellalvoarea}}}{{resistance=@{repeating_spells1_-MWojXgYrdLO17N5ljE8_spellresistencia}}}{{description=@{repeating_spells1_-MWojXgYrdLO17N5ljE8_spelldescription}}}{{cd=@{repeating_spells1_-MWojXgYrdLO17N5ljE8_spellcd}}}\n" ] } ], "source": [ "temp_rol = cria_template_rolagem(\"spell\", \"-MWojXgYrdLO17N5ljE8\", circulo=\"1\")" ] }, { "cell_type": "code", "execution_count": 14, "id": "still-beijing", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "&{template:spell}{{character=@{character_name}}}{{spellname=@{repeating_spells2_-MX-h-dXicmUNW88uEC-_namespell}}}{{type=@{repeating_spells2_-MX-h-dXicmUNW88uEC-_spelltipo}}}{{execution=@{repeating_spells2_-MX-h-dXicmUNW88uEC-_spellexecucao}}}{{duration=@{repeating_spells2_-MX-h-dXicmUNW88uEC-_spellduracao}}}{{range=@{repeating_spells2_-MX-h-dXicmUNW88uEC-_spellalcance}}}{{targetarea=@{repeating_spells2_-MX-h-dXicmUNW88uEC-_spellalvoarea}}}{{resistance=@{repeating_spells2_-MX-h-dXicmUNW88uEC-_spellresistencia}}}{{description=@{repeating_spells2_-MX-h-dXicmUNW88uEC-_spelldescription}}}{{cd=@{repeating_spells2_-MX-h-dXicmUNW88uEC-_spellcd}}}\n" ] } ], "source": [ "temp_rol = cria_template_rolagem(\"spell\", \"-MX-h-dXicmUNW88uEC-\", circulo=\"2\")" ] }, { "cell_type": "code", "execution_count": 15, "id": "convinced-costa", "metadata": {}, "outputs": [], "source": [ "# Exemplo com copia, rodo por padrão para não sobrescrever o CTRL+C do usuário\n", "#temp_rol = cria_template_rolagem(\"spell\", \"-MX-h-dXicmUNW88uEC-\", circulo=\"2\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.2" } }, "nbformat": 4, "nbformat_minor": 5 }