void createNPC(UBYTE index, EntityType type){ fixed r; UBYTE spriteIndex = (index + 1) << 1; EntityData *npc = &(npc_data[index]); npc_counts[npc->type]++; //TODO: figure out why this doesn't work??!? //npc->type = type; //place at a random location off-screen r.w = rand(); if (r.b.l & 1){ npc->position.x.b.h = r.b.l << 4; npc->position.y.b.h = (r.b.l % 96) + 160; } else { npc->position.x.b.h = (r.b.l % 80) + 168; npc->position.y.b.h = r.b.l << 4; } //TEMP start with random speed r.w = rand(); //first 3 for x speed npc->speed.x.w = (r.b.l & 0x7) - 3;//(-3,4) r.w = r.w >> 2; //another 3 for y speed (speeds share a bit) npc->speed.y.w = (r.b.l & 0x7) - 3;//(-3,4) r.w = r.w >> 2; //initialize sprite tile reference register //make sure sprite is in front of background set_sprite_prop(spriteIndex, 0); set_sprite_prop(spriteIndex + 1, 0); //this is done inside npc_setVisibility, no need to do it twice right? //tileSprite(spriteIndex, entity_tiles_ref[npc->type][0], npc->type); placeSprite(spriteIndex, npc); //last 4 for randomizing animation start point (nice-to-have) npc->animFrame = 0;//r.b.l & (entity_anim_frames[type] - 1); npc_setVisibility(npc, spriteIndex); }
uint16 Screen::drawSprite(uint16 flexIndex, int16 x, int16 y) { return placeSprite(_channelsUsedCount + 1, flexIndex, x, y); }
void npc_update(){ UBYTE i, j, prev_frame, is_player_speed_negative; EntityData *npc; for( i=0, j=2; i != MAX_NUM_NPC; i++, j+=2){ npc = &(npc_data[i]); //move based on the player's and NPCs speed npc->position.x.w = npc->position.x.w + npc->speed.x.w - player_data.speed.x.w; npc->position.y.w = npc->position.y.w + npc->speed.y.w - player_data.speed.y.w; //animate dying sprites, whether they are visible or not if (npc->dying){ prev_frame = npc->animFrame; animate(j, npc); //if we looped back to frame 0 // the cell is now officially dead if (prev_frame && !(npc->animFrame)){ npc->dying = 0; //now one fewer skin cell npc_counts[SKIN]--; //if that was the last skin cell, start the endgame! if (!npc_counts[SKIN]){ npc_data[i].type = NEURON; //force it to another position //TODO: beware, this could mess some stuff up npc_data[i].position.z = i & 3; if (npc_data[i].position.z == player_data.position.z){ npc_data[i].position.z++; } createNPC(i, npc_data[i].type); //hopefuly just setting visibility is enough npc_setVisibility(&(npc_data[i]), j); } else { //randomly create another SKIN or IMMUNE cell npc_data[i].type = ((UBYTE)rand()) & 1; //visibility won't change since z-placement won't change createNPC(i, npc_data[i].type); } } else { //keep the sprite moving placeSprite(j, npc); } } else if (npc->visibility != NONE){ if (player_checkCollision(npc)){ switch (npc->type){ case NEURON: screen_data.state = WIN; return; case IMMUNE: screen_data.state = LOSE; return; case SKIN: //cut the player's speed in half is_player_speed_negative = (player_data.speed.x.b.h & 0x80U); player_data.speed.x.w = player_data.speed.x.w >> 1; if (is_player_speed_negative){ player_data.speed.x.b.h = player_data.speed.x.b.h | 0x80U; } is_player_speed_negative = (player_data.speed.y.b.h & 0x80U); player_data.speed.y.w = player_data.speed.y.w >> 1; if (is_player_speed_negative){ player_data.speed.y.b.h = player_data.speed.y.b.h | 0x80U; } npc->dying = 1; //0th frame matches last frame to avoid flicker at end of animation npc->animFrame = 1; } } placeSprite(j, npc); animate(j, npc); } } }
void LuaProxy::Graphics::placeSprite(int type, const LuaProxy::Graphics::LuaImageResource& img, int xPos, int yPos) { placeSprite(type, img.img, xPos, yPos, ""); }
void LuaProxy::Graphics::placeSprite(int type, const LuaProxy::Graphics::LuaImageResource& img, int xPos, int yPos, const std::string& extra) { placeSprite(type, img.img, xPos, yPos, extra, 0); }
void LuaProxy::Graphics::placeSprite(int type, int imgResource, int xPos, int yPos) { placeSprite(type, imgResource, xPos, yPos, ""); }
void LuaProxy::Graphics::placeSprite(int type, int imgResource, int xPos, int yPos, const std::string& extra) { placeSprite(type, imgResource, xPos, yPos, extra, 0); }