Ir para conteúdo
Entre para seguir isso  
Lordfire

PyOT - Como funciona a função genMonster

Recommended Posts

Lordfire    110
Lordfire

Olá!

 

 

Vamos destrinchar e entender como funciona a função genMonster, que o Manoel usou no tutorial PyOT - Como fazer seu primeiro monstro (clique aqui).

 

 

def genMonster(name, look, description=""):
   if isinstance(look, tuple):
       look, corpse = look
   else:
       corpse = idByName('dead %s' % name)
       if not corpse:
           corpse = idByName('slain %s' % name)
   baseMonster = MonsterBase({"lookhead":0, "lookfeet":0, "lookbody":0, "looklegs":0, "lookaddons":0, "looktype":look, "corpse":corpse, "name":name, "description":description or "a %s." % name}, brain)

   monsters[name] = baseMonster


   return baseMonster

 

Se você conhece Python, notou que a primeira linha é a definição de uma função, da seguinte maneira:

def nomeDaFuncao(parametro1, parametro2='valor padrão', ...):

Esta função se chama genMonster, e recebe os parâmetros obrigatórios name, look e o opcional description (de padrão string vazia).

 

 

Na segunda linha, há um teste para verificar se o parâmetro look informado é uma tupla. Uma tupla é um conjunto ordenado de elementos - no caso de Python, uma tupla é imutável (não pode ser alterada após ser criada). O parâmetro pode ser uma tupla ou não porque podemos informar tanto o conjunto do look (o corpo vivo) e do corpse (o corpo morto) do novo monstro, bem como apenas o seu look, você entenderá.

 

 

Caso o if seja True, ou seja, look seja uma tupla, então devemos passar os valores da tupla para as variáveis look e corpse. O código seria assim:

look, corpse = (<corpo vivo>, <corpo morto>)

O que no caso atribui o primeiro valor a look e o segundo a corpse. Se você passar uma tupla com dez valores, os que não forem para uma variável serão descartados. Caso faltem valores, a variável tem o valor None, algo semelhante a nil em Lua.

 

 

Mas caso o programador tenha apenas informado um número no parâmetro look, para indicar que ele sabe apenas o corpo vivo do monstro? Então entraremos no else. Na primeira linha dele, ao corpse é atribuído o retorno da funçãoidByName, que procura o id de um item pelo nome dele. Neste caso, ele procura por "dead <nome do monstro>", como dead demon caso o nome do monstro seja demon.

 

 

E se não houver um item com esse nome? Então o retorno da função será None. O if, então, vai negar o valor de corpse: se houver um item com esse nome, a negação disso será None, portanto, não entra no if; caso não haja, a negação será True (para aritmética booleana, None equivale a False).

 

 

No caso de não haver esse item, então, é procurado o item com o nome "slain <nome do monstro>", do tipo slain demon como no exemplo anterior.

 

 

Se novamente não tivermos um resultado, corpse terá como valor final None, já que não foi informado em nenhum momento. A engine do PyOT toma o cuidado de não tentar criar este corpse quando o monster morrer (e você pode verificar na função onDeath da classe Monster).

 

 

Depois de todos esses testes e condições, chegamos na atribuição de baseMonster (lembre-se, Python é orientado pela indentação do código; essa linha, portanto, está fora dos ifs e elses). Note que não é usada uma função qualquer, e sim uma função com nome de classe (MonsterBase) que, então, executa a função inicializadora dessa classe (a função __init__). Essa função especial cria um novo objeto e envia os parâmetros informados para a função inicializadora, que tem o papel de interpretar esses valores e preencher os atributos do objeto da forma correta. Os parâmetros que enviamos são:

{
   "lookhead" : 0,
   "lookfeet" : 0, 
   "lookbody" : 0,
   "looklegs" : 0,
   "lookaddons" : 0,
   "looktype" : look,
   "corpse" : corpse,
   "name" : name,
   "description" : description or "a %s." % name
}

Eles são enviados em estrutura de dicionário, isto é, um conjunto que é acessado por uma chave que que nós definimos (ao contrário das tuplas e listas, que são acessadas por índices numéricos) e é mutável (pode ser alterado). Cada valor do dicionário tem a estrutura <chave> : <valor> e se parece bastante com as tabelas em Lua.

 

 

O dicionário é apenas um dos parâmetros. O segundo parâmetro, brain, não está em questão, mas é uma outra objeto que armazena todas as ações de um monstro (como uma classe que controla os eventos think, walk, etc.).

 

 

Com isso, temos um monstro criado onde enviamos seus dados e suas ações por parâmetros.

 

 

A penúltima ação, antes do retorno, é registrar o nosso monstro no servidor. Isso é feito inserindo o monstro por seu nome em um dicionário que contém todos os monstros do jogo. Portanto, no dicionário monsters, na chave name (que é o nome do nosso monstro), temos como valor o objeto que representa esse monstro.

 

 

Por último, retornamos esse monstro para o ponto em que executamos a função genMonster. Isso serve para que, quando fizermos o seguinte:

demon = genMonster("demon", <look do demon>)

Possamos acessar o monstro pela variável demon e modificar seus atributos, o que é conteúdo para um novo tutorial.

Compartilhar este post


Link para o post
Manoel R    1
Manoel R

Caralho, você sabe fazer um tutorial em seu fi da mãe...

 

Ficou simplesmente foda, meus parabéns.

Compartilhar este post


Link para o post
Visitante
Este tópico está impedido de receber novos posts.
Entre para seguir isso  
  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.

×