Doom Wiki
Advertisement
Doom Wiki


A veces, los ataques hitscan producidos en grandes áreas abiertas pueden chocar contra una "barrera invisible". Esto se debe al hecho de que el motor de Doom tiene algunas dificultades para manejar la colisión de balas contra paredes que sean muy largas.

Este error ocurre con más frecuencia en niveles donde hay paredes que tienen más de 2048 unidades de largo.

Detalles técnicos[]

Explicación técnica[]

Cuando una pared es muy larga, el motor puede evaluar incorrectamente la posición de la pared.

La explicación técnica de cómo ocurre aún se desconoce, pero se conoce un caso particular que los mapeadores deben evitar: la linedef #0 siempre debe tener una longitud menor a 2048 unidades. Esto reduce en gran medida la aparición del error, porque esencialmente todas las utilidades de generación de mapas de bloques incluirán linedef #0 en cada bloque del BLOCKMAP.

Aunque esta es la causa más común de este error, también puede ocurrir cuando un hitscan cruza un bloque que contiene otra línea larga.

Barrera invisible

Los ataques de Spiderdemon están bloqueados por una "barrera invisible".

Explicación técnica del caso más común[]

Para comprender este caso, primero se debe comprender la estructura del lump BLOCKMAP. Cada bloque del mapa de bloques contiene una lista (blocklist) de linedefs que toca o puede tocar el bloque. La lista de bloques siempre comienza con el valor 0 y termina con -1. La mayoría de las utilidades incluirán el número 0 al principio de la lista, aunque no es una necesidad técnica y el motor de Doom no lo omitirá.

Esta es la parte esencial de la función P_BlockLinesIterator de p_maputl.c:

  offset = y*bmapwidth+x;
   
   offset = *(blockmap+offset);
   
   for ( list = blockmaplump+offset ; *list != -1 ; list++)
   {
       ld = &lines[*list];
       
       if (ld->validcount == validcount)
           continue; 	// line has already been checked
       
       ld->validcount = validcount;
       
       if ( !func(ld) )
           return false;
   }
   return true;	// everything was checke

El ciclo iterará sobre la lista y comenzará al principio de la lista de bloques que tiene el valor 0 hasta que llega al final. Cada elemento de la lista es el número de una linedef, pero como la iteración comienza en el primer elemento, que siempre es 0, la definición de línea #0 se comprueba constantemente cada vez que se llama a la función. Dado que se hace cada vez que el jugador dispara, es más probable que el error ocurra en un nivel donde esta definición de línea es demasiado larga.

Véase también[]

Advertisement