O escudo deve ser sua própria entidade que rastreia a localização do jogador? Isso pode dificultar a implementação da filtragem de danos. Também meio que desfoca as linhas entre componentes e entidades anexados.
Edit: Eu acho que não há "comportamento autônomo" suficiente para uma entidade separada. Nesse caso específico, um escudo segue o alvo, trabalha para o alvo e não sobrevive ao alvo. Embora eu concorde que não há nada errado com o conceito de "objeto de escudo", neste caso, estamos lidando com comportamento, que se encaixa perfeitamente em um componente. Mas também sou um defensor de entidades puramente lógicas (em oposição a sistemas de entidades completos nos quais você pode encontrar componentes de transformação e renderização).
O escudo deve ser um componente que abriga outros componentes? Eu nunca vi ou ouvi falar de algo assim, mas talvez seja comum e ainda não sou profundo o suficiente.
Veja isso em uma perspectiva diferente; adicionar um componente também adiciona outros componentes e, após a remoção, os componentes adicionais também desaparecem.
O escudo deve ser apenas um conjunto de componentes que são adicionados ao player? Possivelmente com um componente extra para gerenciar os outros, por exemplo, para que todos possam ser removidos como um grupo. (deixe acidentalmente para trás o componente de redução de danos, agora isso seria divertido).
Essa poderia ser uma solução, promoveria a reutilização, mas também é mais suscetível a erros (para o problema que você mencionou, por exemplo). Não é necessariamente ruim. Você pode descobrir novas combinações de feitiços com tentativa e erro :)
Outra coisa óbvia para alguém com mais experiência em componentes?
Eu vou elaborar um pouco.
Acredito que você tenha notado como alguns componentes devem ter prioridade, independentemente de serem adicionados a uma entidade (isso também responderia a sua outra pergunta).
Também vou assumir que estamos usando a comunicação baseada em mensagens (por uma questão de discussão, é apenas uma abstração sobre uma chamada de método no momento).
Sempre que um componente de blindagem é "instalado", os manipuladores de mensagens dos componentes de blindagem são encadeados com uma ordem específica (superior).
Handler Stage Handler Level Handler Priority
In Pre System High
Out Invariant High
Post AboveNormal
Normal
BelowNormal
Low
System Low
In - incoming messages
Out - outgoing messages
Index = ((int)Level | (int)Priority)
O componente "stats" instala um manipulador de mensagens "dano" no índice In / Invariant / Normal. Sempre que uma mensagem de "dano" for recebida, diminua o HP pelo valor "valor".
Comportamento bastante padrão (coloque alguma resistência a danos naturais e / ou características raciais, qualquer que seja).
O componente blindado instala um manipulador de mensagens "danificado" no índice In / Pre / High.
Every time a "damage" message is received, deplete the shield energy and substract
the shield energy from the damage value, so that the damage down the message
handler pipeline is reduced.
damage -> stats
stats
stats.hp -= damage.value
damage -> shield -> stats
shield
if(shield.energy) {
remove_me();
return;
}
damage.value -= shield.energyquantum
shield.energy -= shield.energyquantum;
stats
stats.hp -= damage.value
Você pode ver que isso é bastante flexível, apesar de exigir um planejamento cuidadoso ao projetar a interação do componente, pois você precisará determinar em que parte dos manipuladores de eventos de componentes do pipeline de manipulação de mensagens estão instalados.
Faz sentido? Deixe-me saber se posso adicionar mais detalhes.
Editar: sobre instâncias de múltiplos componentes (dois componentes de armadura). Você pode acompanhar a contagem total de instâncias em apenas uma instância da entidade (no entanto, isso mata o estado por componente) e continuar adicionando manipuladores de eventos de mensagem ou garantir que seus contêineres de componentes permitam a duplicação de tipos de componentes com antecedência.