Doom Wiki
Doom Wiki


Debido a un error en la implementación de las luchas internas entre monstruos en Doom v1.1 y versiones anteriores, los monstruos intentarán suicidarse atacándose a sí mismos si reciben daño cuando destruyen barriles explosivos.

Una simple explicación para este comportamiento es la siguiente: cuando explota un barril, el motor de Doom busca qué jugador o monstruo fue el causante de la explosión. Cuando otro objeto se daña como resultado de la explosión del barril, la "fuente" de la explosión se pasa entonces al objeto dañado. Un monstruo herido en una explosión de barril luego tomará represalias contra el monstruo o jugador que provocó que explotara.

Sin embargo, si un monstruo se daña a sí mismo en la explosión del barril, es la causa de su propia lesión. Las versiones de Doom anteriores a v1.1 no comprobaban este caso especial (no es un escenario que se repita con frecuencia durante un juego normal). Como resultado, los monstruos que se lesionan a sí mismos por la explosión de un barril tomarán represalias contra ellos mismos.

Los monstruos como Cacodemonios, Barones del infierno y Diablillos se "destrozarán" con su propio ataque cuerpo a cuerpo. Los Zombis (o monstruos sin ataques cuerpo a cuerpo) se "vuelven locos", disparando ciegamente por delante, lo que puede causar que se generen luchas internas entre monstruos como resultado.

Aspectos técnicos[]

La causa probable de esto puede verse en el código fuente de Doom. En la función P_DamageMobj en p_inter.c es el siguiente código:

if ( (!target->threshold || target->type == MT_VILE)
        && source && source != target
        && source->type != MT_VILE)
   {
       // if not intent on another player,
       // chase after this one
       target->target = source;
       target->threshold = BASETHRESHOLD;
       if (target->state == &states[target->info->spawnstate]
           && target->info->seestate != S_NULL)
           P_SetMobjState (target, target->info->seestate);
   }

Se ejecuta este código cuando un objeto es dañado por otro objeto, incluyendo explosiones de barriles. La variable source es una referencia al objeto que causó el daño, mientras que la variable target es una referencia al objeto sobre el que se inflige daño. Cuando se destruye el barril, los enemigos afectados se lesionan con un valor de source igual al del jugador o enemigo que causó la explosión.

Se supone que el código anterior produce que los monstruos tomen represalias contra los jugadores que les atacan. Sin embargo, cuando un monstruo se daña sí mismo a través de una explosión de barril, tanto target como source hacen referencia al propio monstruo. Es probable que el código en negrita no estuviese presente en la versión 1.1. Como resultado de ello, el objetivo del monstruo (target->target, el objeto que está persiguiendo / atacando actualmente) queda enfocado sobre sí mismo. El resultado es que se ataca a sí mismo.

Error[]

La idea era presumiblemente que los barriles "culparan" al actor directamente responsable de su explosión. Sin embargo, la función P_DamageMobj no funciona en el orden correcto para que esto suceda realmente. Este extracto muestra el problema:

   // do the damage	
   target->health -= damage;	
   if (target->health <= 0)
   {
	P_KillMobj (source, target);
	return;
   }

   if ( (P_Random () < target->info->painchance)
	 && !(target->flags&MF_SKULLFLY) )
   {
	target->flags |= MF_JUSTHIT;	// fight back!
	
	P_SetMobjState (target, target->info->painstate);
   }
			
   target->reactiontime = 0;		// we're awake now...	

   if ( (!target->threshold || target->type == MT_VILE)
	 && source && source != target
	 && source->type != MT_VILE)
   {
	// if not intent on another player,
	// chase after this one
	target->target = source;
	target->threshold = BASETHRESHOLD;
	if (target->state == &states[target->info->spawnstate]
	    && target->info->seestate != S_NULL)
	    P_SetMobjState (target, target->info->seestate);
   }

El primer bloque destruirá automáticamente al actor dañado si no tiene puntos de golpe restantes. El último bloque, detallado en la sección anterior de este artículo, cambia el objetivo. Tenga en cuenta la instrucción return; después de P_KillMobj en el primer bloque: esto significa que si se mata el actor, no ejecutará el resto de la función y, por lo tanto, no cambiará de destino.

P_KillMobj () tampoco tiene un mecanismo de cambio de objetivo. (Aparte, este código también muestra algunos trucos específicos de la clase de actor: un Alma perdida que carga no se colocará en su estado de dolor, y un Archi-vil nunca será atacado, lo que lo hace inmune a las luchas internas).

Otros juegos[]

El error se mantuvo en Heretic y Hexen, que nunca lo solucionaron en un lanzamiento oficial.

  • En Heretic, las Vainas sirven como análogo del barril.
  • La variante Hexen requiere que ocurran circunstancias algo más inusuales; el monstruo en cuestión debe tener un proyectil de tipo "bola de fuego" y sufrir daño por salpicadura al quemar un árbol o arbusto destructible. Las criaturas que pueden cumplir con estos requisitos incluyen Afrits, ambas variedades de Serpiente del caos, Guivernos de la muerte, Korax, Menelkir y Saqueadores.

Video[]

Cacodemon comete suicidio en Doom 1.1

Véase también[]