/////////////////////////// // RPG-esque HP Display // // v0.7 // // 19th August, 2020 // // For ZC 2.55 Alpha 80+ // // By: ZoriaRPG // /////////////////////////// namespace hphealth { const int TEMPLIFESPAN_SPRITE = 1; enum colourtype { cNONE, cWHITE, cGREY, cBLUE, cRED = 0x81 }; const int OLDHP_INDX = 19; const int ORIGHP_INDX = 25; //lanmola const int OLDHP_DIFF = 20; const int SPAWN_CLK = 21; const int DRAW_CLK = 22; const int INITIALISED = 23; const int SPAWNCLKDUR = 60; const int HPCLOCKDUR = 10; const int CREATEDSPR = 24; const int DMG_COLOUR = cRED; const int DMG_OUTLINE = cWHITE; const int HEAL_OUTLINE = cWHITE; const int HEAL_COLOUR = cBLUE; const int DRAW_LAYER = 6; const int XOFS = -4; const int YOFS = -4; const int DUMMY_SPRITE_ID = 255; const int DUMMY_SPRITE_OTILE = 214240; const int DUMMY_SPRITE_FRAMES = 1; const int DUMMY_SPRITE_SPD = 16; const int DUMMY_AMOUNT = 30; void init_dummy_sprite() { spritedata sd = Game->LoadSpriteData(DUMMY_SPRITE_ID); sd->Tile = DUMMY_SPRITE_OTILE; sd->Frames = DUMMY_SPRITE_FRAMES; sd->Speed = DUMMY_SPRITE_SPD; } global script test { void run() { init_dummy_sprite(); while(1) { for ( int q = Screen->NumNPCs(); q > 0; --q ) { npc n = Screen->LoadNPC(q); init_enemy_hp(n); do_npc_hp_clock(n); update_npc_hp(n); draw_npc_hp_change(n); } //draw_floating_damage(); init_hero_hp(); do_hero_hp_clock(); update_hero_hp(); draw_hero_hp_change(); Waitdraw(); //for ( int q = Screen->NumNPCs(); q > 0; --q ) //{ // npc n = Screen->LoadNPC(q); // update_lanmola_hp(n); //} Waitframe(); } } } void do_npc_hp_clock(npc n) { ++n->Misc[SPAWN_CLK]; } void init_enemy_hp(npc n) { unless ( n->Misc[INITIALISED] ) { if ( n->Family == NPCT_LANMOLA ) { if ( n->Core ) { npcdata nd = Game->LoadNPCData(n->ID); n->Misc[OLDHP_INDX] = nd->HP*nd->Attributes[0]+1; //the spawned enemy has +1 n->Misc[INITIALISED] = 1; n->Misc[ORIGHP_INDX] = nd->HP*nd->Attributes[0]-(nd->HP-1); //printf("n->Misc[ORIGHP_INDX]: %d\n", n->Misc[ORIGHP_INDX]); //printf("Lanmola core hp: %d\n",n->Misc[OLDHP_INDX]); } } else { n->Misc[OLDHP_INDX] = n->HP; n->Misc[INITIALISED] = 1; } } } int get_lanmola_hp(npc n) { //if ( n->Misc[DRAW_CLK] ) return; if ( n->Family == NPCT_LANMOLA ) //update every frame because of engine stupidity { int totalhp; if ( n->Core ) { totalhp = n->HP; int count; //find its chilren for ( int w = Screen->NumNPCs(); w > 0; --w ) { npc child = Screen->LoadNPC(w); if ( child->ParentUID == n->UID ) //it is a child of this core { ++count; totalhp += child->HP; } } return totalhp; } } } void update_npc_hp(npc n) { { if ( n->Family != NPCT_GLEEOK && n->Misc[DRAW_CLK] == 0 && (n->HitBy[2] || n->Family == NPCT_MOLDORM ) && n->HP != n->Misc[OLDHP_INDX] ) { n->Misc[OLDHP_DIFF] = n->HP - n->Misc[OLDHP_INDX]; n->Misc[DRAW_CLK] = HPCLOCKDUR; } else if ( (n->Family == NPCT_GLEEOK && n->Core) && n->HP != n->Misc[OLDHP_INDX] && n->Misc[DRAW_CLK] == 0 ) { n->Misc[OLDHP_DIFF] = n->HP - n->Misc[OLDHP_INDX]; n->Misc[DRAW_CLK] = HPCLOCKDUR; } else if ( n->Family == NPCT_LANMOLA && n->Core && n->Misc[DRAW_CLK] == 0 ) ////&& n->HP != n->Misc[OLDHP_INDX] { int totalhp; { totalhp = n->HP; int count; //find its chilren for ( int w = Screen->NumNPCs(); w > 0; --w ) { npc child = Screen->LoadNPC(w); if ( child->ParentUID == n->UID ) //it is a child of this core { ++count; totalhp += child->HP; } } //printf("count of segment children is: %d\n", count); //printf("total HP of lanmola: %d\n", totalhp); //printf("n->Misc[SPAWN_CLK]: %d\n", n->Misc[SPAWN_CLK]); //printf("n->Misc[OLDHP_INDX]: %d\n", n->Misc[OLDHP_INDX]); //printf("n->Misc[CFHP_INDX]: %d\n", n->Misc[CFHP_INDX]); if ( totalhp != n->Misc[OLDHP_INDX] ) { int dif = totalhp - n->Misc[OLDHP_INDX]; //printf("dif is %d\n", dif); if ( dif != (n->Misc[ORIGHP_INDX]*-1) ) //quirk of lanmola spawn { n->Misc[OLDHP_DIFF] = dif; n->Misc[DRAW_CLK] = HPCLOCKDUR; } //n->Misc[OLDHP_INDX] = totalhp; } //else //{ // printf("Equal\n"); // n->Misc[OLDHP_INDX] = totalhp; // n->Misc[OLDHP_DIFF] = 0; //} } } } } /*void draw_floating_damage() { for ( int q = Screen->NumLWeapons(); q > 0; --q ) { lweapon t = Screen->LoadLWeapon(q); if ( t->ID == LW_SPARKLE && t->Misc[IS_DUMMMY_SPR] ) { t->Script = Game->GetLWeaponScript("damagedisplay"); } } }*/ lweapon script damagedisplay { void run() { //printf("Starting damagedisplay\n"); int buffer[8]; int buffer2[8]; itoa(buffer,this->Misc[DUMMY_AMOUNT]); if ( this->Misc[DUMMY_AMOUNT] > 0 ) { buffer2[0] = '+'; } strcat(buffer2, buffer); while(1) { //printf("Drawing damagedisplay\n"); Screen->DrawString ( DRAW_LAYER, this->X, this->Y, FONT_Z3SMALL, ((this->Misc[DUMMY_AMOUNT]<0) ? DMG_COLOUR : HEAL_COLOUR), -1, 0, buffer2, 128, SHD_OUTLINED8, ((this->Misc[DUMMY_AMOUNT]<0) ? DMG_OUTLINE : HEAL_OUTLINE) ); Waitframe(); } } } void draw_npc_hp_change(npc n) { if ( n->Misc[SPAWN_CLK] < SPAWNCLKDUR ) return; if ( n->Family == NPCT_LANMOLA && n->Misc[OLDHP_DIFF] > 0 ) return; //Lanmolas juggle HP so don't show imbalances being offset. if ( --n->Misc[DRAW_CLK] > 0 && n->Misc[OLDHP_DIFF] ) { /*int buffer[8]; int buffer2[8]; itoa(buffer,n->Misc[OLDHP_DIFF]); if ( n->Misc[OLDHP_DIFF] > 0 ) { buffer2[0] = '+'; } strcat(buffer2, buffer); */ if ( TEMPLIFESPAN_SPRITE ) { int tmpx, tmpy; unless ( n->Misc[CREATEDSPR] ) { int prntuid = n->ParentUID; npc prnt = NULL; if ( prntuid ) prnt = Screen->LoadNPCByUID(n->ParentUID); if (n->Family == NPCT_MOLDORM ) { //find the core //npc prnt = Screen->LoadNPCByUID(n->ParentUID); tmpx = prnt->X; tmpy = prnt->Y; } if ( n->Family == NPCT_LANMOLA && prnt->isValid() ) { //find the core //npc prnt = Screen->LoadNPCByUID(n->ParentUID); tmpx = prnt->X; tmpy = prnt->Y; } else if ( n->Family == NPCT_GLEEOK ) { tmpx = prnt->X-12; tmpy = prnt->Y-4; } else { tmpx = n->X; tmpy = n->Y; } //printf("Creating dummy sprite.\n"); lweapon dummy = Screen->CreateLWeapon(LW_SPARKLE); dummy->X = Clamp(tmpx + XOFS,0,SCREEN_W-8); dummy->Y = Clamp(tmpy + YOFS,0,SCREEN_H-8); dummy->UseSprite(DUMMY_SPRITE_ID); dummy->HitYOffset = -32768; dummy->Misc[DUMMY_AMOUNT] = n->Misc[OLDHP_DIFF]; dummy->Script = Game->GetLWeaponScript("damagedisplay"); //printf("Game->GetLWeaponScript(damagedisplay) is: %d\n", dummy->Script); n->Misc[CREATEDSPR] = 1; } } else { int buffer[8]; int buffer2[8]; itoa(buffer,n->Misc[OLDHP_DIFF]); if ( n->Misc[OLDHP_DIFF] > 0 ) { buffer2[0] = '+'; } strcat(buffer2, buffer); Screen->DrawString ( DRAW_LAYER, n->X + XOFS, n->Y + YOFS, FONT_Z3SMALL, ((n->Misc[OLDHP_DIFF]<0) ? DMG_COLOUR : HEAL_COLOUR), -1, 0, buffer2, 128, SHD_OUTLINED8, ((n->Misc[OLDHP_DIFF]<0) ? DMG_OUTLINE : HEAL_OUTLINE) ); } } else { if ( n->Family == NPCT_LANMOLA ) { n->Misc[DRAW_CLK] = 0; n->Misc[OLDHP_INDX] = get_lanmola_hp(n); n->Misc[CREATEDSPR] = 0; } else { n->Misc[DRAW_CLK] = 0; n->Misc[OLDHP_INDX] = n->HP; n->Misc[CREATEDSPR] = 0; } } } void do_hero_hp_clock() { ++Hero->Misc[SPAWN_CLK]; } void init_hero_hp() { unless ( Hero->Misc[INITIALISED] ) { Hero->Misc[OLDHP_INDX] = Hero->HP; Hero->Misc[INITIALISED] = 1; } } void update_hero_hp() { if ( Hero->Misc[DRAW_CLK] == 0 && Hero->HP != Hero->Misc[OLDHP_INDX] ) { Hero->Misc[OLDHP_DIFF] = Hero->HP - Hero->Misc[OLDHP_INDX]; Hero->Misc[DRAW_CLK] = HPCLOCKDUR; } } void draw_hero_hp_change() { if ( --Hero->Misc[DRAW_CLK] > 0 && Hero->Misc[OLDHP_DIFF] ) { int buffer[8]; int buffer2[8]; itoa(buffer,Hero->Misc[OLDHP_DIFF]); if ( Hero->Misc[OLDHP_DIFF] > 0 ) { buffer2[0] = '+'; } strcat(buffer2, buffer); Screen->DrawString ( DRAW_LAYER, Hero->X + XOFS, Hero->Y + YOFS, FONT_Z3SMALL, ((Hero->Misc[OLDHP_DIFF]<0) ? DMG_COLOUR : HEAL_COLOUR), -1, 0, buffer2, 128, SHD_OUTLINED8, ((Hero->Misc[OLDHP_DIFF]<0) ? DMG_OUTLINE : HEAL_OUTLINE) ); } else { Hero->Misc[DRAW_CLK] = 0; Hero->Misc[OLDHP_INDX] = Hero->HP; } } }