From ae3870f3c17717acfda7fc88e296325d340bf297 Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Sun, 7 Feb 2021 17:57:20 +0100 Subject: [PATCH] Parry tweaks. Now parrying on the very first tic will always result in a "perfect parry". Parry tracking on stats tab. Parry kill score bonuses. Small optimizations. --- README.md | 1 + language.def_base | 2 ++ language.def_menu | 2 ++ language.es_base | 2 ++ language.es_menu | 2 ++ language.version | 4 ++-- zscript/swwm_common.zsc | 2 +- zscript/swwm_handler.zsc | 17 +++++++++++++++-- zscript/swwm_inventory.zsc | 29 +++++++++++++++++++++++------ zscript/swwm_kbase.zsc | 4 ++++ zscript/swwm_powerup.zsc | 11 +++++++---- zscript/swwm_thinkers.zsc | 10 +++++----- 12 files changed, 66 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index af7d77c3d..5953e8d6e 100644 --- a/README.md +++ b/README.md @@ -474,6 +474,7 @@ The scoring system is pretty straightforward. Each enemy you kill will give you * +500 if the enemy was killed with the **Deep Impact** primary (humiliation). * +300 if the enemy was killed with your butt while dashing (no, seriously). * +600 if the enemy was killed with a blown kiss (oh my~). + * +200 if the enemy was killed with a parried projectile (+200 more if it was a perfect parry). * x2 for an overkill (enemy was gibbed or received twice its base health in damage). * x1.5 for each combo level, up to x8 in steps of x0.5. Kills are considered combos if multiple enemies are killed within 5 seconds of each other. * +100 for killing an enemy without having taken damage since last spawn, with extra +10 boosts for consecutive kills (extra boosts taper off after 10x). diff --git a/language.def_base b/language.def_base index 9fc1da87a..ae7f05c0d 100644 --- a/language.def_base +++ b/language.def_base @@ -946,6 +946,8 @@ SWWM_BUTTSLAM = "Buttslam"; SWWM_LOVED = "L\cg♥\c-VE"; SWWM_LOVED_ALT = "F\cg♥\c-CK NAZIS"; SWWM_FROGGED = "CROAK"; +SWWM_PARRY = "Parry"; +SWWM_PPARRY = "Perfect Parry"; // score messages SWWM_FINDSECRET = "\cf%s\cf found a secret. +%d\c-"; SWWM_FINDKEY = "\cf%s\cf got the %s\cf. +%d\c-"; diff --git a/language.def_menu b/language.def_menu index 8014d5fad..4b803faf2 100644 --- a/language.def_menu +++ b/language.def_menu @@ -305,6 +305,8 @@ SWWM_STATSTOMP = "Times Stomped: "; SWWM_STATFUEL = "Total Fuel Usage: "; SWWM_STATSPEED = "Top Speed: "; SWWM_STATAIRTIME = "Longest Air Time: "; +SWWM_STATPARRY = "Projectiles Parried: "; +SWWM_STATPPARRY = "Perfect Parries: "; SWWM_STATWPONCH = "Usables Punched: "; SWWM_STATBUSTS = "Walls Busted: "; SWWM_STATBUTTS = "Butt Slams: "; diff --git a/language.es_base b/language.es_base index 26f6b15af..399db057f 100644 --- a/language.es_base +++ b/language.es_base @@ -880,6 +880,8 @@ SWWM_LTFORM = "\cf¡%s\cf Legendario se ha transformado!\c-"; SWWM_SHAMEFUL = "Humillación"; SWWM_BUTTSLAM = "Culazo"; SWWM_FROGGED = "CROAC"; +SWWM_PARRY = "Parada"; +SWWM_PPARRY = "Parada Perfecta"; // score messages SWWM_FINDSECRET = "\cf%s\cf encontró un secreto. +%d\c-"; SWWM_FINDKEY = "\cf%s\cf obtuvo la %s\cf. +%d\c-"; diff --git a/language.es_menu b/language.es_menu index 40a6beda0..a40e88b13 100644 --- a/language.es_menu +++ b/language.es_menu @@ -302,6 +302,8 @@ SWWM_STATSTOMP = "Veces Impactado: "; SWWM_STATFUEL = "Uso Total de Combustible: "; SWWM_STATSPEED = "Velocidad Punta: "; SWWM_STATAIRTIME = "Mayor Tiempo en Aire: "; +SWWM_STATPARRY = "Proyectiles Parados: "; +SWWM_STATPPARRY = "Paradas Perfectas: "; SWWM_STATWPONCH = "Utilizables Aporreados: "; SWWM_STATBUSTS = "Paredes Reventadas: "; SWWM_STATBUTTS = "Golpes de Culo: "; diff --git a/language.version b/language.version index 8de40dc7e..75bcc4bc7 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\chSWWM \czGZ\c- \cw0.9.11b-pre r254 \cu(Fri 5 Feb 23:52:59 CET 2021)\c-"; -SWWM_SHORTVER="\cw0.9.11b-pre r254 \cu(2021-02-05 23:52:59)\c-"; +SWWM_MODVER="\chSWWM \czGZ\c- \cw0.9.11b-pre r255 \cu(Sun 7 Feb 17:57:20 CET 2021)\c-"; +SWWM_SHORTVER="\cw0.9.11b-pre r255 \cu(2021-02-07 17:57:20)\c-"; diff --git a/zscript/swwm_common.zsc b/zscript/swwm_common.zsc index f5bc120a9..db7633149 100644 --- a/zscript/swwm_common.zsc +++ b/zscript/swwm_common.zsc @@ -1313,7 +1313,7 @@ Class SWWMTeleportLine : Actor double pt = FRandom[ExploS](-90,90); double d = FRandom[ExploS](0.,1.); Vector3 ppos = bpos*d+apos*(1.-d)+(0,0,FRandom[ExploS](1,4)); - Vector3 rpos = level.Vec3Diff(pos,ppos); + Vector3 rpos = ppos-pos; A_SpawnParticle("88 AA FF",SPF_FULLBRIGHT,Random[ExploS](120,240),FRandom[ExploS](2.,4.),0,rpos.x,rpos.y,rpos.z,FRandom[ExploS](-.3,.3),FRandom[ExploS](-.3,.3),FRandom[ExploS](-.3,.3),0,0,FRandom[ExploS](.05,.1),FRandom[ExploS](.15,.3),-1,FRandom[ExploS](-.02,-.01)); } } diff --git a/zscript/swwm_handler.zsc b/zscript/swwm_handler.zsc index b2ed78261..389c6f5fc 100644 --- a/zscript/swwm_handler.zsc +++ b/zscript/swwm_handler.zsc @@ -1597,7 +1597,7 @@ Class SWWMHandler : EventHandler } else if ( e.DamageType == 'Buttslam' ) { - score += 200; + score += 300; if ( scr ) { scr.xscore[ofs] = 0; @@ -1618,7 +1618,7 @@ Class SWWMHandler : EventHandler } else if ( e.Inflictor is 'FroggyChair' ) { - score += 800; + score += 1440; if ( scr ) { scr.xscore[ofs] = 0; @@ -1627,6 +1627,19 @@ Class SWWMHandler : EventHandler scr.xcnt = ++ofs; } } + Inventory pb; + if ( e.Inflictor && (pb = e.Inflictor.FindInventory('ParriedBuff')) ) + { + score += 200; + if ( pb.special1&1 ) score += 200; + if ( scr ) + { + scr.xscore[ofs] = 0; + if ( pb.special1&1 ) scr.xstr[ofs] = StringTable.Localize("$SWWM_PPARRY"); + else scr.xstr[ofs] = StringTable.Localize("$SWWM_PARRY"); + scr.xcnt = ++ofs; + } + } if ( (e.Damage >= e.Thing.GetSpawnHealth()*2) || (((e.Thing.Health <= e.Thing.GetGibHealth()) || (src.bEXTREMEDEATH) || (e.Inflictor && e.Inflictor.bEXTREMEDEATH) || (e.DamageType == 'Extreme')) && !src.bNOEXTREMEDEATH && (!e.Inflictor || !e.Inflictor.bNOEXTREMEDEATH)) ) { score *= 2; diff --git a/zscript/swwm_inventory.zsc b/zscript/swwm_inventory.zsc index 60a462111..5f76f1094 100644 --- a/zscript/swwm_inventory.zsc +++ b/zscript/swwm_inventory.zsc @@ -820,7 +820,8 @@ Class ParryRing : Actor Class ParryField : Actor { - int lasteggtic; + bool critsnd; + SWWMStats s; Default { @@ -840,6 +841,7 @@ Class ParryField : Actor Destroy(); return; } + if ( master.player && !s ) s = SWWMStats.Find(master.player); Vector3 x, y, z, origin; [x, y, z] = swwm_CoordUtil.GetAxes(master.pitch,master.angle,master.roll); origin = level.Vec3Offset(master.Vec2OffsetZ(0,0,master.player.viewz),x*20); @@ -852,11 +854,16 @@ Class ParryField : Actor if ( !((a.bMISSILE && !a.IsZeroDamage() && (a.target != master)) || a.bSKULLFLY) || a.bTHRUACTORS || (level.Vec3Diff(a.pos,pos).length() > 80) ) continue; Vector3 vdir = a.vel; Vector3 dir = level.Vec3Diff(master.Vec2OffsetZ(0,0,pos.z),a.pos).unit(); + Vector3 hdir = dir; if ( a.bMISSILE ) { // deflect directly to target - if ( !Random[Parry](0,2) && a.target ) - dir = level.Vec3Diff(a.pos,a.target.Vec3Offset(0,0,a.target.height/2)).unit(); + if ( a.target ) + { + hdir = level.Vec3Diff(a.pos,a.target.Vec3Offset(0,0,a.target.height/2)).unit(); + double theta = max(FRandom[Parry](0.,1.)**2.,.1); + dir = dir*(1.-theta)+hdir*theta; + } // push away if ( a.bSEEKERMISSILE ) a.tracer = a.target; a.target = master; @@ -884,17 +891,26 @@ Class ParryField : Actor i.bAMBUSH = true; A_QuakeEx(3,3,3,10,0,64,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:.2); A_StartSound("demolitionist/parry",CHAN_WEAPON); - if ( (level.maptime > lasteggtic) && !Random[Parry](0,4) ) + if ( special1 >= special2 ) // perfect parry { + // increased homing + dir = dir*.4+hdir*.6; + nspeed = min(100,nspeed*1.5); + a.vel = dir*nspeed; for ( int i=1; i<6; i++ ) { let r = Spawn("ParryRing",a.pos); r.specialf1 = i*.04; } buff.special1++; - A_StartSound("misc/soulsparry",CHAN_ITEM,CHANF_OVERLAP,1.,.5); - lasteggtic = level.maptime+5; + if ( !critsnd ) + { + A_StartSound("misc/soulsparry",CHAN_ITEM,CHANF_OVERLAP,1.,.5); + if ( s ) s.pparries++; + } + critsnd = true; } + if ( s ) s.parries++; } if ( --special1 <= 0 ) Destroy(); } @@ -1430,6 +1446,7 @@ Class SWWMWeapon : Weapon abstract invoker.pfield = Spawn("ParryField",origin); invoker.pfield.master = self; invoker.pfield.special1 = duration; + invoker.pfield.special2 = duration; if ( !FindInventory("ParryDamageChecker") ) GiveInventory("ParryDamageChecker",1); // need this so parried projectiles deal extra damage } diff --git a/zscript/swwm_kbase.zsc b/zscript/swwm_kbase.zsc index d06402812..be15618fe 100644 --- a/zscript/swwm_kbase.zsc +++ b/zscript/swwm_kbase.zsc @@ -2463,6 +2463,10 @@ Class DemolitionistMenu : GenericMenu tsec = (stats.airtime/GameTicRate)%60; str = String.Format("\cx%s\c-%02d\cu:\c-%02d\cu:\c-%02d",StringTable.Localize("$SWWM_STATAIRTIME"),thour,tmin,tsec); statlist.Push(str); + str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATPARRY"),stats.parries); + statlist.Push(str); + str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATPPARRY"),stats.pparries); + statlist.Push(str); str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATWPONCH"),stats.wponch); statlist.Push(str); str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATBUSTS"),stats.busts); diff --git a/zscript/swwm_powerup.zsc b/zscript/swwm_powerup.zsc index 54ef0eb4c..d440145e2 100644 --- a/zscript/swwm_powerup.zsc +++ b/zscript/swwm_powerup.zsc @@ -305,6 +305,8 @@ Class GhostPower : PowerInvisibility Class GhostArtifactX : Actor { + SpriteID bsprite; + Default { RenderStyle "Add"; @@ -324,12 +326,13 @@ Class GhostArtifactX : Actor Destroy(); return; } - vel = target.vel; prev = target.prev; - SetOrigin(target.pos+vel,true); - A_SetAngle(target.angle,SPF_INTERPOLATE); + vel = target.vel; + if ( (target.pos != pos) || (target.vel != (0,0,0)) ) SetOrigin(target.pos+vel,true); + if ( angle != target.angle ) A_SetAngle(target.angle,SPF_INTERPOLATE); FloatBobPhase = target.FloatBobPhase; - bInvisible = target.bInvisible||!target.InStateSequence(target.CurState,target.FindState("Spawn")); + if ( !bsprite ) bsprite = GetSpriteIndex('XZW1'); + bInvisible = target.bInvisible||(target.sprite!=bsprite); } States { diff --git a/zscript/swwm_thinkers.zsc b/zscript/swwm_thinkers.zsc index c6255b0e2..6e6412e08 100644 --- a/zscript/swwm_thinkers.zsc +++ b/zscript/swwm_thinkers.zsc @@ -99,7 +99,7 @@ Class SWWMStats : Thinker int lastspawn, dashcount, boostcount, stompcount, airtime, kills, deaths, damagedealt, hdamagedealt, damagetaken, hdamagetaken, mkill, hiscore, hhiscore, topdealt, toptaken, skill, wponch, - busts, buttslams, secrets, items; + busts, buttslams, secrets, items, parries, pparries; double grounddist, airdist, swimdist, fuelusage, topspeed, teledist; Array wstats; Array mstats; @@ -646,9 +646,9 @@ Enum EScoreObjType Class SWWMScoreObj : Thinker { int xcnt; - int xtcolor[5]; - int xscore[5]; - String xstr[5]; + int xtcolor[6]; + int xscore[6]; + String xstr[6]; int tcolor; int score; Vector3 pos; @@ -693,7 +693,7 @@ Class SWWMScoreObj : Thinker o.seed2 = Random[ScoreBits](); o.damnum = (type > ST_Score); o.xcnt = 0; - for ( int i=0; i<5; i++ ) o.xtcolor[i] = hnd.numcolor_bonus.GetInt(); + for ( int i=0; i<6; i++ ) o.xtcolor[i] = hnd.numcolor_bonus.GetInt(); o.acc = acc; if ( o.damnum ) {