Issues with element I'm coding in.

  • 4D4850
    17th Aug 2021 Member 0 Permalink

    The specific issue is that this code (code for e+, the positron) is deleting stuff it shouldn't be deleting when it comes in contact with ELEC:

     

     
    static int update(UPDATE_FUNC_ARGS);
    static int graphics(GRAPHICS_FUNC_ARGS);
    static void create(ELEMENT_CREATE_FUNC_ARGS);
     
    void Element::Element_EPLUS()
    {
    Identifier = "DEFAULT_PT_EPLUS";
    Name = "e+";
    Colour = PIXPACK(0xDFEFFF);
    MenuVisible = 1;
    MenuSection = SC_NUCLEAR;
    Enabled = 1;
     
    Advection = 0.0f;
    AirDrag = 0.00f * CFDS;
    AirLoss = 1.00f;
    Loss = 1.00f;
    Collision = -0.99f;
    Gravity = 0.0f;
    Diffusion = 0.00f;
    HotAir = 0.000f * CFDS;
    Falldown = 0;
     
    Flammable = 0;
    Explosive = 0;
    Meltable = 0;
    Hardness = 0;
     
    Weight = -1;
     
    DefaultProperties.temp = R_TEMP + 200.0f + 273.15f;
    HeatConduct = 251;
    Description = "Positrons. React violently with electrons";
     
    Properties = TYPE_ENERGY|PROP_LIFE_DEC|PROP_LIFE_KILL_DEC;
     
    LowPressure = IPL;
    LowPressureTransition = NT;
    HighPressure = IPH;
    HighPressureTransition = NT;
    LowTemperature = ITL;
    LowTemperatureTransition = NT;
    HighTemperature = ITH;
    HighTemperatureTransition = NT;
     
    Update = &update;
    Graphics = &graphics;
    Create = &create;
    }
     
    static int update(UPDATE_FUNC_ARGS)
    {
    int r, rt, rx, ry, nb, rrx, rry;
    for (rx=-2; rx<=2; rx++)
    for (ry=-2; ry<=2; ry++)
    if (BOUNDS_CHECK) {
    r = pmap[y+ry][x+rx];
    if (!r)
    r = sim->photons[y+ry][x+rx];
    if (!r)
    continue;
    rt = TYP(r);
    switch (rt)
    {
    case PT_ELEC:
    if (rt!=PT_AMTR && rt!=PT_DMND && rt!=PT_CLNE && rt!=PT_PCLN && rt!=PT_VOID && rt!=PT_BHOL && rt!=PT_NBHL && rt!=PT_PRTI && rt!=PT_PRTO)
    {
    int r, rx, ry, rt;
    for (rx=-1; rx<2; rx++)
    for (ry=-1; ry<2; ry++)
    if (BOUNDS_CHECK && (rx || ry))
    {
    r = pmap[y+ry][x+rx];
    if (!r)
    continue;
    rt = TYP(r);
    parts[i].life++;
    if (parts[i].life==4)
    {
    sim->kill_part(i);
    return 1;
    }
     
    sim->create_part(ID(r), x+rx, y+ry, PT_PHOT);
     
    sim->kill_part(ID(r));
    sim->pv[y/CELL][x/CELL] += 10.0f;
    }
    }
    break;
    case PT_EXOT:
    parts[ID(r)].tmp2 += 5;
    parts[ID(r)].life = 1000;
    break;
    default:
    parts[ID(r)].temp +=50;
    parts[i].temp += 50;
    break;
     
    }
    }
    return 0;
    }
     
    static int graphics(GRAPHICS_FUNC_ARGS)
    {
    *firea = 70;
    *firer = *colr;
    *fireg = *colg;
    *fireb = *colb;
     
    *pixel_mode |= FIRE_ADD;
    return 0;
    }
     
    static void create(ELEMENT_CREATE_FUNC_ARGS)
    {
    float a = RNG::Ref().between(0, 359) * 3.14159f / 180.0f;
    sim->parts[i].life = 680;
    sim->parts[i].vx = 2.0f * cosf(a);
    sim->parts[i].vy = 2.0f * sinf(a);

    }

    #include "simulation/ElementCommon.h"

     

     

    The code works how I want it to, except when e+ annihilates with ELEC, it will destroy stuff surrounding it as well, despite the checks I added. The code in a more readable format is at https://github.com/4D4850/The-Powder-Toy/blob/master/src/simulation/elements/EPLUS.cpp

     

    Apologies if I made any dumb mistakes. I do hope to eventually help with development of TPT, but that is evidentally very far off.

     

    (Also, ignore the issue I posted that AMTR may live forever. I think I fixed that.)

  • jacob1
    18th Aug 2021 Developer 0 Permalink
    I do see a few issues, one causing the particle deletion, also another likely bug that you haven't noticed.

    First, you are checking (in the switch) if rt equal PT_ELEC. You then immediately check this:
    if (rt!=PT_AMTR && rt!=PT_DMND && rt!=PT_CLNE && rt!=PT_PCLN && rt!=PT_VOID && rt!=PT_BHOL && rt!=PT_NBHL && rt!=PT_PRTI && rt!=PT_PRTO)
    but it's already been established that rt is PT_ELEC. I think this is a bug and you meant to put it in the inner for loop.

    Anyway, inside the inner for loop you increase life by 1 for every particle found (until it gets to .life = 4). So the first 4 particles will have a reaction occur, that will delete them, because of these two lines:
    sim->create_part(ID(r), x+rx, y+ry, PT_PHOT);
    sim->kill_part(ID(r));
    The create_part is telling it to reuse particle r and create a PHOT at that position. so whatever particle r was in the inner loop, has now been changed to PHOT. If you meant to create a new particle, use -1 instead of ID(r).
    Then the next line immediately kills the particle you just changed to PHOT.

    Based on this code, it seems like deleting the particles surrounding the ELEC, or changing them into PHOT, is the intended effect. But since it's not, you'll have to fix the logic, hopefully I explained it well enough that you can understand the problems.
  • 4D4850
    18th Aug 2021 Member 0 Permalink

    Right. Sorry, I had copied the code from AMTR and forgot to change that. The check was to see  if I could stop it with that to make it at least not destroy those. Thank you for the feedback!

    Edited once by 4D4850. Last: 18th Aug 2021