From e97fc541791e8335564a8fcd0d098bf6deb75225 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 23 Dec 2022 19:56:39 +0100 Subject: [PATCH] - scriptified shootstuff. --- source/core/thingdef_data.cpp | 2 + source/games/duke/src/constants.h | 3 + source/games/duke/src/player_d.cpp | 107 ---------------- source/games/duke/src/player_r.cpp | 116 ------------------ .../filter/redneck/rmapinfo.spawnclasses | 2 +- wadsrc/static/zscript.txt | 1 + .../static/zscript/games/duke/actors/boss2.zs | 1 + .../zscript/games/duke/actors/controllers.zs | 1 + .../duke/actors/dukeweapons/projectiles.zs | 60 +++++++++ .../zscript/games/duke/actors/projectiles.zs | 107 ++++++++++++---- .../games/duke/actors/redneckenemies.zs | 7 ++ .../games/duke/actors/redneckenemies/vixen.zs | 48 ++++++-- wadsrc/static/zscript/games/duke/dukeactor.zs | 4 +- 13 files changed, 196 insertions(+), 263 deletions(-) create mode 100644 wadsrc/static/zscript/games/duke/actors/dukeweapons/projectiles.zs diff --git a/source/core/thingdef_data.cpp b/source/core/thingdef_data.cpp index fb0079e22..6a0f2c266 100644 --- a/source/core/thingdef_data.cpp +++ b/source/core/thingdef_data.cpp @@ -175,6 +175,8 @@ static FFlagDef DukeActorFlagDefs[] = DEFINE_FLAG(SFLAG3, NOGRAVITY, DDukeActor, flags3), DEFINE_FLAG(SFLAG3, SIMPLEINIT, DDukeActor, flags3), DEFINE_FLAG(SFLAG3, NOHITSCANHIT, DDukeActor, flags1), + DEFINE_FLAG(SFLAG3, SPECIALINIT, DDukeActor, flags3), + DEFINE_FLAG(SFLAG3, DONTLIGHTSHOOTER, DDukeActor, flags3), }; diff --git a/source/games/duke/src/constants.h b/source/games/duke/src/constants.h index 1d40758d6..a0c67a6a6 100644 --- a/source/games/duke/src/constants.h +++ b/source/games/duke/src/constants.h @@ -408,6 +408,9 @@ enum sflags3_t SFLAG3_NOGRAVITY = 0x00000040, // disables makeitfall. SFLAG3_SIMPLEINIT = 0x00000080, // Internal: skip default init stuff in DukeActor::Initialize. SFLAG3_NOHITSCANHIT = 0x00000100, // just pretend the hit never happened. RR's tornado uses it. + SFLAG3_SPECIALINIT = 0x00000200, // special aiming case for Duke's BOSS2 + SFLAG3_DONTLIGHTSHOOTER = 0x00000400, + }; using EDukeFlags3 = TFlags; diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 4a79c62e0..6eb817ebd 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -81,107 +81,6 @@ void incur_damage_d(player_struct* p) } -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -static void shootstuff(DDukeActor* actor, int p, DVector3 pos, DAngle ang, int atwith) -{ - sectortype* sect = actor->sector(); - double vel, zvel; - int scount; - - if (actor->spr.extra >= 0) actor->spr.shade = -96; - - scount = 1; - if (atwith == DTILE_SPIT) vel = 292 / 16.; - else - { - if (atwith == DTILE_COOLEXPLOSION1) - { - if (actor->spr.picnum == DTILE_BOSS2) vel = 644 / 16.; - else vel = 348 / 16.; - pos.Z -= 2; - } - else - { - vel = 840 / 16.; - pos.Z -= 2; - } - } - - if (p >= 0) - { - auto aimed = aim(actor, AUTO_AIM_ANGLE); - - if (aimed) - { - auto tex = TexMan.GetGameTexture(aimed->spr.spritetexture()); - double dal = ((aimed->spr.scale.X * tex->GetDisplayHeight()) * 0.5) - 12; - double dist = (ps[p].GetActor()->spr.pos.XY() - aimed->spr.pos.XY()).Length(); - - zvel = ((aimed->spr.pos.Z - pos.Z - dal) * vel) / dist; - ang = (aimed->spr.pos.XY() - pos.XY()).Angle(); - } - else - setFreeAimVelocity(vel, zvel, ps[p].Angles.getPitchWithView(), 49.); - } - else - { - double x; - int j = findplayer(actor, &x); - ang += DAngle22_5 / 8 - randomAngle(22.5 / 4); -#if 1 - double dist = (ps[j].GetActor()->spr.pos.XY() - actor->spr.pos.XY()).Length(); - zvel = ((ps[j].GetActor()->getPrevOffsetZ() - pos.Z + 3) * vel) / dist; -#else - // this is for pitch corrected velocity - auto dist = (ps[j].GetActor()->spr.pos - actor->spr.pos).Resized(vel); - vel = dist.XY().Length(); - zvel = dist.Z; -#endif - } - - double oldzvel = zvel; - double scale = p >= 0? 0.109375 : 0.28125; - if (atwith == DTILE_SPIT) - { - pos.Z -= 10; - } - // Whatever else was here always got overridden by the final 'p>=0' check. - - - while (scount > 0) - { - auto spawned = CreateActor(sect, pos, atwith, -127, DVector2(scale, scale), ang, vel, zvel, actor, 4); - if (!spawned) return; - spawned->spr.extra += (krand() & 7); - - if (atwith == DTILE_COOLEXPLOSION1) - { - spawned->spr.shade = 0; - if (actor->spr.picnum == DTILE_BOSS2) - { - auto ovel = spawned->vel.X; - spawned->vel.X = 64; - ssp(spawned, CLIPMASK0); - spawned->vel.X = ovel; - spawned->spr.Angles.Yaw += DAngle22_5 - randomAngle(45); - } - } - - spawned->spr.cstat = CSTAT_SPRITE_YCENTER; - spawned->clipdist = 1; - - ang = actor->spr.Angles.Yaw + DAngle22_5 / 4 - randomAngle(22.5 / 2); - zvel = oldzvel + 2 - krandf(4); - - scount--; - } -} - //--------------------------------------------------------------------------- // // @@ -389,12 +288,6 @@ void shoot_d(DDukeActor* actor, int atwith, PClass *cls) switch (atwith) { - case DTILE_FIRELASER: - case DTILE_SPIT: - case DTILE_COOLEXPLOSION1: - shootstuff(actor, p, spos, sang, atwith); - return; - case DTILE_FREEZEBLAST: spos.Z += 3; [[fallthrough]]; diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 1a7c23b86..01c4e83f9 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -83,116 +83,6 @@ void incur_damage_r(player_struct* p) // //--------------------------------------------------------------------------- -static void shootstuff(DDukeActor* actor, int p, DVector3 pos, DAngle ang, int atwith) -{ - auto sect = actor->sector(); - double vel = 0, zvel; - int scount; - - if (isRRRA()) - { - if (atwith != RTILE_SHITBALL && actor->spr.extra >= 0) actor->spr.shade = -96; - - scount = 1; - if (atwith == RTILE_SHITBALL) - { - if (actor->spr.picnum == RTILE_MAMA) - vel = 37.5; - else - vel = 25; - } - } - else - { - if (actor->spr.extra >= 0) actor->spr.shade = -96; - - scount = 1; - if (atwith == RTILE_SHITBALL) vel = 25; - } - if (atwith != RTILE_SHITBALL) - { - vel = 52.5; - pos.Z -= 4; - if (actor->spr.picnum == RTILE_HULK) - { - pos += (actor->spr.Angles.Yaw + DAngle45).ToVector() * 16; - pos.Z += 12; - } - if (actor->spr.picnum == RTILE_VIXEN) - { - pos.Z -= 12; - } - } - - if (p >= 0) - { - auto aimed = aim(actor, AUTO_AIM_ANGLE); - - pos += (actor->spr.Angles.Yaw + DAngle22_5 * 1.25).ToVector() * 16; - - if (aimed) - { - auto tex = TexMan.GetGameTexture(aimed->spr.spritetexture()); - double dal = ((aimed->spr.scale.X * tex->GetDisplayHeight()) * 0.5) - 12; - double dist = (ps[p].GetActor()->spr.pos.XY() - aimed->spr.pos.XY()).Length(); - - zvel = ((aimed->spr.pos.Z - pos.Z - dal) * vel) / dist; - ang = (aimed->spr.pos.XY() - pos.XY()).Angle(); - } - else - { - setFreeAimVelocity(vel, zvel, ps[p].Angles.getPitchWithView(), 49.); - } - } - else - { - double x; - int j = findplayer(actor, &x); - if (actor->spr.picnum == RTILE_HULK) - ang -= randomAngle(22.5 / 4); - else if (actor->spr.picnum == RTILE_VIXEN) - ang -= randomAngle(22.5 / 8); - else if (actor->spr.picnum != RTILE_UFOBEAM) - ang += DAngle22_5 / 8. - randomAngle(22.5 / 4); - - double dist = (ps[j].GetActor()->spr.pos.XY() - actor->spr.pos.XY()).Length(); - zvel = ((ps[j].GetActor()->getPrevOffsetZ() - pos.Z + 3) * vel) / dist; - } - - double oldzvel = zvel; - double scale = p >= 0? 0.109375 : atwith == RTILE_VIXENSHOT? 0.125 : 0.28125; - - if (atwith == RTILE_SHITBALL) - { - if (!isRRRA() || actor->spr.picnum != RTILE_MAMA) pos.Z -= 10; else pos.Z -= 20; - } - - while (scount > 0) - { - auto spawned = CreateActor(sect, pos, atwith, -127, DVector2(scale, scale), ang, vel, zvel, actor, 4); - if (!spawned) return; - spawned->spr.extra += (krand() & 7); - spawned->spr.cstat = CSTAT_SPRITE_YCENTER; - spawned->clipdist = 1; - - ang = actor->spr.Angles.Yaw + DAngle22_5 / 4 + randomAngle(22.5 / 2); - zvel = oldzvel + 2 - krandf(4); - - if (atwith == RTILE_FIRELASER) - { - spawned->spr.scale = DVector2(0.125, 0.125); - } - - scount--; - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - static void shootrpg(DDukeActor* actor, int p, DVector3 pos, DAngle ang, int atwith) { auto sect = actor->sector(); @@ -352,12 +242,6 @@ void shoot_r(DDukeActor* actor, int atwith, PClass* cls) switch (atwith) { - case RTILE_FIRELASER: - case RTILE_SHITBALL: - case RTILE_VIXENSHOT: - shootstuff(actor, p, spos, sang, atwith); - return; - case RTILE_RPG2: case RTILE_BOATGRENADE: if (isRRRA()) goto rrra_rpg2; diff --git a/wadsrc/static/filter/redneck/rmapinfo.spawnclasses b/wadsrc/static/filter/redneck/rmapinfo.spawnclasses index 533ac0b0f..a3c3c0772 100644 --- a/wadsrc/static/filter/redneck/rmapinfo.spawnclasses +++ b/wadsrc/static/filter/redneck/rmapinfo.spawnclasses @@ -78,7 +78,7 @@ spawnclasses 1526 = DukeBloodSplat2, noskill 1527 = DukeBloodSplat3, noskill 1528 = DukeBloodSplat4, noskill - 3420 = DukeFireLaser, noskill + 3420 = RedneckFireLaser, noskill 3471 = RedneckOWhip, noskill 3475 = RedneckUWhip, noskill 2095 = RedneckVixenShot, noskill diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 85fc3f179..78e6c7c4c 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -160,6 +160,7 @@ version "4.10" #include "zscript/games/duke/actors/dukeweapons/melee.zs" #include "zscript/games/duke/actors/dukeweapons/hitscan.zs" +#include "zscript/games/duke/actors/dukeweapons/projectiles.zs" #include "zscript/games/duke/actors/dukeweapons/shrinker.zs" #include "zscript/games/duke/actors/dukeweapons/grower.zs" #include "zscript/games/duke/actors/dukeweapons/tripbomb.zs" diff --git a/wadsrc/static/zscript/games/duke/actors/boss2.zs b/wadsrc/static/zscript/games/duke/actors/boss2.zs index efe037a72..dd79388cf 100644 --- a/wadsrc/static/zscript/games/duke/actors/boss2.zs +++ b/wadsrc/static/zscript/games/duke/actors/boss2.zs @@ -5,6 +5,7 @@ class DukeBoss2 : DukeBoss1 pic "BOSS2"; -ALTHITSCANDIRECTION; +NONSMOKYROCKET; // If this wasn't needed for a CON defined actor it could be handled better + +SPECIALINIT; } override void PlayFTASound() diff --git a/wadsrc/static/zscript/games/duke/actors/controllers.zs b/wadsrc/static/zscript/games/duke/actors/controllers.zs index 1211487e5..9bf8d001a 100644 --- a/wadsrc/static/zscript/games/duke/actors/controllers.zs +++ b/wadsrc/static/zscript/games/duke/actors/controllers.zs @@ -205,6 +205,7 @@ class RedneckUfoBeam : DukeActor { pic "UFOBEAM"; +BADGUY; + ProjectileSpread 0; } override bool animate(tspritetype t) diff --git a/wadsrc/static/zscript/games/duke/actors/dukeweapons/projectiles.zs b/wadsrc/static/zscript/games/duke/actors/dukeweapons/projectiles.zs new file mode 100644 index 000000000..fa7d2d0ea --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/dukeweapons/projectiles.zs @@ -0,0 +1,60 @@ +extend class DukeActor +{ + DukeActor shootprojectile1(DukeActor actor, DukePlayer p, Vector3 pos, double ang, double vel, double zofs_post = 0, double scale = 0) const + { + sectortype sect = actor.sector; + int scount; + double zvel; + + if (actor.extra >= 0 && !self.bDONTLIGHTSHOOTER) actor.shade = -96; // not for shitball + + if (p != null) + { + let aimed = actor.aim(self); + + if (aimed) + { + double dal = ((aimed.scale.X * aimed.spriteHeight()) * 0.5); + double dist = (p.actor.pos.XY - aimed.pos.XY).Length(); + + zvel = ((aimed.pos.Z - pos.Z - dal) * vel) / dist; + ang = (aimed.pos.XY - pos.XY).Angle(); + } + else + { + [vel, zvel] = Raze.setFreeAimVelocity(vel, zvel, p.getPitchWithView(), 49.); + } + } + else + { + pos += actor.SpecialProjectileOffset(); + + let j = actor.findplayer(); + + if (actor.projectilespread < 0) + ang += frandom(self.projectilespread, 0); + else + ang += frandom(-self.projectilespread / 2, self.projectilespread / 2); + + double dist = (j.actor.pos.XY - actor.pos.XY).Length(); + zvel = ((j.actor.opos.Z + j.actor.viewzoffset - pos.Z + 3) * vel) / dist; + } + + if (scale <= 0) scale = p? 0.109375 : 0.28125; + + pos.Z += zofs_post; + + let spawned = dlevel.SpawnActor(sect, pos, self.GetClass(), -127, (scale, scale), ang, vel, zvel, actor, STAT_PROJECTILE); + if (!spawned) return nullptr; + spawned.extra += random(0, 7); + + spawned.cstat = CSTAT_SPRITE_YCENTER; + spawned.clipdist = 1; + return spawned; + } + + virtual Vector3 SpecialProjectileOffset() + { + return (0, 0, 0); + } +} diff --git a/wadsrc/static/zscript/games/duke/actors/projectiles.zs b/wadsrc/static/zscript/games/duke/actors/projectiles.zs index de5ada2d5..932c00866 100644 --- a/wadsrc/static/zscript/games/duke/actors/projectiles.zs +++ b/wadsrc/static/zscript/games/duke/actors/projectiles.zs @@ -227,12 +227,14 @@ class DukeFirelaser : DukeProjectile // Liztrooper shot return false; } - override bool animate(tspritetype tspr) + override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const { - if (Raze.isRR()) tspr.setSpritePic(self, ((PlayClock >> 2) % 6)); + pos.Z -= 2; + shootprojectile1(actor, p, pos, ang, 52.5, 0); return true; } - + + } class DukeFirelaserTrail : DukeActor @@ -257,6 +259,29 @@ class DukeFirelaserTrail : DukeActor if (Raze.isRR()) tspr.setSpritePic(self, ((PlayClock >> 2) % 6)); return true; } + + +} + +class RedneckFirelaser : DukeFirelaser +{ + default + { + spriteset "FIRELASER", "FIRELASER2", "FIRELASER3", "FIRELASER4", "FIRELASER5", "FIRELASER6"; + } + + override bool animate(tspritetype tspr) + { + tspr.setSpritePic(self, ((PlayClock >> 2) % 6)); + return true; + } + + override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const + { + pos.Z -= 4; + shootprojectile1(actor, p, pos, ang, 52.5, 0, 0.125); + return true; + } } @@ -476,6 +501,13 @@ class DukeSpit : DukeProjectile } return false; } + + override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const + { + pos.Z -= 10; + shootprojectile1(actor, p, pos, ang, 292/16., 0); + return true; + } } //--------------------------------------------------------------------------- @@ -494,18 +526,23 @@ class DukeCoolExplosion1 : DukeProjectile // octabrain shot. "COOLEXPLOSION16", "COOLEXPLOSION17", "COOLEXPLOSION18", "COOLEXPLOSION19", "COOLEXPLOSION20"; +FULLBRIGHT; +MIRRORREFLECT; + +SPECIALINIT; } override void Initialize() { - self.angle = self.ownerActor.angle; - self.shade = -64; - self.cstat = CSTAT_SPRITE_YCENTER | self.randomXFlip(); + if (!bSIMPLEINIT) + { + // looks like this case is never used anywhere. + self.cstat = CSTAT_SPRITE_YCENTER | self.randomXFlip(); + self.angle = self.ownerActor.angle; + self.shade = -64; - double c, f; - [c, f] = self.sector.getSlopes(self.pos.XY); - if (self.pos.Z > f - 12) - self.pos.Z = f - 12; + double c, f; + [c, f] = self.sector.getSlopes(self.pos.XY); + if (self.pos.Z > f - 12) + self.pos.Z = f - 12; + } } override bool premoveeffect() @@ -557,6 +594,27 @@ class DukeCoolExplosion1 : DukeProjectile // octabrain shot. return true; } + override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const + { + pos.Z -= 10; + let spawned = shootprojectile1(actor, p, pos, ang, 292/16., 0); + if (spawned) + { + spawned.shade = 0; + // special hack case. + if (actor.bSPECIALINIT) + { + let ovel = spawned.vel.X; + spawned.vel.X = 64; + spawned.DoMove(CLIPMASK0); + spawned.vel.X = ovel; + spawned.Angle += frandom(-22.5, 22.5); + } + } + + return true; + } + } //--------------------------------------------------------------------------- @@ -731,21 +789,6 @@ class DukeFireball : DukeProjectile // WorldTour only } } -//--------------------------------------------------------------------------- -// -// These 3 just use the base projectile code... -// -//--------------------------------------------------------------------------- - -class RedneckVixenShot : RedneckUWhip // COOLEXPLOSION1 -{ - default - { - pic "VIXENSHOT"; - +INFLAME; - } -} - //--------------------------------------------------------------------------- // // @@ -983,6 +1026,20 @@ class RedneckShitBall : DukeSpit } return true; } + + override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const + { + if (actor.bSPAWNRABBITGUTS) + { + shootprojectile1(actor, p, pos, ang, 37.5, -20); + } + else + { + shootprojectile1(actor, p, pos, ang, 25, -10); + } + return true; + } + } //--------------------------------------------------------------------------- diff --git a/wadsrc/static/zscript/games/duke/actors/redneckenemies.zs b/wadsrc/static/zscript/games/duke/actors/redneckenemies.zs index d45ba7967..c02c1874a 100644 --- a/wadsrc/static/zscript/games/duke/actors/redneckenemies.zs +++ b/wadsrc/static/zscript/games/duke/actors/redneckenemies.zs @@ -336,6 +336,7 @@ class RedneckHulk : DukeActor +INTERNAL_BADGUY; +KILLCOUNT; +NORADIUSPUSH; + ProjectileSpread -5.625; } override void Initialize() @@ -343,6 +344,12 @@ class RedneckHulk : DukeActor self.scale = (0.5, 0.5); self.setClipDistFromTile(); } + + override Vector3 SpecialProjectileOffset() + { + return ((self.Angle + 45).ToVector() * 16, 12); + } + } class RedneckHulkStayput : RedneckHulk diff --git a/wadsrc/static/zscript/games/duke/actors/redneckenemies/vixen.zs b/wadsrc/static/zscript/games/duke/actors/redneckenemies/vixen.zs index dfe85e4ab..96d6c8c42 100644 --- a/wadsrc/static/zscript/games/duke/actors/redneckenemies/vixen.zs +++ b/wadsrc/static/zscript/games/duke/actors/redneckenemies/vixen.zs @@ -6,16 +6,7 @@ class RedneckVixen : DukeActor +INTERNAL_BADGUY; +KILLCOUNT; +LOOKALLAROUND; - } - -class RedneckVixen : DukeActor -{ - default - { - pic "VIXEN"; - +INTERNAL_BADGUY; - +KILLCOUNT; - +LOOKALLAROUND; + ProjectileSpread -2.8125; } override void Initialize() @@ -31,6 +22,12 @@ class RedneckVixen : DukeActor self.setClipDistFromTile(); } + + override Vector3 SpecialProjectileOffset() + { + return (0, 0, -12); + } + } @@ -68,10 +65,10 @@ class RedneckUWhip : DukeProjectile else { let j = actor.findplayer(); - if (actor is 'RedneckVixen') - ang -= frandom(0, 22.5 / 8); + if (actor.projectilespread < 0) + ang += frandom(self.projectilespread, 0); else - ang += frandom(-22.5 / 8, 22.5 / 8); + ang += frandom(-self.projectilespread / 2, self.projectilespread / 2); double dist = (j.actor.pos.XY - actor.pos.XY).Length(); zvel = ((j.actor.opos.Z + j.actor.oviewzoffset - pos.Z + 3) * vel) / dist; @@ -112,3 +109,28 @@ class RedneckOWhip : RedneckUWhip return true; } } + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class RedneckVixenShot : DukeActor +{ + default + { + pic "VIXENSHOT"; + +INFLAME; + +FULLBRIGHT; + } + + override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const + { + pos.Z -= 4; + shootprojectile1(actor, p, pos, ang, 52.5, 0, 0.125); + return true; + } + +} + diff --git a/wadsrc/static/zscript/games/duke/dukeactor.zs b/wadsrc/static/zscript/games/duke/dukeactor.zs index 3952a66c8..c8eb1bd16 100644 --- a/wadsrc/static/zscript/games/duke/dukeactor.zs +++ b/wadsrc/static/zscript/games/duke/dukeactor.zs @@ -90,6 +90,7 @@ class DukeActor : CoreActor native lookallarounddefault; falladjustz 24; autoaimangle 8.4375; + projectilespread 5.625; } enum EStatnums { @@ -149,6 +150,7 @@ class DukeActor : CoreActor native meta int strength; meta double autoaimangle; meta double sparkoffset; + meta double projectilespread; property prefix: none; property gutsoffset: gutsoffset; @@ -157,7 +159,7 @@ class DukeActor : CoreActor native property strength: strength; property autoaimangle: autoaimangle; property sparkoffset: sparkoffset; - + property projectilespread: projectilespread; native void SetSpritesetImage(int index); native int GetSpritesetSize();