//Enemies //RPG 0.97 Enemy Functions: //Move contents of RPG_NPCs to this? //Or make NPCs_Friendly.zlib //Enemy Misc Attributes const int MISC_HP_READ = 5; //NPC Misc Attribute; const int MISC_HP = 8; const int MISC_HP_MAX = 9; const int DIETYPE_ENEMY_HP = 8; int EnemyHP[4096]; //Intentionally large size, as we're storing in-game pointers. const int DAMAGE_VALUE_DURATION = 70; const int DAMAGE_VALUE_OPACITY = 100; const int DAMAGE_VALUE_COLOUR = 120; //155, Ruby (13), gARNET (150), 191 (PINK), 190 (MAUVE PINK), 188 (GREY) //155 is decent for green. const int DAMAGE_VALUE_COLOUR_HEAL = 157; //88 Med Blue, tURQUOISE (181) 155/157 LT GREEN; 150,151,152 REDS; 56/58 mauve, 57 salmon; 59 yellow const int DAMAGE_VALUE_COLOUR_OUTLINE = 10; const int DAMAGE_VALUE_LAYER = 7; const int DAMAGE_VALUE_OUTLINE_LAYER = 6; const int DAMAGE_VALUE_X_OFFSET = 12; const int DAMAGE_VALUE_Y_OFFSET = 12; const int DAMAGE_VALUE_FONT = 2; //Small Z3 font (2), LA (16). const int DAMAGE_VALUE_SIZE = 16; const int DAMAGE_VALUE_BG_COLOUR = -1; //Transparent. const int DAMAGE_VALUE_FLOATING_POINT_PLACES = 0; void RollEnemyHP(int dietype){ int curHP; int newHP; npc enem; for ( int q = 0; q < NumberOfNPCs(); q++ ){ enem = Screen->LoadNPC(q); curHP = enem->HP; newHP = Roll(curHP,dietype); if ( enem->Misc[MISC_HP_READ] == 0 ){ enem->Misc[MISC_HP_READ] = 1; enem->HP = newHP; } } } void EnemySetup(){ RollEnemyHP(DIETYPE_ENEMY_HP); //DrawEnemyDamage(); //Other enem setup functions. } void StoreEnemyHP(){ for ( int q = 1; q < NumberOfNPCs(); q++ ){ npc r = Screen->LoadNPC(q); int curHP = r->HP; if ( r->Misc[MISC_HP] == 0 ) { r->Misc[MISC_HP] = curHP; } if ( r->Misc[MISC_HP_MAX] == 0 ) { r->Misc[MISC_HP_MAX] = curHP; } } } //This function is designed to draw numeric values representing the damage an enemy took per hit. It should run immediately prior to Waitdraw(), after StoreEnemyHP(). //X and Y offset are how far from the enemy to draw the numbers. //The function will NOT draw damage if an enemiy DIES! It will draw only if the enemy remains alive after being damaged! //A message string on-screen will cause a glitch, displaying the last diff value at pos x0/y0, if it appears immediately after an enemy dies. //We need to give messages one pre-frame, with a Waitframes(1) on the message functions, to allow this to clear. void DrawDamage(int showFor, int thisLayer, int xOffset, int yOffset, int useFont, int damageColour, int healColour, int bgColour, int widthPX, int heightPX, int floatingPlaces, int opacity, bool outline, int outlineLayer, int outlineColour){ //Place after Waitdraw() ? for ( int q = 1; q < NumberOfNPCs(); q++ ){ npc r = Screen->LoadNPC(q); int curHP = r->HP; int npcX; int npcY; int drawX; int drawY; if ( r->Misc[MISC_HP] != 0 ){ int oldHP = r->Misc[MISC_HP]; curHP = r->HP; int diff = oldHP - curHP; if ( diff > 0 ){ npcX = r->X; npcY = r->Y; drawX = npcX + xOffset; drawY = npcY + yOffset; int newDif = oldHP - r->HP; if ( diff < r->Misc[MISC_HP_MAX] ) { for ( int w = showFor; w > 0; w-- ) { if ( diff < 0 ) { break; } npcX = r->X; drawX = npcX + xOffset; npcY = r->Y; drawY = npcY + yOffset; newDif = curHP - r->HP; //Try fonts: Z3 Small (2) if ( outline ){ Screen->DrawInteger(outlineLayer, drawX+1, drawY+1, useFont, outlineColour, -1, widthPX, heightPX, diff, floatingPlaces, opacity); //Screen->DrawInteger(outlineLayer, drawX-1, drawY-1, useFont, outlineColour, -1, widthPX, heightPX, diff, floatingPlaces, opacity); } Screen->DrawInteger(thisLayer, drawX, drawY, useFont, damageColour, -1, widthPX, heightPX, diff, floatingPlaces, opacity); if ( newDif != 0 && diff != newDif ) { diff = newDif; //break; } if ( diff < 0 ) { break; } curHP = r->HP; Waitframe(); } } r->Misc[MISC_HP] = r->HP; } else if ( diff < 0 ){ npcX = r->X; npcY = r->Y; drawX = npcX + xOffset; drawY = npcY + yOffset; if ( diff < r->Misc[MISC_HP_MAX] ) { for ( int w = showFor; w > 0; w-- ) { npcX = r->X; drawX = npcX + xOffset; npcY = r->Y; drawY = npcY + yOffset; //Try fonts: Z3 Small (2) if ( outline ){ Screen->DrawInteger(outlineLayer, drawX+1, drawY+1, useFont, outlineColour, -1, widthPX, heightPX, diff, floatingPlaces, opacity); } Screen->DrawInteger(thisLayer, drawX, drawY, useFont, healColour, -1, widthPX, heightPX, diff, floatingPlaces, opacity); Waitframe(); } } r->Misc[MISC_HP] = r->HP; } } } } //Do segmented enemy heads/main body segments have different npc->IDs than their daughter components? //If so, assign the x/y coords to the main part, after locating it with list arrays. //List constants for enemy types for segmented enemies, and constants for their tiles: const int ENEM_LANMOLA_ID = 0; //We need this to be its own list...? const int ENEM_LANMOLA_CORE_TILE = 0; const int ENEM_LANMOLA_SEGMENT_TILE = 0; const int ENEM_GLEEOK_ID = 0; //We need this to be its own list...? const int ENEM_GLEEOK_CORE_TILE = 0; const int ENEM_GLEEOK_SEGMENT_TILE = 0; const int ENEM_GLEEOK_HEAD_TILE = 0; const int ENEM_MOLDORM_ID = 0; const int ENEM_MOLDORM_SEGMENT_TILE = 0; const int ENEM_MOLDORM_CORE_TILE = 0; //Store tiles for segmented enemies in an array: int SegmentedEnemyIDs[]={0}; int SegmentedEnemyTiles[]={0}; //Track the core of these enemies by determining first if an enemy is a segmented type, using SegmentedEnemyIDs[] //then if so, determine which ID it truly has, and use this to point to the SegmentedEnemyTiles[] array at the correct //index, and find the core. Then, display effects only on the core. //Store the core tile in the enemy->Misc[MISC_CORE] attribute, and use that in the DrawDamage[] function to //generate X/Y coordinates. //if ( e->Misc[MISC_CORE] != 0 ) { // npcX = ( enem->Tile ??? How do we read only a specific tile for that enemy, in this instance and prevent conflicts?