🤔 Para Refletir :
"De pixel a pixel, os tiles compõem o Mapa."
- Core32

DrXama_copyEvents

DadoCWB Masculino

Duque
Membro
Membro
"Esto no me gusta"
Juntou-se
02 de Setembro de 2018
Postagens
724
Bravecoins
1.826
O script do Dr. Xamã possui um comportamento estranho que, eu gostaria de compartilhar e se possível entender/resolver:

1) Eu copio alguns eventos pro mapa onde estou .

2) Saio do mapa e ao retornar pra ele os eventos sumiram. (normal);

3) O problema é que $dataMap.events.length me da um valor como ser aqueles eventos ainda estivessem ali. Diferentemente de $gameMap.events().length .

4) Se eu voltar a copiar um evento para este mesmo mapa.. A nova ID dele será uma ID "irreal" que não reflete o numero de eventos que possui no mapa. A ID toma por base TODOS os eventos que já foram copiados para o mapa.

5) Minha duvida então é:

a) Como que posso dar respawn nesses eventos ao voltar pro mapa?
b) Como deletar esses eventos do $dataMap quando eu "saio" do mapa.

DEMO:
https://drive.google.com/file/d/1vpX-L9T8JkEdUhguTk2APtqd2WozrkK1/view?usp=sharing
 
Olá [member=2347]DadoCWB[/member], tudo bem?

Poderia adicionar o conteúdo do script inteiro na sua postagem?

Creio que dessa forma fica mais fácil de entender e analisar.
 
Antes de qualquer coisa, vou deixar dito aqui que eu posso ter entendido alguma coisa errada (tanto na sua explicação quanto no funcionamento do script). Mas vamos lá.

DadoCWB comentou:
3) O problema é que $dataMap.events.length me da um valor como ser aqueles eventos ainda estivessem ali. Diferentemente de $gameMap.events().length .

1. $dataMap.events e $gameMap._events são duas coisas diferentes. Pelo que vi no código do rpg_objects.js, o primeiro é usado pra popular o segundo, o segundo então sendo acessado pela função events() da $gameMap;

O primeiro (dataMap.events) começa a contagem dos eventos a partir do 1, ou seja, o primeiro valor (index 0) vai ser sempre null. Além disso, aparentemente os ultimos 2 valores serão null também.
Num mapa com 2 eventos, a estrutura da array será mais ou menos
Código:
$dataMap.events = (5) […]?
    0: null?
    1: Object { id: 1, name: "EV001", x: 8, … }?
    2: Object { id: 2, name: "EV002", x: 5, … }?
    3: null?
    4: null?
    length: 5

No retorno do segundo ($gameMap.events()), a contagem começa normalmente do 0 e acaba no ultimo evento do mapa, ou seja, se o mapa tiver 2 eventos, ele terá 2 entradas.
Outra diferença do $gameMap.events() é ele não ser mapeado pelo ID do evento.
Num mapa com 2 eventos, a estrutura da array que a função retorna será mais ou menos
Código:
$dataMap.events() = (2) […]?
    0: Object { _x: 8, _y: 4, _realX: 8, … }?
    1: Object { _x: 5, _y: 4, _realX: 5, … }?
    length: 2

Um extra: A variável $gameMap tem uma propriedade chamada _events que é uma array com os eventos do mapa (a mesma retornada pela função ai de cima), porém, algo curioso em relação à essa array, é que se você acessar ela direto você terá acesso à mesma estrutura de cima porém ordenada pelo ID do evento.
Num mapa com 2 eventos, a estrutura dessa propriedade será mais ou menos
Código:
$gameMap._events = (3) […]?
    1: Object { _x: 8, _y: 4, _realX: 8, … }?
    2: Object { _x: 5, _y: 4, _realX: 5, … }?
    length: 3
Percebe que a propriedade length dessa array é 3 mesmo que ela só liste 2 itens? ;)
PS: O valor na posição 0 é igual a undefined.

DadoCWB comentou:
4) Se eu voltar a copiar um evento para este mesmo mapa.. A nova ID dele será uma ID "irreal" que não reflete o numero de eventos que possui no mapa. A ID toma por base TODOS os eventos que já foram copiados para o mapa.
Eu não sei como funciona o código do plugin dele porém essa ID "irreral" que você se refere na verdade parece ser a ID real do evento. Se o plugin não apaga os eventos da gameMap, eles continuarão sendo incluídos no mapa.
Aparentemente não tem como apagar um evento da dataMap. A gameMap tem uma função eraseEvent() mas ela na verdade só muda o pageIndex do evento pra -1 e muda algumas de suas propriedades (remove imagem, torna o evento "passável", etc...). Com esse pageIndex de -1, o evento de torna inútil mas aparentemente continua nas arrays citadas acima.

Resumo: gameMap.events() reflete realmente a quantidade de eventos no mapa, visíveis ou não.
gameMap._events retorna os eventos do mapa com o index incrementado em 1 (na mesma ordem de seus IDs).
dataMap.events reflete a quantidade de eventos do mapa (criados ou não) e é usado na hora de criar os eventos do mapa (então armazenados em gameMap._events). Tem o seu primeiro valor nulo pra compensar o ID dos eventos além de outros dois valores nulos no final, por algum motivo ¯\_(?)_/¯

DadoCWB comentou:
5) Minha duvida então é:
a) Como que posso dar respawn nesses eventos ao voltar pro mapa?
b) Como deletar esses eventos do $dataMap quando eu "saio" do mapa.
a) Utilize a função setupEvents() da $gameMap e recarrega o mapa. Qualquer evento apagado porém ainda listado entre os eventos do mapa será "respawnado".

b) Aparentemente não existe uma forma nativa de se apagar um evento do $dataMap. É possível apagar o evento do mapa ($gameMap) porém ele ainda seria listado entre os eventos, só não seria interagível.



No final, falei, falei, e não devo ter ajudado em nada kkkkk.
Enfim, se algo ajudou, de nada. Do contrário, perdão.
 
[member=1052]Kawthar[/member] : Cara ... isso é uma aula... entendi boa parte do que você falou mas preciso tentar por em pratica. Em relação ao $dataMap me incomoda de verdade que os eventos copiados pro mapa possuam um ID cada vez mais alto. Para quem trabalha com poucos eventos isso é tranquilo, mas estou manipulando centenas deles...

[member=770]Resque[/member]: olá! Eu fiz mais ou menos uma demonstração da minha duvida:

DEMO:
https://drive.google.com/file/d/1vpX-L9T8JkEdUhguTk2APtqd2WozrkK1/view?usp=sharing

Obrigado a todos pela ajuda...
 
DadoCWB comentou:
[member=1052]Kawthar[/member] : Cara ... isso é uma aula... entendi boa parte do que você falou mas preciso tentar por em pratica. Em relação ao $dataMap me incomoda de verdade que os eventos copiados pro mapa possuam um ID cada vez mais alto. Para quem trabalha com poucos eventos isso é tranquilo, mas estou manipulando centenas deles...
Algo que você pode fazer (consumiria tempo mas facilitaria a programação) seria dar tags pros seus eventos.
Imagine como um código em HTML onde você dá ID ou uma Class pra um elemento pra poder acessar ele diretamente depois.
Você faria isso adicionando meta tags no evento:

F3lXuwa.png

Essa tags estariam listadas na propriedade meta do evento listado no $dataMap.events. Exemplo:
O ID do evento da print é 2, se eu quiser acessar a tag tagOne da print (valor de 20) eu faria:
Código:
let tagOne = parseInt($dataMap.events[2].meta['tagOne'].trim());
Importante notar, também, que o valor da meta tag será sempre uma string e você precisará converter ela pro valor desejado (vide parseInt() no exemplo acima).
Outra coisa importante são os espaços:
Código:
<tagOne: 20 > // => tagOne: ' 20 '
<tagOne:20> // => tagOne: '20'
<tag One: 20> // => 'tag One': ' 20'
Por via das dúvidas, sempre acesse o valor da tag usando ['nome da tag'] e sempre dê um trim() no valor pra tirar os possíveis espaços.

// Edit

Complementando a ideia:

A ideia é filtrar os eventos pelas tags. Você então poderia fazer
Código:
let targets = $dataMap.events.map((event) => event.meta['class'] === 'Evento Class 00');
Assim, targets conteria apenas os eventos com a meta tag class no valor Evento Class 00.
 
Bom ... vamos recapitular a minha questão:

  1)  Estou no mapa 001. 
1.1) este mapa possui 3 eventos (EV 001,EV 002,EV003);
1.2) eu copio o evento de um outro mapa para meu mapa atual.
1.3) meu mapa 1 passa a contar com 4 eventos (EV 001, EV 002, EV003, EV004);
1.4) a função $gameMap.events().length me retorna 4. Isto significa que tenho 4 eventos no meu mapa.
1.5) a função  $dataMap.events.length me retorna 5. Isto significa que tenho 4 eventos no "data" deste mapa;
1.6) o índice [0] de $dataMap.events é nulo (só pra constar).

  2) Eu teleporto para o mapa 002.

  3) Eu teleporto de volta para o mapa 001.
3.1) na tela de jogo estão  3 eventos: EV 001, EV 002, e EV003;
3.2) O evento EV 004 não é exibido na tela de jogo.
3.3) $gameMap.events().length me retorna 3. Exatamente o numero de evntos que é mostrado na tela.
3.4) Apesar de não ser mostrado na tela, o EV 004 é contabilizado em $dataMap.events.length que me retorna 4.

  4) Se eu copiar um novo evento para este mapa. Este evento virá com um índice 005.
4.1)Isso acontece por que no script que copia o evento pro mapa atual sempre acrescenta o evento na ultima psição de $dataMap.events.
4.2) Então eu teria na tela de jogo os eventos: EV 001, EV 002, EV 003 e EV 005.

A solução mais simples que encontrei para evitar ter o $dataMap.events contabilizando eventos que não estão na tela é a seguinte:

Toda vez que eu aciono a função para copiar um evento  no mapa eu verifico se existem eventos no $dataMap que não estão sendo exibidos na tela. Se essa condição for verdade eu deleto esse índice do $dataMap. Faço isso quanstas vezes for necessário.

Código:
//reseta o $dataMap caso necesário: enquanto houverem indices nullos em $dataMap.events maiores que o ultimo evento valido

var tam = $gameMap.events()[$gameMap.events().length-1]._eventId; // ID do ultimo evento não nulo do mapa atual
while($dataMap.events.length> tam+1){ 
  $dataMap.events.pop();
}



edit: alterei o código para evitar bugs em função de haver eventos nulos em $dataMap.events com índices menores que o índice do ultimo evento não-nulo.

https://github.com/DadoCWB/RPG-MAKER-MV--JS/blob/master/DrXama_copyEvents.js
 
DadoCWB comentou:
Bom ... vamos recapitular a minha questão:

  1)  Estou no mapa 001. 
1.1) este mapa possui 3 eventos (EV 001,EV 002,EV003);
1.2) eu copio o evento de um outro mapa para meu mapa atual.
1.3) meu mapa 1 passa a contar com 4 eventos (EV 001, EV 002, EV003, EV004);
1.4) a função $gameMap.events().length me retorna 4. Isto significa que tenho 4 eventos no meu mapa.
1.5) a função  $dataMap.events.length me retorna 5. Isto significa que tenho 4 eventos no "data" deste mapa;
1.6) o índice [0] de $dataMap.events é nulo (só pra constar).

  2) Eu teleporto para o mapa 002.

  3) Eu teleporto de volta para o mapa 001.
3.1) na tela de jogo estão  3 eventos: EV 001, EV 002, e EV003;
3.2) O evento EV 004 não é exibido na tela de jogo.
3.3) $gameMap.events().length me retorna 3. Exatamente o numero de evntos que é mostrado na tela.
3.4) Apesar de não ser mostrado na tela, o EV 004 é contabilizado em $dataMap.events.length que me retorna 4.

  4) Se eu copiar um novo evento para este mapa. Este evento virá com um índice 005.
4.1)Isso acontece por que no script que copia o evento pro mapa atual sempre acrescenta o evento na ultima psição de $dataMap.events.
4.2) Então eu teria na tela de jogo os eventos: EV 001, EV 002, EV 003 e EV 005.

A solução mais simples que encontrei para evitar ter o $dataMap.events contabilizando eventos que não estão na tela é a seguinte:

Toda vez que eu aciono a função para copiar um evento  no mapa eu verifico se existem eventos no $dataMap que não estão sendo exibidos na tela. Se essa condição for verdade eu deleto esse índice do $dataMap. Faço isso quanstas vezes for necessário.

Código:
	//reseta o $dataMap caso necesário
                while($dataMap.events.length> $gameMap.events().length+1){
                	$dataMap.events.pop();
                }

Eu não gosto de alterar código alheio mas eu realmente precisava dessa solução. A seguir o código completo e alterado:

código disponivel em : https://github.com/DadoCWB/RPG-MAKER-MV--JS/blob/master/DrXama_copyEvents.js
 
Muito Obrigado dr Xamã ....

Após um exaustivo uso desse script, se me permite opinar eu alteraria ele e retiraria um monte de funções que a meu ver são "perfumaria" e deixaria ele somente com o essencial.

1) $gameMap.copyEvent(mapId, eventId, mapX, mapY, selfSwitches)

O problema dessa função é a falta de controle do usuario sobre a ID do evento criado. Eu  sugiro que ela retorna a ID do evento criado.



2)  * $gameMap.copyEventRegion(mapId, eventId, regionId, quantity, selfSwitches)

Pra mim o parâmetro quantity é desnecessário. Pois se eu quiser copiar um memso evento  varias vezes eu simplesmente poderia repetir o comando dentro de um while ou for (por exemplo);




3) * $gameMap.copyEventName(eventName, mapId, tileX, tileY, quantity, selfSwitches)

A mesma observação da questõao (2);



PERSISTÊCNCIA
Todas essas 3 funções poderiam ter 2 versões:

Versão Persistente: copia o evento pro mapa DEFINITIVAMENTE. Isso p evitaria que o ele  desaparecesse toda vez que o jogador teleportasse pra outro mapa e retornasse.

Versão temporária: copia o evento pro mapa mas quando o jogado teleporta para outro mapa, aquele evento é APAGADO definitivamente do mapa.

FORÇAR ID

Uma função boa também seria uma que PERMITISSE AO PROGRAMADOR escolher qual a ID que ELE quer atribuir ao evento copiado pro mapa. Isso me permitiria por exemplo sobescrever um evento já existente no mapa.
 
Desculpa ser chata agora mas temos regras contra double-posts então vou pedir pra que, na próxima, você edite sua última mensagem e adicione a informação extra. Toleramos double-post só em situações justificáveis.

Vou editar seus posts e apagar os duplicados.
 
Eu agradeço e peço desculpas....
Acabei clicando em citação ao invés de edição e isso fez as postagens  em duplicidade....

Pode notar que de uma forma muito estranha "eu estou citando a mim mesmo" ...
Peço desculpas pela atrapalhada.
 
Voltar
Topo Inferior