[SOLVED AGAIN] Element counted multiple times

This is my code (pretty ugly, I know):

public class IncreasedDamageTakenProcessor extends BaseAppState {

    static Logger log = LoggerFactory.getLogger(IncreasedDamageTakenProcessor.class);

    private EntityData ed;
    private EntitySet entities;

    public static int increasedDamageTaken = 0;

    @Override
    protected void initialize(Application app) {
        ed = getState(EntityDataState.class).getEntityData();
        //entities = ed.getEntities(IncreasedDamageTaken.class, Touching.class);
        entities = ed.getEntities(Filters.fieldEquals(Touching.class, "touched", FightAppState.pppp),IncreasedDamageTaken.class);
    }

    @Override
    protected void cleanup(Application app) {
        // Release the entity set we grabbed previously
        entities.release();
        entities = null;
    }

    @Override
    public void update(float tpf) {
        entities.applyChanges();
        int idt = 0;
        for (Entity e : entities) {
            idt += ed.getComponent(e.getId(), IncreasedDamageTaken.class).getValue();
        }
        increasedDamageTaken = idt;
        ed.setComponent(FightAppState.pppp, new IncreasedDamageTaken(idt));
        System.out.println("IDT: "+increasedDamageTaken);
    }

    @Override
    protected void onEnable() {
    }

    @Override
    protected void onDisable() {
    }
}

Basically I read the ā€œincreaseddamageā€ component that are ā€œtouchingā€ an element, and apply the sum as a component to the entity they were touching.

However, for each tpf the value is counted again. The explanation could be that the element is ā€œtouchingā€ himself but thatā€™s not the case:

 System.out.println(ed.getEntity(FightAppState.pppp, Touching.class));

return

Entity[EntityId[0], values=[null]]

Not sure if i am understanding your problem correct or no, but
you need to get entitties as below

entities.getAddedEntities() 
entities.getChangedEntities() 
entities.getRemovedEntities()

also this line

ed.getEntities(Filters.fieldEquals(Touching.class, "touched", FightAppState.pppp),IncreasedDamageTaken.class);

should change to

ed.getEntities(Filters.fieldEquals(Touching.class, "touched", FightAppState.pppp),IncreasedDamageTaken.class, Touching.class);

otherwise Touching component wont be detected.

He only needs that if he wants to track add/changed/removedā€¦ if you just iterate over the entities every frame then you donā€™t need that. Just applyChanges() is fine.

The rest is true, though. Just because you filter on something doesnā€™t mean itā€™s included in the components list.

And Iā€™m curious what FightAppState.pppp is because that looks super-duper strange for three or four different reasons.

The whole thing looks very strange. Like you are only trying to edit one entityā€¦ in which case EntitySet is like using a 20 ton truck to swat a fly. Edit: Except I think I know why nowā€¦ but Iā€™d still be curious why you are only doing this for one entity instead of all entities that might take damage.

If I do like this then the component is filtered and I donā€™t see anything.

To clarify: ā€œentitiesā€ is always empty.

Yeah, this is done for testing. Eventually it will work for any entity.

However, my original issue is not addressed: why does the component proliferate?

If you donā€™t do it like thatā€¦ then you might as well leave the filter out because it canā€™t be doing anything.

Itā€™s still a bit unclear what you are actually trying to do and whether youā€™ve actually added debugging to see whatā€™s going on. My first step would have been to stick printlns in to see whatā€™s going on.

Thatā€™s what I eventually did, and it workedā€¦ so thanks all, I guess :slight_smile:

This is my code for Touching

public class Touching implements EntityComponent {
	private final EntityId touched;
	
	public Touching() {
		touched = null;
	}

	public Touching(EntityId touched){
		this.touched = touched;
	}

	public EntityId getTouched() {
		return touched;
	}
}

How is testing done with Filters.fieldEquals(Touching.class, "touched", FightAppState.pppp ?
It is always falseā€¦ maybe it uses == instead of equals()? And if yes, how should I rectify it? Store the entityid as Long?

Canā€™t see how you are determining this. Because your earlier code would have definitely because you werenā€™t retrieving the component so the entity would never have had the component to test.

It uses .equals().

Edit: see:

1 Like

Thanks! Ok, now Iā€™ve learned that I should do

ed.getEntities(Filters.fieldEquals(Touching.class, "touched", myID),Touching.class)

instead of

ed.getEntities(Filters.fieldEquals(Touching.class, "touched", myID),Touching.class, AnotherComponent.class)

Narrowing down the selection of component should be done later.

Thatā€™s fineā€¦ as long as the entity actually has AnotherComponent on it.

You can specify as many components as you want. They must all be present and the one in the filter must be specified. Those are the only requirements.

Iā€™ll provide an example similar to things I use all the time just in case this isnā€™t clear still.

Letā€™s say we have InContainer which points to a container and ContainerSlot which defines where in the container we might be. Now letā€™s say I want to get all of a particular containers contents. I can use:

EntityId containerId = ā€¦
ed.getEntities(Filters.fieldEquals(InContainer.class, ā€œcontainerā€, containerId), InContainer.class, ContainerPosition.class, IconInfo.class, Name.class);

ā€¦and I will get all of the entities that have all of those components and also have the InContainer component that has the ā€˜containerā€™ Iā€™m interested in.

It works fine. I do this all the time.

1 Like

That was my misunderstanding. It is an ā€œandā€ filter for Component, not an ā€œorā€ (I thought that having at least one would suffice)