void display_ents()
{
unsigned f;
int i, z, wall = 0, wall2;
entity *e = NULL;
entity *other = NULL;
int qx, qy, sy, sz, alty;
int sortid;
float temp1, temp2;
int useshadow = 0;
int can_mirror = 0;
int shadowz;
s_drawmethod *drawmethod = NULL;
s_drawmethod commonmethod;
s_drawmethod shadowmethod;
int use_mirror = (level && level->mirror);
int o_scrx = screenx, o_scry = screeny, scrx, scry;
if(level)
{
shadowz = SHADOW_Z;
}
else
{
shadowz = MIN_INT + 100;
}
for(i = 0; i < ent_max; i++)
{
if(ent_list[i] && ent_list[i]->exists)
{
e = ent_list[i];
if(Script_IsInitialized(e->scripts->ondraw_script))
{
ent_stack[ent_stack_size++] = e;
}
//if(!e->exists) continue; // just in case kill is called in the script
if(e->modeldata.hpbarstatus.size.x)
{
drawenemystatus(e);
}
sortid = e->sortid;
scrx = o_scrx - ((e->modeldata.noquake & NO_QUAKEN) ? 0 : gfx_x_offset);
scry = o_scry - ((e->modeldata.noquake & NO_QUAKEN) ? 0 : gfx_y_offset);
if(freezeall || !(e->blink && (time % (GAME_SPEED / 10)) < (GAME_SPEED / 20)))
{
// If special is being executed, display all entities regardless
f = e->animation->sprite[e->animpos];
other = check_platform(e->position.x, e->position.z, e);
wall = checkwall(e->position.x, e->position.z);
if(f < sprites_loaded)
{
// var "z" takes into account whether it has a setlayer set, whether there are other entities on
// the same "z", in which case there is a layer offset, whether the entity is on an obstacle, and
// whether the entity is grabbing someone and has grabback set
z = (int)e->position.z; // Set the layer offset
if(e->binding.ent)
{
sortid = e->binding.ent->sortid - 1;
}
if(e->grabbing && e->modeldata.grabback)
{
z--;
sortid = e->link->sortid - 1; // Grab animation displayed behind
}
else if(!e->modeldata.grabback && e->grabbing)
{
z++;
sortid = e->link->sortid + 1;
}
/*
if(e->binding.ent && e->binding.ent->grabbing==e)
{
if(e->binding.ent->modeldata.grabback) z--;
else z++;
}
*/
if(other && e->position.y >= other->position.y + other->animation->platform[other->animpos][7] && !other->modeldata.setlayer)
{
if(
e->link &&
((e->modeldata.grabback && !e->grabbing) ||
(e->link->modeldata.grabback && e->link->grabbing) ||
e->grabbing)
)
{
z = (int)(other->position.z + 2); // Make sure entities get displayed in front of obstacle and grabbee
}
else
{
z = (int)(other->position.z + 1); // Entity should always display in front of the obstacle
}
}
if(e->owner)
{
sortid = e->owner->sortid + 1; // Always in front
}
if(e->modeldata.setlayer)
{
z = HOLE_Z + e->modeldata.setlayer; // Setlayer takes precedence
}
//UT: commented this out, it seems to be some legacy code, ==2 doesn't make sense anymore
//if(checkhole(e->position.x, e->position.z)==2) z = PANEL_Z-1; // place behind panels
drawmethod = e->animation->drawmethods ? getDrawMethod(e->animation, e->animpos) : NULL;
//drawmethod = e->animation->drawmethods?e->animation->drawmethods[e->animpos]:NULL;
if(e->drawmethod.flag)
{
drawmethod = &(e->drawmethod);
}
if(!drawmethod)
{
commonmethod = plainmethod;
}
else
{
commonmethod = *drawmethod;
}
drawmethod = &commonmethod;
if(e->modeldata.alpha >= 1 && e->modeldata.alpha <= MAX_BLENDINGS)
{
if(drawmethod->alpha < 0)
{
drawmethod->alpha = e->modeldata.alpha;
}
}
if(!drawmethod->table)
{
if(drawmethod->remap >= 1 && drawmethod->remap <= e->modeldata.maps_loaded)
{
drawmethod->table = model_get_colourmap(&(e->modeldata), drawmethod->remap);
}
if(e->colourmap)
{
if(drawmethod->remap < 0)
{
drawmethod->table = e->colourmap;
}
}
if(!drawmethod->table)
{
drawmethod->table = e->modeldata.palette;
}
if(e->modeldata.globalmap)
{
if(level && current_palette)
{
drawmethod->table = level->palettes[current_palette - 1];
}
else
{
drawmethod->table = pal;
}
}
}
if(e->dying) // Code for doing dying flash
{
if((e->health <= e->per1 && e->health > e->per2 && (time % (GAME_SPEED / 5)) < (GAME_SPEED / 10)) ||
(e->health <= e->per2 && (time % (GAME_SPEED / 10)) < (GAME_SPEED / 20)))
{
if(e->health > 0 )
{
drawmethod->table = model_get_colourmap(&(e->modeldata), e->dying);
}
}
}
if(e->direction == DIRECTION_LEFT)
{
drawmethod->flipx = !drawmethod->flipx;
if(drawmethod->fliprotate && drawmethod->rotate)
{
drawmethod->rotate = 360 - drawmethod->rotate;
}
}
if(!use_mirror || z > MIRROR_Z) // don't display if behind the mirror
{
//just a simple check, doesn't work with mirror nor gfxshadow
if(drawmethod->clipw)
{
drawmethod->clipx += (int)(e->position.x - scrx);
drawmethod->clipy += (int)(e->position.z - e->position.y - scry);
}
spriteq_add_sprite((int)(e->position.x - scrx), (int)(e->position.z - e->position.y - scry), z, f, drawmethod, sortid);
}
can_mirror = (use_mirror && self->position.z > MIRROR_Z);
if(can_mirror)
{
spriteq_add_sprite((int)(e->position.x - scrx), (int)((2 * MIRROR_Z - e->position.z) - e->position.y - scry), 2 * PANEL_Z - z , f, drawmethod, ent_list_size * 100 - sortid);
}
}//end of if(f<sprites_loaded)
if(e->modeldata.gfxshadow == 1 && f < sprites_loaded) //gfx shadow
{
useshadow = (e->animation->shadow ? e->animation->shadow[e->animpos] : 1) && shadowcolor && light.y;
//printf("\n %d, %d, %d\n", shadowcolor, light.x, light.y);
if(useshadow && e->position.y >= 0 && (!e->modeldata.aironly || (e->modeldata.aironly && inair(e))))
{
wall = checkwall_below(e->position.x, e->position.z, e->position.y);
if(wall < 0)
{
alty = (int)e->position.y;
temp1 = -1 * e->position.y * light.x / 256; // xshift
temp2 = (float)(-alty * light.y / 256); // zshift
qx = (int)(e->position.x - scrx/* + temp1*/);
qy = (int)(e->position.z - scry/* + temp2*/);
}
else
{
alty = (int)(e->position.y - level->walls[wall].height);
temp1 = -1 * (e->position.y - level->walls[wall].height) * light.x / 256; // xshift
temp2 = (float)(-alty * light.y / 256); // zshift
qx = (int)(e->position.x - scrx/* + temp1*/);
qy = (int)(e->position.z - scry /*+ temp2*/ - level->walls[wall].height);
}
wall2 = checkwall_below(e->position.x + temp1, e->position.z + temp2, e->position.y); // check if the shadow drop into a hole or fall on another wall
//TODO check platforms, don't want to go through the entity list again right now
if(!(checkhole(e->position.x + temp1, e->position.z + temp2) && wall2 < 0 && !other) ) //&& !(wall>=0 && level->walls[wall].height>e->position.y))
{
if(wall >= 0 && wall2 >= 0)
{
alty += (int)(level->walls[wall].height - level->walls[wall2].height);
/*qx += -1*(level->walls[wall].height-level->walls[wall2].height)*light.x/256;
qy += (level->walls[wall].height-level->walls[wall2].height) - (level->walls[wall].height-level->walls[wall2].height)*light.y/256;*/
}
else if(wall >= 0)
{
alty += (int)(level->walls[wall].height);
/*qx += -1*level->walls[wall].height*light.x/256;
qy += level->walls[wall].height - level->walls[wall].height*light.y/256;*/
}
else if(wall2 >= 0)
{
alty -= (int)(level->walls[wall2].height);
/*qx -= -1*level->walls[wall2].height*light.x/256;
qy -= level->walls[wall2].height - level->walls[wall2].height*light.y/256;*/
}
sy = (2 * MIRROR_Z - qy) - 2 * scry;
z = shadowz;
sz = PANEL_Z - HUD_Z;
if(e->animation->shadow_coords)
{
if(e->direction == DIRECTION_RIGHT)
{
qx += e->animation->shadow_coords[e->animpos][0];
}
else
{
qx -= e->animation->shadow_coords[e->animpos][0];
}
qy += e->animation->shadow_coords[e->animpos][1];
sy -= e->animation->shadow_coords[e->animpos][1];
}
shadowmethod = plainmethod;
shadowmethod.fillcolor = (shadowcolor > 0 ? shadowcolor : 0);
shadowmethod.alpha = shadowalpha;
shadowmethod.table = drawmethod->table;
shadowmethod.scalex = drawmethod->scalex;
shadowmethod.flipx = drawmethod->flipx;
shadowmethod.scaley = light.y * drawmethod->scaley / 256;
shadowmethod.flipy = drawmethod->flipy;
shadowmethod.centery += alty;
if(shadowmethod.flipy)
{
shadowmethod.centery = -shadowmethod.centery;
}
if(shadowmethod.scaley < 0)
{
shadowmethod.scaley = -shadowmethod.scaley;
shadowmethod.flipy = !shadowmethod.flipy;
}
shadowmethod.rotate = drawmethod->rotate;
shadowmethod.shiftx = drawmethod->shiftx + light.x;
spriteq_add_sprite(qx, qy, z, f, &shadowmethod, 0);
if(use_mirror)
{
shadowmethod.flipy = !shadowmethod.flipy;
shadowmethod.centery = -shadowmethod.centery;
spriteq_add_sprite(qx, sy, sz, f, &shadowmethod, 0);
}
}
}//end of gfxshadow
}
else //plain shadow
{
useshadow = e->animation->shadow ? e->animation->shadow[e->animpos] : e->modeldata.shadow;
if(useshadow < 0)
{
useshadow = e->modeldata.shadow;
}
if(useshadow && e->position.y >= 0 && !(checkhole(e->position.x, e->position.z) && checkwall_below(e->position.x, e->position.z, e->position.y) < 0) && (!e->modeldata.aironly || (e->modeldata.aironly && inair(e))))
{
if(other && other != e && e->position.y >= other->position.y + other->animation->platform[other->animpos][7])
{
qx = (int)(e->position.x - scrx);
qy = (int)(e->position.z - other->position.y - other->animation->platform[other->animpos][7] - scry);
sy = (int)((2 * MIRROR_Z - e->position.z) - other->position.y - other->animation->platform[other->animpos][7] - scry);
z = (int)(other->position.z + 1);
sz = 2 * PANEL_Z - z;
}
else if(level && wall >= 0)// && e->position.y >= level->walls[wall].height)
{
qx = (int)(e->position.x - scrx);
qy = (int)(e->position.z - level->walls[wall].height - scry);
sy = (int)((2 * MIRROR_Z - e->position.z) - level->walls[wall].height - scry);
z = shadowz;
sz = PANEL_Z - HUD_Z;
}
else
{
qx = (int)(e->position.x - scrx);
qy = (int)(e->position.z - scry);
sy = (int)((2 * MIRROR_Z - e->position.z) - scry);
z = shadowz;
sz = PANEL_Z - HUD_Z;
}
if(e->animation->shadow_coords)
{
if(e->direction == DIRECTION_RIGHT)
{
qx += e->animation->shadow_coords[e->animpos][0];
}
else
{
qx -= e->animation->shadow_coords[e->animpos][0];
}
qy += e->animation->shadow_coords[e->animpos][1];
sy -= e->animation->shadow_coords[e->animpos][1];
}
shadowmethod = plainmethod;
shadowmethod.alpha = BLEND_MULTIPLY + 1;
shadowmethod.flipx = !e->direction;
spriteq_add_sprite(qx, qy, z, shadowsprites[useshadow - 1], &shadowmethod, 0);
if(use_mirror)
{
spriteq_add_sprite(qx, sy, sz, shadowsprites[useshadow - 1], &shadowmethod, 0);
}
}//end of plan shadow
}
}// end of blink checking
if(e->arrowon) // Display the players image while invincible to indicate player number
{
if(e->modeldata.parrow[(int)e->playerindex][0] && e->invincible == 1)
{
spriteq_add_sprite((int)(e->position.x - scrx + e->modeldata.parrow[(int)e->playerindex][1]), (int)(e->position.z - e->position.y - scry + e->modeldata.parrow[(int)e->playerindex][2]), (int)e->position.z, e->modeldata.parrow[(int)e->playerindex][0], NULL, sortid * 2);
}
}
}// end of if(ent_list[i]->exists)
}// end of for
//defer ondraw script so it can manage spriteq better
for(i = 0; i < ent_stack_size; i++)
{
execute_ondraw_script(ent_stack[i]);
}
ent_stack_size = 0;
}