Major achievement progress.
This commit is contained in:
parent
7d401bdb61
commit
f5c9733c65
41 changed files with 868 additions and 276 deletions
|
|
@ -142,6 +142,8 @@ nosave color swwm_mm_yourcolor = "80 ff 00";
|
|||
|
||||
server noarchive bool swwm_iseriouslywanttoplaythiswithbd = false; // self-explanatory
|
||||
|
||||
nosave int swwm_playtime = 0; // total playtime in seconds
|
||||
|
||||
// cross-session achievement cvars (0: locked, 1: unlocked, 2: notified)
|
||||
nosave int swwm_achievement_gcsandwich = 0;
|
||||
nosave int swwm_achievement_hdoom = 0;
|
||||
|
|
@ -226,6 +228,7 @@ nosave int swwm_achievement_snake = 0;
|
|||
nosave int swwm_achievement_smb = 0;
|
||||
nosave int swwm_achievement_tyrian = 0;
|
||||
nosave int swwm_achievement_bof = 0;
|
||||
nosave int swwm_achievement_wantdie = 0;
|
||||
// cross-session progress cvars
|
||||
nosave int swwm_progress_gcsandwich = 0;
|
||||
nosave int swwm_progress_ghost = 0;
|
||||
|
|
@ -240,7 +243,7 @@ nosave int swwm_progress_gib = 0;
|
|||
nosave int swwm_progress_barrier = 0;
|
||||
nosave int swwm_progress_bossdash = 0;
|
||||
nosave int swwm_progress_sneeze = 0;
|
||||
nosave int swwm_progress_fuel = 0;
|
||||
nosave float swwm_progress_fuel = 0; // this one has to be a double
|
||||
nosave int swwm_progress_slayer = 0;
|
||||
nosave int swwm_progress_stomp = 0;
|
||||
nosave int swwm_progress_thruwall = 0;
|
||||
|
|
@ -257,7 +260,6 @@ nosave int swwm_progress_parry = 0;
|
|||
nosave int swwm_progress_allkills = 0;
|
||||
nosave int swwm_progress_allsecrets = 0;
|
||||
nosave int swwm_progress_reflect = 0;
|
||||
nosave int swwm_progress_wave = 0;
|
||||
nosave int swwm_progress_friend = 0;
|
||||
nosave int swwm_progress_shock = 0;
|
||||
nosave int swwm_progress_balls = 0;
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 185 B After Width: | Height: | Size: 189 B |
|
|
@ -854,7 +854,7 @@ SWWM_ACHIEVEMENT_CLIFFYB_TAG = "Errand Boy Bullshit";
|
|||
SWWM_ACHIEVEMENT_CLIFFYB_TXT = "Finish a map without collecting any keys";
|
||||
SWWM_ACHIEVEMENT_PAR_TAG = "Fast";
|
||||
SWWM_ACHIEVEMENT_PAR_TXT = "Beat the par time in %d maps";
|
||||
SWWM_ACHIEVEMENT_ONEGUY_TAG = "Fuck this Guy in Particular";
|
||||
SWWM_ACHIEVEMENT_ONEGUY_TAG = "Fuck that Guy in Particular";
|
||||
SWWM_ACHIEVEMENT_ONEGUY_TXT = "Use the Ynykron Artifact to kill a single non-boss enemy";
|
||||
SWWM_ACHIEVEMENT_GOLDEN_TAG = "Golden Shower";
|
||||
SWWM_ACHIEVEMENT_GOLDEN_TXT = "Use %d golden shells";
|
||||
|
|
@ -897,9 +897,9 @@ SWWM_ACHIEVEMENT_BUSTIN_TXT = "Bust %d walls";
|
|||
SWWM_ACHIEVEMENT_MOTH_TAG = "Mother";
|
||||
SWWM_ACHIEVEMENT_MOTH_TXT = "Gather %d moths";
|
||||
SWWM_ACHIEVEMENT_IWAD_TAG = "Mx. Worldwide";
|
||||
SWWM_ACHIEVEMENT_IWAD_TXT = "Play on all supported IWADs";
|
||||
SWWM_ACHIEVEMENT_IWAD_TXT = "Play on all supported games";
|
||||
SWWM_ACHIEVEMENT_BRAKE_TAG = "No Brakes";
|
||||
SWWM_ACHIEVEMENT_BRAKE_TXT = "Consume all your fuel while dashing %d times";
|
||||
SWWM_ACHIEVEMENT_BRAKE_TXT = "Consume your full fuel supply in a single dash %d times";
|
||||
SWWM_ACHIEVEMENT_RAGE_TAG = "No Talk me Angy";
|
||||
SWWM_ACHIEVEMENT_RAGE_TXT = "Use %d Ragekits";
|
||||
SWWM_ACHIEVEMENT_ABORT_TAG = "Oops I Broke It";
|
||||
|
|
@ -915,7 +915,7 @@ SWWM_ACHIEVEMENT_REFLECT_TXT = "Kill %d enemies with parried projectiles";
|
|||
SWWM_ACHIEVEMENT_SEKIRO_TAG = "Hesitation is Defeat";
|
||||
SWWM_ACHIEVEMENT_SEKIRO_TXT = "Die and reboot two times in the same map";
|
||||
SWWM_ACHIEVEMENT_WAVE_TAG = "Sayonara, Scumbag";
|
||||
SWWM_ACHIEVEMENT_WAVE_TXT = "Wave at a dying enemy %d times";
|
||||
SWWM_ACHIEVEMENT_WAVE_TXT = "Wave at a dying enemy";
|
||||
SWWM_ACHIEVEMENT_FRIEND_TAG = "Shaped like a Friend";
|
||||
SWWM_ACHIEVEMENT_FRIEND_TXT = "Befriend %d Cacodemons, Weredragons or Ettins with headpats";
|
||||
SWWM_ACHIEVEMENT_SHOCK_TAG = "Shockmaster";
|
||||
|
|
@ -941,13 +941,13 @@ SWWM_ACHIEVEMENT_DOSH_TXT = "Have ¥1,000,000,000 in bank";
|
|||
SWWM_ACHIEVEMENT_JUMP_TAG = "Verticality";
|
||||
SWWM_ACHIEVEMENT_JUMP_TXT = "Walljump %d times";
|
||||
SWWM_ACHIEVEMENT_EZKILL_TAG = "Well That was Easy";
|
||||
SWWM_ACHIEVEMENT_EZKILL_TXT = "Kill %d enemies with a single Ynykron Artifact shot";
|
||||
SWWM_ACHIEVEMENT_EZKILL_TXT = "Kill %d enemies with a single Ynykron Artifact shot (excluding altfire)";
|
||||
SWWM_ACHIEVEMENT_LIGMA_TAG = "Who's Steve Jobs?";
|
||||
SWWM_ACHIEVEMENT_LIGMA_TXT = "Kill an endgame boss with the Ynykron Artifact";
|
||||
SWWM_ACHIEVEMENT_YEET_TAG = "YEET";
|
||||
SWWM_ACHIEVEMENT_YEET_TXT = "Throw a Candygun right into the Icon of Sin's brains";
|
||||
SWWM_ACHIEVEMENT_MBF_TAG = "You can Pet the Dog";
|
||||
SWWM_ACHIEVEMENT_MBF_TXT = "Pet an MBF Helper Dog";
|
||||
SWWM_ACHIEVEMENT_MBF_TXT = "Pet a dog";
|
||||
SWWM_ACHIEVEMENT_LIGHTNING_TAG = "And the Dragons were No More";
|
||||
SWWM_ACHIEVEMENT_LIGHTNING_TXT = "Kill the Death Wyvern using the Rail Carbine";
|
||||
SWWM_ACHIEVEMENT_DAKKA_TAG = "Dakka";
|
||||
|
|
@ -994,3 +994,5 @@ SWWM_ACHIEVEMENT_TYRIAN_TAG = "Master of SHMUPs";
|
|||
SWWM_ACHIEVEMENT_TYRIAN_TXT = "Complete a full game of Interstellar Demolitionist";
|
||||
SWWM_ACHIEVEMENT_BOF_TAG = "Master of RPGs";
|
||||
SWWM_ACHIEVEMENT_BOF_TXT = "Complete a full game of Demolition Quest";
|
||||
SWWM_ACHIEVEMENT_WANTDIE_TAG = "E N D M I I";
|
||||
SWWM_ACHIEVEMENT_WANTDIE_TXT = "Fully clear a single map in the hardest difficulty (without dying)";
|
||||
|
|
|
|||
|
|
@ -756,7 +756,7 @@ SWWM_ACHIEVEMENT_CLIFFYB_TAG = "Mierdas de Recadero";
|
|||
SWWM_ACHIEVEMENT_CLIFFYB_TXT = "Termina un mapa sin obtener ninguna llave";
|
||||
SWWM_ACHIEVEMENT_PAR_TAG = "Rápido";
|
||||
SWWM_ACHIEVEMENT_PAR_TXT = "Supera el tiempo par en %d mapas";
|
||||
SWWM_ACHIEVEMENT_ONEGUY_TAG = "A la Mierda este Tío en Particular";
|
||||
SWWM_ACHIEVEMENT_ONEGUY_TAG = "A la Mierda el Tío Ese";
|
||||
SWWM_ACHIEVEMENT_ONEGUY_TXT = "Usa el Artefacto Ynykron para matar a un único enemigo no-jefe";
|
||||
SWWM_ACHIEVEMENT_GOLDEN_TAG = "Lluvia Dorada";
|
||||
SWWM_ACHIEVEMENT_GOLDEN_TXT = "Usa %d cartuchos dorados";
|
||||
|
|
@ -797,9 +797,9 @@ SWWM_ACHIEVEMENT_BUSTIN_TAG = "Me Hace Sentir Bien";
|
|||
SWWM_ACHIEVEMENT_BUSTIN_TXT = "Revienta %d paredes";
|
||||
SWWM_ACHIEVEMENT_MOTH_TAG = "Madre Polilla";
|
||||
SWWM_ACHIEVEMENT_MOTH_TXT = "Reúne %d polillas";
|
||||
SWWM_ACHIEVEMENT_IWAD_TXT = "Juega en todos los IWADs soportados";
|
||||
SWWM_ACHIEVEMENT_IWAD_TXT = "Juega en todos los juegos soportados";
|
||||
SWWM_ACHIEVEMENT_BRAKE_TAG = "Sin Frenos";
|
||||
SWWM_ACHIEVEMENT_BRAKE_TXT = "Consume todo tu combustible esprintando %d veces";
|
||||
SWWM_ACHIEVEMENT_BRAKE_TXT = "Consume toda tu capacidad de combustible en un solo esprint %d veces";
|
||||
SWWM_ACHIEVEMENT_RAGE_TAG = "No Hablo me Enfado";
|
||||
SWWM_ACHIEVEMENT_RAGE_TXT = "Usa %d Ragekits";
|
||||
SWWM_ACHIEVEMENT_ABORT_TAG = "Uy lo He Roto";
|
||||
|
|
@ -815,7 +815,7 @@ SWWM_ACHIEVEMENT_REFLECT_TXT = "Mata %d enemigos con proyectiles desviados";
|
|||
SWWM_ACHIEVEMENT_SEKIRO_TAG = "Dudar es Fracasar";
|
||||
SWWM_ACHIEVEMENT_SEKIRO_TXT = "Muere y reinicia dos veces en el mismo mapa";
|
||||
SWWM_ACHIEVEMENT_WAVE_TAG = "Sayonara, Capullo";
|
||||
SWWM_ACHIEVEMENT_WAVE_TXT = "Saluda a un enemigo muriéndose %d veces";
|
||||
SWWM_ACHIEVEMENT_WAVE_TXT = "Saluda a un enemigo muriéndose";
|
||||
SWWM_ACHIEVEMENT_FRIEND_TAG = "Con Forma de Amigo";
|
||||
SWWM_ACHIEVEMENT_FRIEND_TXT = "Entabla amistad con %d Cacodemonios, Hombres-Dragón o Ettins a base de caricias";
|
||||
SWWM_ACHIEVEMENT_SHOCK_TXT = "Realiza %d combos de Biospark";
|
||||
|
|
@ -839,12 +839,12 @@ SWWM_ACHIEVEMENT_DOSH_TXT = "Ten ¥1.000.000.000 en mano";
|
|||
SWWM_ACHIEVEMENT_JUMP_TAG = "Verticalidad";
|
||||
SWWM_ACHIEVEMENT_JUMP_TXT = "Salta paredes %d veces";
|
||||
SWWM_ACHIEVEMENT_EZKILL_TAG = "Eso Estuvo Fácil";
|
||||
SWWM_ACHIEVEMENT_EZKILL_TXT = "Mata %d enemigos con un solo disparo de Artefacto Ynykron";
|
||||
SWWM_ACHIEVEMENT_EZKILL_TXT = "Mata %d enemigos con un solo disparo de Artefacto Ynykron (excluyendo modo secundario)";
|
||||
SWWM_ACHIEVEMENT_LIGMA_TAG = "¿Quien es Steve Jobs?";
|
||||
SWWM_ACHIEVEMENT_LIGMA_TXT = "Mata a un jefe final con el Artefacto Ynykron";
|
||||
SWWM_ACHIEVEMENT_YEET_TXT = "Lanza una Pistola Caramelo justo dentro del cerebro del Icono del Pecado";
|
||||
SWWM_ACHIEVEMENT_MBF_TAG = "Puedes Acariciar el Perro";
|
||||
SWWM_ACHIEVEMENT_MBF_TXT = "Acaricia un Perro Ayudante MBF";
|
||||
SWWM_ACHIEVEMENT_MBF_TXT = "Acaricia un perro";
|
||||
SWWM_ACHIEVEMENT_LIGHTNING_TAG = "Y los Dragones Desaparecieron";
|
||||
SWWM_ACHIEVEMENT_LIGHTNING_TXT = "Mata al Wyvern Mortal usando la Carabina de Raíl";
|
||||
SWWM_ACHIEVEMENT_DAKKA_TXT = "Dispara la Ametralladora Sheen durante un minuto entero";
|
||||
|
|
@ -888,3 +888,5 @@ SWWM_ACHIEVEMENT_TYRIAN_TAG = "Maestro de SHMUPs";
|
|||
SWWM_ACHIEVEMENT_TYRIAN_TXT = "Completa una partida entera de Interstellar Demolitionist";
|
||||
SWWM_ACHIEVEMENT_BOF_TAG = "Maestro de RPGs";
|
||||
SWWM_ACHIEVEMENT_BOF_TXT = "Completa una partida entera de Demolition Quest";
|
||||
SWWM_ACHIEVEMENT_WANTDIE_TAG = "Mata a tu Jefe";
|
||||
SWWM_ACHIEVEMENT_WANTDIE_TXT = "Despeja un mapa en la dificultad más alta (sin morir)";
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
[default]
|
||||
SWWM_MODVER="\chSWWM \czGZ\c- \cw0.9.11b-pre r395 \cu(Tue 23 Mar 17:03:51 CET 2021)\c-";
|
||||
SWWM_SHORTVER="\cw0.9.11b-pre r395 \cu(2021-03-23 17:03:51)\c-";
|
||||
SWWM_MODVER="\chSWWM \czGZ\c- \cw0.9.11b-pre r396 \cu(Wed 24 Mar 02:25:38 CET 2021)\c-";
|
||||
SWWM_SHORTVER="\cw0.9.11b-pre r396 \cu(2021-03-24 02:25:38)\c-";
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ Class SWWMHDoomHandler : StaticEventHandler
|
|||
"\cx┃ \cfIf you want Demo-chan to actually fuck some hot demon girls, \cx┃\n"
|
||||
"\cx┃ \cfjust go commission a porn artist or something, idk. \cx┃\n"
|
||||
"\cx┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛");
|
||||
SWWMUtility.MarkAchievement('swwm_achievement_hdoom',players[consoleplayer]);
|
||||
}
|
||||
|
||||
override void WorldLoaded( WorldEvent e )
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ Class SWWMBrutalHandler : StaticEventHandler
|
|||
"\cx┃ \cfand trust me, it's better this way. \cx┃\n"
|
||||
"\cx┃ \cf<See you again, have a nice day> \cx┃\n"
|
||||
"\cx┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛");
|
||||
SWWMUtility.MarkAchievement('swwm_achievement_broccolidoccoli',players[consoleplayer]);
|
||||
}
|
||||
|
||||
override void WorldLoaded( WorldEvent e )
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ extend Class SWWMHandler
|
|||
S_StartSound("menu/buyinv",CHAN_ITEM,CHANF_UI);
|
||||
S_StartSound("misc/emone",CHAN_VOICE,CHANF_UI);
|
||||
}
|
||||
SWWMCredits.HasCheated(players[e.Args[0]]);
|
||||
SWWMCredits.Give(players[e.Args[0]],1000000000);
|
||||
SWWMScoreObj.Spawn(1000000000,players[e.Args[0]].mo.Vec3Offset(0,0,players[e.Args[0]].mo.Height/2));
|
||||
}
|
||||
|
|
@ -341,6 +342,7 @@ extend Class SWWMHandler
|
|||
if ( kstr != cht[i].Left(kstr.length()) ) continue;
|
||||
matchany = true;
|
||||
if ( kstr != cht[i] ) continue;
|
||||
if ( i > 4 ) SWWMUtility.MarkAchievement('swwm_achievement_cheat',players[consoleplayer]);
|
||||
if ( SWWMUtility.CheatsDisabled(consoleplayer) )
|
||||
{
|
||||
kfail = true;
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ extend Class SWWMHandler
|
|||
s.AddDamageDealt(e.Damage);
|
||||
if ( e.Damage > s.topdealt ) s.topdealt = e.Damage;
|
||||
}
|
||||
SWWMFlyTracker.Track(e.Thing,e.DamageSource);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -156,6 +157,25 @@ extend Class SWWMHandler
|
|||
lastcombat = AddOneliner("scorekill",1,15);
|
||||
}
|
||||
}
|
||||
// achievement stuff
|
||||
if ( e.Thing.IsHostile(src) )
|
||||
{
|
||||
if ( e.Thing.bBOSS && ((e.DamageType == 'Dash') || (e.DamageType == 'Buttslam')) )
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_bossdash',1,src.player);
|
||||
if ( e.DamageType == 'Push' )
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_sneeze',1,src.player);
|
||||
else if ( e.DamageType == 'Buttslam' )
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_butts',1,src.player);
|
||||
else if ( e.DamageType == 'Jump' )
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_stomp',1,src.player);
|
||||
else if ( e.DamageType == 'GroundPound' )
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_thicc',1,src.player);
|
||||
else if ( (e.DamageType == 'Love') && !(e.Thing is 'WolfensteinSS') )
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_love',1,src.player);
|
||||
if ( e.Inflictor && e.Inflictor.FindInventory('ParriedBuff') )
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_reflect',1,src.player);
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_mega',1,src.player);
|
||||
}
|
||||
// no credits unless it's a counted kill or marine (that isn't friendly)
|
||||
if ( e.Thing.IsFriend(src) || (!e.Thing.default.bCountKill && !(e.Thing is 'ScriptedMarine')) )
|
||||
return;
|
||||
|
|
@ -236,6 +256,7 @@ extend Class SWWMHandler
|
|||
scr.xstr[ofs] = StringTable.Localize("$SWWM_OVERKILL");
|
||||
scr.xcnt = ++ofs;
|
||||
}
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_gib',1,src.player);
|
||||
}
|
||||
score = int(score*(1.+.5*min(multilevel[pnum],16)));
|
||||
if ( (multilevel[pnum] > 0) && scr )
|
||||
|
|
@ -281,6 +302,7 @@ extend Class SWWMHandler
|
|||
SWWMCredits.Give(src.player,1000);
|
||||
Console.Printf(StringTable.Localize("$SWWM_LASTMONSTER"),src.player.GetUserName(),1000);
|
||||
SWWMScoreObj.Spawn(1000,src.Vec3Offset(0,0,src.Height/2));
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_allkills',1,src.player);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
// vanilla boss stuff
|
||||
|
||||
Class EndgameBossMarker : Inventory {}
|
||||
|
||||
extend Class SWWMHandler
|
||||
{
|
||||
String bosstag;
|
||||
|
|
@ -131,6 +133,7 @@ extend Class SWWMHandler
|
|||
bossactors.Push(e.Thing);
|
||||
if ( upgrademe ) e.Thing.StartHealth = e.Thing.Health *= 6;
|
||||
if ( trk ) trk.bBOSS = true;
|
||||
e.Thing.GiveInventory('EndgameBossMarker',1);
|
||||
}
|
||||
bosstag = "$BT_SPIDER";
|
||||
}
|
||||
|
|
@ -162,6 +165,7 @@ extend Class SWWMHandler
|
|||
bossactors.Push(e.Thing);
|
||||
if ( upgrademe ) e.Thing.StartHealth = e.Thing.Health *= 40; // goodbye, instakills
|
||||
if ( trk ) trk.bBOSS = true;
|
||||
e.Thing.GiveInventory('EndgameBossMarker',1);
|
||||
}
|
||||
if ( e.Thing is 'BossEye' )
|
||||
bossviewactor = e.Thing;
|
||||
|
|
@ -195,6 +199,7 @@ extend Class SWWMHandler
|
|||
if ( upgrademe ) e.Thing.StartHealth = e.Thing.Health *= 2;
|
||||
if ( trk ) trk.bBOSS = true;
|
||||
bosstag = "$BT_DSPARIL";
|
||||
e.Thing.GiveInventory('EndgameBossMarker',1);
|
||||
}
|
||||
else if ( e.Thing is 'Sorcerer2' )
|
||||
{
|
||||
|
|
@ -205,6 +210,7 @@ extend Class SWWMHandler
|
|||
if ( upgrademe ) e.Thing.StartHealth = e.Thing.Health *= 8;
|
||||
if ( trk ) trk.bBOSS = true;
|
||||
bosstag = "$BT_DSPARIL2";
|
||||
e.Thing.GiveInventory('EndgameBossMarker',1);
|
||||
}
|
||||
}
|
||||
else if ( bossmap == MAP_HMAP38 )
|
||||
|
|
@ -265,6 +271,7 @@ extend Class SWWMHandler
|
|||
if ( upgrademe ) e.Thing.StartHealth = e.Thing.Health *= 10;
|
||||
if ( trk ) trk.bBOSS = true;
|
||||
bosstag = "$BT_KORAX";
|
||||
e.Thing.GiveInventory('EndgameBossMarker',1);
|
||||
}
|
||||
}
|
||||
else if ( bossmap == MAP_HMAP60 )
|
||||
|
|
@ -276,6 +283,7 @@ extend Class SWWMHandler
|
|||
if ( trk ) trk.bBOSS = true;
|
||||
bosstag = "$BT_DEATHKINGS";
|
||||
initialized = true; // healthbar shows from the start
|
||||
e.Thing.GiveInventory('EndgameBossMarker',1);
|
||||
}
|
||||
}
|
||||
else if ( bossmap == MAP_EVMAP30 )
|
||||
|
|
@ -286,6 +294,7 @@ extend Class SWWMHandler
|
|||
if ( upgrademe ) e.Thing.StartHealth = e.Thing.Health *= 5;
|
||||
if ( trk ) trk.bBOSS = true;
|
||||
bosstag = "$BT_ARCHANGELUS";
|
||||
e.Thing.GiveInventory('EndgameBossMarker',1);
|
||||
}
|
||||
else if ( e.Thing.GetClassName() == "ArchangelusB" )
|
||||
{
|
||||
|
|
@ -296,6 +305,7 @@ extend Class SWWMHandler
|
|||
if ( upgrademe ) e.Thing.StartHealth = e.Thing.Health *= 5;
|
||||
if ( trk ) trk.bBOSS = true;
|
||||
bosstag = "$BT_ARCHANGELUS";
|
||||
e.Thing.GiveInventory('EndgameBossMarker',1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ extend Class SWWMHandler
|
|||
// for minimap
|
||||
Array<int> ffsectors;
|
||||
|
||||
Array<Key> mapkeys;
|
||||
|
||||
// level end stats
|
||||
override void WorldUnloaded( WorldEvent e )
|
||||
{
|
||||
|
|
@ -70,6 +72,21 @@ extend Class SWWMHandler
|
|||
players[i].mo.GiveInventory("InventoryWipeToken",1);
|
||||
}
|
||||
}
|
||||
// did we complete this map without collecting any of its keys? (doesn't work for hubs)
|
||||
if ( (mapkeys.Size() > 0) && !(level.clusterflags&LevelLocals.CLUSTER_HUB) )
|
||||
{
|
||||
bool collected = false;
|
||||
for ( int i=0; i<mapkeys.Size(); i++ )
|
||||
{
|
||||
if ( !mapkeys[i].Owner || !mapkeys[i].Owner.player ) continue;
|
||||
collected = true;
|
||||
break;
|
||||
}
|
||||
if ( !collected ) SWWMUtility.MarkAchievement('swwm_achievement_cliffyb',players[consoleplayer]);
|
||||
}
|
||||
// beat the par time?
|
||||
if ( level.partime && (Thinker.Tics2Seconds(level.maptime) <= level.partime) )
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_par',1,players[consoleplayer]);
|
||||
}
|
||||
|
||||
private void SetupLockdefsCache( SWWMCachedLockInfo cli )
|
||||
|
|
@ -249,5 +266,13 @@ extend Class SWWMHandler
|
|||
}
|
||||
// spawn loot
|
||||
Chancebox.SpawnChanceboxes();
|
||||
// list map keys
|
||||
let ti = ThinkerIterator.Create("Key");
|
||||
Key k;
|
||||
while ( k = Key(ti.Next()) )
|
||||
{
|
||||
if ( k.Owner ) continue;
|
||||
mapkeys.Push(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ extend Class SWWMHandler
|
|||
allitems = true;
|
||||
Console.Printf(StringTable.Localize("$SWWM_LASTITEM"),players[i].GetUserName(),500);
|
||||
score += 490;
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_allitems',1,players[i]);
|
||||
}
|
||||
SWWMCredits.Give(players[i],score);
|
||||
SWWMScoreObj.Spawn(score,players[i].mo.Vec3Offset(0,0,players[i].mo.Height/2));
|
||||
|
|
@ -189,6 +190,15 @@ extend Class SWWMHandler
|
|||
}
|
||||
}
|
||||
mapclearagain++;
|
||||
if ( !iwantdie ) return;
|
||||
let ti = ThinkerIterator.Create("SWWMStats",Thinker.STAT_STATIC);
|
||||
SWWMStats s;
|
||||
while ( s = SWWMStats(ti.Next()) )
|
||||
{
|
||||
if ( s.deaths > 0 )
|
||||
return;
|
||||
}
|
||||
SWWMUtility.MarkAchievement('swwm_achievement_wantdie',players[consoleplayer]);
|
||||
}
|
||||
|
||||
// "simple" tracking (used by the minimap)
|
||||
|
|
|
|||
|
|
@ -1,56 +1,55 @@
|
|||
// achievement tracking
|
||||
|
||||
// constants for finetuning them numbers
|
||||
const SA_GCSANDWICH = 40;
|
||||
const SA_GHOST = 30;
|
||||
const SA_ALLITEMS = 75;
|
||||
const SA_CONGA = 25;
|
||||
const SA_EXPLOGUN = 5;
|
||||
const SA_GRAVITY = 20;
|
||||
const SA_FLIGHT = 1000;
|
||||
const SA_PAR = 25;
|
||||
const SA_GCSANDWICH = 25;
|
||||
const SA_GHOST = 25;
|
||||
const SA_ALLITEMS = 30;
|
||||
const SA_CONGA = 15;
|
||||
const SA_EXPLOGUN = 7;
|
||||
const SA_GRAVITY = 25;
|
||||
const SA_FLIGHT = 2000;
|
||||
const SA_PAR = 30;
|
||||
const SA_GOLDEN = 24;
|
||||
const SA_GIB = 500;
|
||||
const SA_BARRIER = 30;
|
||||
const SA_BOSSDASH = 20;
|
||||
const SA_SNEEZE = 50;
|
||||
const SA_FUEL = 200;
|
||||
const SA_BARRIER = 25;
|
||||
const SA_BOSSDASH = 10;
|
||||
const SA_SNEEZE = 20;
|
||||
const SA_FUEL = 400;
|
||||
const SA_SLAYER = 40;
|
||||
const SA_STOMP = 50;
|
||||
const SA_THRUWALL = 30;
|
||||
const SA_THRUWALL = 25;
|
||||
const SA_LEAD = 1500;
|
||||
const SA_LOVE = 50;
|
||||
const SA_LOVE = 20;
|
||||
const SA_BUTTS = 100;
|
||||
const SA_PLUSH = 20;
|
||||
const SA_BUSTIN = 40;
|
||||
const SA_MOTH = 60;
|
||||
const SA_BRAKE = 30;
|
||||
const SA_RAGE = 40;
|
||||
const SA_MOTH = 50;
|
||||
const SA_BRAKE = 20;
|
||||
const SA_RAGE = 25;
|
||||
const SA_PARRY = 100;
|
||||
const SA_ALLKILLS = 100;
|
||||
const SA_ALLSECRETS = 50;
|
||||
const SA_REFLECT = 50;
|
||||
const SA_WAVE = 20;
|
||||
const SA_FRIEND = 60;
|
||||
const SA_SHOCK = 50;
|
||||
const SA_BALLS = 30;
|
||||
const SA_REFRESH = 40;
|
||||
const SA_ALLKILLS = 30;
|
||||
const SA_ALLSECRETS = 30;
|
||||
const SA_REFLECT = 20;
|
||||
const SA_FRIEND = 30;
|
||||
const SA_SHOCK = 30;
|
||||
const SA_BALLS = 10;
|
||||
const SA_REFRESH = 25;
|
||||
const SA_STEP = 60;
|
||||
const SA_SUNNY = 30;
|
||||
const SA_SUNNY = 25;
|
||||
const SA_THICC = 80;
|
||||
const SA_SLEMG = 100;
|
||||
const SA_JUMP = 100;
|
||||
const SA_EZKILL = 200;
|
||||
const SA_SLEMG = 50;
|
||||
const SA_JUMP = 80;
|
||||
const SA_EZKILL = 100;
|
||||
const SA_ROAST = 30;
|
||||
const SA_DAB = 60;
|
||||
const SA_DAB = 100;
|
||||
const SA_HND = 6;
|
||||
const SA_GEPGUN = 50;
|
||||
const SA_GEPGUN = 30;
|
||||
const SA_PENE = 20;
|
||||
const SA_ACID = 200;
|
||||
const SA_ACID = 100;
|
||||
const SA_SANIC = 800;
|
||||
const SA_BUNE = 150;
|
||||
const SA_BONK = 300;
|
||||
const SA_ANOM = 40;
|
||||
const SA_ANOM = 25;
|
||||
|
||||
// achievement unlock tracking
|
||||
extend Class SWWMStaticHandler
|
||||
|
|
@ -84,6 +83,7 @@ extend Class SWWMStaticHandler
|
|||
else if ( ac == 'swwm_achievement_dakka' ) maxval = 60;
|
||||
else if ( ac == 'swwm_achievement_dosh' ) maxval = 1000000000;
|
||||
else if ( ac == 'swwm_achievement_mega' ) maxval = 1000000;
|
||||
else if ( ac == 'swwm_achievement_iwad' ) maxval = 7;
|
||||
if ( val && (prog < maxval) )
|
||||
{
|
||||
ev.SetInt(0);
|
||||
|
|
@ -194,7 +194,8 @@ extend Class SWWMStaticHandler
|
|||
'swwm_achievement_snake',
|
||||
'swwm_achievement_smb',
|
||||
'swwm_achievement_tyrian',
|
||||
'swwm_achievement_bof'
|
||||
'swwm_achievement_bof',
|
||||
'swwm_achievement_wantdie'
|
||||
};
|
||||
// localized name
|
||||
static const String names[] =
|
||||
|
|
@ -280,7 +281,8 @@ extend Class SWWMStaticHandler
|
|||
"$SWWM_ACHIEVEMENT_SNAKE",
|
||||
"$SWWM_ACHIEVEMENT_SMB",
|
||||
"$SWWM_ACHIEVEMENT_TYRIAN",
|
||||
"$SWWM_ACHIEVEMENT_BOF"
|
||||
"$SWWM_ACHIEVEMENT_BOF",
|
||||
"$SWWM_ACHIEVEMENT_WANTDIE"
|
||||
};
|
||||
// has number in txt
|
||||
static const int number[] =
|
||||
|
|
@ -328,7 +330,7 @@ extend Class SWWMStaticHandler
|
|||
SA_ALLSECRETS,
|
||||
SA_REFLECT,
|
||||
0, // SEKIRO
|
||||
SA_WAVE,
|
||||
0, // WAVE
|
||||
SA_FRIEND,
|
||||
SA_SHOCK,
|
||||
SA_BALLS,
|
||||
|
|
@ -366,7 +368,8 @@ extend Class SWWMStaticHandler
|
|||
0, // SNAKE
|
||||
0, // SMB
|
||||
0, // TYRIAN
|
||||
0 // BOF
|
||||
0, // BOF
|
||||
0 // WANTDIE
|
||||
};
|
||||
// is ignored (hide away achievements that can't be done yet)
|
||||
static const bool ignoreme[] =
|
||||
|
|
@ -452,93 +455,95 @@ extend Class SWWMStaticHandler
|
|||
true, // SNAKE
|
||||
true, // SMB
|
||||
true, // TYRIAN
|
||||
true // BOF
|
||||
true, // BOF
|
||||
false // WANTDIE
|
||||
};
|
||||
// progress tracking cvar (if any)
|
||||
static const Name pvar[] =
|
||||
{
|
||||
'swwm_progress_gcsandwich', // GCSANDWICH
|
||||
'swwm_progress_gcsandwich',
|
||||
'None', // HDOOM
|
||||
'None', // ONESTANDING
|
||||
'None', // OOPSIE
|
||||
'swwm_progress_ghost', // GHOST
|
||||
'swwm_progress_ghost',
|
||||
'None', // CLONK
|
||||
'swwm_progress_allitems', // ALLITEMS
|
||||
'swwm_progress_conga', // CONGA
|
||||
'swwm_progress_explogun', // EXPLOGUN
|
||||
'swwm_progress_gravity', // GRAVITY
|
||||
'swwm_progress_flight', // FLIGHT
|
||||
'swwm_progress_allitems',
|
||||
'swwm_progress_conga',
|
||||
'swwm_progress_explogun',
|
||||
'swwm_progress_gravity',
|
||||
'swwm_progress_flight',
|
||||
'None', // CLIFFYB
|
||||
'swwm_progress_par', // PAR
|
||||
'swwm_progress_par',
|
||||
'None', // ONEGUY
|
||||
'swwm_progress_golden', // GOLDEN
|
||||
'swwm_progress_gib', // GIB
|
||||
'swwm_progress_barrier', // BARRIER
|
||||
'swwm_progress_bossdash', // BOSSDASH
|
||||
'swwm_progress_sneeze', // SNEEZE
|
||||
'swwm_progress_fuel', // FUEL
|
||||
'swwm_progress_slayer', // SLAYER
|
||||
'swwm_progress_golden',
|
||||
'swwm_progress_gib',
|
||||
'swwm_progress_barrier',
|
||||
'swwm_progress_bossdash',
|
||||
'swwm_progress_sneeze',
|
||||
'swwm_progress_fuel',
|
||||
'swwm_progress_slayer',
|
||||
'None', // BROCCOLIDOCCOLI
|
||||
'None', // DIME
|
||||
'swwm_progress_stomp', // STOMP
|
||||
'swwm_progress_stomp',
|
||||
'None', // CHEAT
|
||||
'None', // GOD
|
||||
'swwm_progress_thruwall', // THRUWALL
|
||||
'swwm_progress_thruwall',
|
||||
'None', // MASHIRO
|
||||
'swwm_progress_lead', // LEAD
|
||||
'swwm_progress_love', // LOVE
|
||||
'swwm_progress_butts', // BUTTS
|
||||
'swwm_progress_plush', // PLUSH
|
||||
'swwm_progress_bustin', // BUSTIN
|
||||
'swwm_progress_moth', // MOTH
|
||||
'None', // IWAD
|
||||
'swwm_progress_lead',
|
||||
'swwm_progress_love',
|
||||
'swwm_progress_butts',
|
||||
'swwm_progress_plush',
|
||||
'swwm_progress_bustin',
|
||||
'swwm_progress_moth',
|
||||
'swwm_progress_iwad',
|
||||
'swwm_progress_brake', // BRAKE
|
||||
'swwm_progress_rage', // RAGE
|
||||
'swwm_progress_rage',
|
||||
'None', // ABORT
|
||||
'swwm_progress_parry', // PARRY
|
||||
'swwm_progress_allkills', // ALLKILLS
|
||||
'swwm_progress_allsecrets', // ALLSECRETS
|
||||
'swwm_progress_reflect', // REFLECT
|
||||
'swwm_progress_parry',
|
||||
'swwm_progress_allkills',
|
||||
'swwm_progress_allsecrets',
|
||||
'swwm_progress_reflect',
|
||||
'None', // SEKIRO
|
||||
'swwm_progress_wave', // WAVE
|
||||
'swwm_progress_friend', // FRIEND
|
||||
'swwm_progress_shock', // SHOCK
|
||||
'swwm_progress_balls', // BALLS
|
||||
'swwm_progress_refresh', // REFRESH
|
||||
'swwm_progress_step', // STEP
|
||||
'swwm_progress_sunny', // SUNNY
|
||||
'swwm_progress_thicc', // THICC
|
||||
'swwm_progress_allcoll', // ALLCOLL
|
||||
'swwm_progress_slemg', // SLEMG
|
||||
'swwm_progress_dosh', // DOSH
|
||||
'swwm_progress_jump', // JUMP
|
||||
'swwm_progress_ezkill', // EZKILL
|
||||
'None', // WAVE
|
||||
'swwm_progress_friend',
|
||||
'swwm_progress_shock',
|
||||
'swwm_progress_balls',
|
||||
'swwm_progress_refresh',
|
||||
'swwm_progress_step',
|
||||
'swwm_progress_sunny',
|
||||
'swwm_progress_thicc',
|
||||
'swwm_progress_allcoll',
|
||||
'swwm_progress_slemg',
|
||||
'swwm_progress_dosh',
|
||||
'swwm_progress_jump',
|
||||
'swwm_progress_ezkill',
|
||||
'None', // LIGMA
|
||||
'None', // YEET
|
||||
'None', // MBF
|
||||
'None', // LIGHTNING
|
||||
'swwm_progress_dakka', // DAKKA
|
||||
'swwm_progress_roast', // ROAST
|
||||
'swwm_progress_dab', // DAB
|
||||
'swwm_progress_hnd', // HND
|
||||
'swwm_progress_gepgun', // GEPGUN
|
||||
'swwm_progress_dakka',
|
||||
'swwm_progress_roast',
|
||||
'swwm_progress_dab',
|
||||
'swwm_progress_hnd',
|
||||
'swwm_progress_gepgun',
|
||||
'None', // FULLER
|
||||
'swwm_progress_pene', // PENE
|
||||
'swwm_progress_acid', // ACID
|
||||
'swwm_progress_pene',
|
||||
'swwm_progress_acid',
|
||||
'None', // SALT
|
||||
'swwm_progress_mega', // MEGA
|
||||
'swwm_progress_sanic', // SANIC
|
||||
'swwm_progress_mega',
|
||||
'swwm_progress_sanic',
|
||||
'None', // TELE
|
||||
'swwm_progress_bune', // BUNE
|
||||
'swwm_progress_bonk', // BONK
|
||||
'swwm_progress_anom', // ANOM
|
||||
'swwm_progress_bune',
|
||||
'swwm_progress_bonk',
|
||||
'swwm_progress_anom',
|
||||
'None', // ANONE
|
||||
'None', // TETRIS
|
||||
'None', // PONG
|
||||
'None', // SNAKE
|
||||
'None', // SMB
|
||||
'None', // TYRIAN
|
||||
'None' // BOF
|
||||
'None', // BOF
|
||||
'None' // WANTDIE
|
||||
};
|
||||
bool alldone = true;
|
||||
for ( int i=0; i<vars.Size(); i++ )
|
||||
|
|
|
|||
|
|
@ -206,10 +206,10 @@ Class SWWMAchievementNotification : HUDMessageBase
|
|||
else hs.x = swwm_hudscale;
|
||||
Vector2 ss = (Screen.GetWidth()/hs.x,Screen.GetHeight()/hs.y);
|
||||
double alpha = (tics<fadeintics)?(tics/fadeintics):(tics<(fadeintics+holdtics))?1.:(1.-(tics-(fadeintics+holdtics))/fadeouttics);
|
||||
Vector2 pos = (int(ss.x-232)/2,(ss.y-(margin+36))+int(margin+40)*(1.-alpha));
|
||||
Vector2 pos = (int(ss.x-256)/2,(ss.y-(margin+36))+int(margin+40)*(1.-alpha));
|
||||
String loctag = StringTable.Localize(tag);
|
||||
String loctxt = num?String.Format(StringTable.Localize(txt),num):StringTable.Localize(txt);
|
||||
BrokenLines l = fnt2.BreakLines(loctxt,176);
|
||||
BrokenLines l = fnt2.BreakLines(loctxt,200);
|
||||
int th = 14+(9*l.Count());
|
||||
Screen.DrawTexture(frame,false,pos.x,pos.y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alpha);
|
||||
if ( icon.IsValid() ) Screen.DrawTexture(icon,false,pos.x+2,pos.y+2,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alpha);
|
||||
|
|
@ -218,7 +218,7 @@ Class SWWMAchievementNotification : HUDMessageBase
|
|||
yy += 14;
|
||||
for ( int i=0; i<l.Count(); i++ )
|
||||
{
|
||||
Screen.DrawText(fnt2,Font.CR_WHITE,pos.x+46,pos.y+yy,l.StringAt(i),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alpha);
|
||||
Screen.DrawText(fnt2,Font.CR_WHITE,pos.x+44,pos.y+yy,l.StringAt(i),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alpha);
|
||||
yy += 9;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,6 +80,26 @@ Class SWWMCollectible : Inventory abstract
|
|||
override void AttachToOwner( Actor other )
|
||||
{
|
||||
Super.AttachToOwner(other);
|
||||
// count how many we have, set progress accordingly
|
||||
int nc = 0, tnc = 0, cnc = 0;
|
||||
for ( int i=0; i<AllActorClasses.Size(); i++ )
|
||||
{
|
||||
let c = (Class<SWWMCollectible>)(AllActorClasses[i]);
|
||||
if ( !c || (c == 'SWWMCollectible') ) continue;
|
||||
let def = GetDefaultByType(c);
|
||||
tnc++;
|
||||
// check that we can collect it in this IWAD
|
||||
if ( !def.ValidGame() ) continue;
|
||||
nc++;
|
||||
}
|
||||
for ( Inventory i=other.inv; i; i=i.inv )
|
||||
{
|
||||
if ( i is 'SWWMCollectible' )
|
||||
cnc++;
|
||||
}
|
||||
// force progress to be "total collectibles" so this doesn't get unset on other IWADs that may have more
|
||||
if ( cnc == nc ) SWWMUtility.AchievementProgress('swwm_progress_allcoll',tnc,other.player);
|
||||
else SWWMUtility.AchievementProgress('swwm_progress_allcoll',cnc,other.player);
|
||||
// we're only attaching to the other players
|
||||
if ( propagated )
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -100,11 +100,19 @@ Class SayaBeanGesture : SWWMItemGesture
|
|||
}
|
||||
A_StartSound("saya/giggle",CHAN_ITEMEXTRA,CHANF_OVERLAP);
|
||||
}
|
||||
action void A_UsePlush()
|
||||
{
|
||||
if ( !Demolitionist(self) ) return;
|
||||
let s = Demolitionist(self).mystats;
|
||||
if ( !s ) return;
|
||||
s.plushuses++;
|
||||
SWWMUtility.AchievementProgress('swwm_progress_plush',s.plushuses,player);
|
||||
}
|
||||
|
||||
States
|
||||
{
|
||||
Fire:
|
||||
XZW1 A 3;
|
||||
XZW1 A 3 A_UsePlush();
|
||||
XZW1 B 3 A_StartSound("demolitionist/handsup",CHAN_WEAPON,CHANF_OVERLAP);
|
||||
XZW1 CDEFGH 3;
|
||||
XZW1 IJ 4;
|
||||
|
|
|
|||
|
|
@ -183,6 +183,7 @@ Class RefresherItem : SWWMHealth
|
|||
}
|
||||
override void AutoUseExtra( bool recursive )
|
||||
{
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_refresh',1,Owner.player);
|
||||
// regen effect doesn't stack if we autoactivated recursively
|
||||
if ( recursive ) return;
|
||||
let p = Powerup(Owner.FindInventory("RefresherRegen"));
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ Class GrilledCheeseSandwich : Inventory
|
|||
double lastsafeangle[5];
|
||||
int safetic;
|
||||
int dteleport;
|
||||
Actor lastdropper;
|
||||
|
||||
override Inventory CreateCopy( Actor other )
|
||||
{
|
||||
|
|
@ -35,6 +36,7 @@ Class GrilledCheeseSandwich : Inventory
|
|||
}
|
||||
void DoTheThing( bool extrasafe = false )
|
||||
{
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_gcsandwich',1,Owner.player);
|
||||
SWWMHandler.DoFlash(Owner,Color(64,255,255,64),10);
|
||||
Owner.A_QuakeEx(9,9,9,3,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:1.);
|
||||
Owner.GiveBody(1000,1000);
|
||||
|
|
@ -183,9 +185,14 @@ Class GrilledCheeseSandwich : Inventory
|
|||
other.Inv = Inv;
|
||||
Inv = saved;
|
||||
}
|
||||
override void OnDrop( Actor dropper )
|
||||
{
|
||||
lastdropper = dropper;
|
||||
}
|
||||
override void PostTeleport( Vector3 destpos, double destangle, int flags )
|
||||
{
|
||||
// TODO "teleported bread" achievement
|
||||
if ( !lastdropper ) return;
|
||||
SWWMUtility.MarkAchievement('swwm_achievement_tele',lastdropper.player);
|
||||
}
|
||||
|
||||
Default
|
||||
|
|
@ -392,6 +399,7 @@ Class GhostArtifact : Inventory
|
|||
Demolitionist(Owner).lastbump *= 1.04;
|
||||
}
|
||||
else Owner.GiveInventory("GhostPower",1);
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_ghost',1,Owner.player);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -541,6 +549,7 @@ Class GravitySuppressor : Inventory
|
|||
Demolitionist(Owner).lastbump *= 1.04;
|
||||
}
|
||||
else Owner.GiveInventory("GravityPower",1);
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_gravity',1,Owner.player);
|
||||
return true;
|
||||
}
|
||||
override void Travelled()
|
||||
|
|
@ -782,6 +791,7 @@ Class FuckingInvinciball : Inventory
|
|||
Demolitionist(Owner).lastbump *= 1.1;
|
||||
}
|
||||
else Owner.GiveInventory("InvinciballPower",1);
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_sunny',1,Owner.player);
|
||||
return true;
|
||||
}
|
||||
override void Travelled()
|
||||
|
|
@ -1064,6 +1074,7 @@ Class Ragekit : Inventory
|
|||
Demolitionist(Owner).lastbump *= .95;
|
||||
}
|
||||
else Owner.GiveInventory("RagekitPower",1);
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_rage',1,Owner.player);
|
||||
return true;
|
||||
}
|
||||
override void Travelled()
|
||||
|
|
@ -1560,6 +1571,7 @@ Class CompanionLamp : Actor
|
|||
m.lamp = self;
|
||||
m.trail = m.pos;
|
||||
moff.Push(m);
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_moth',1,parent.player);
|
||||
}
|
||||
override void PostBeginPlay()
|
||||
{
|
||||
|
|
@ -2015,6 +2027,7 @@ Class EBarrier : Inventory
|
|||
Demolitionist(Owner).lastbump *= 0.95;
|
||||
}
|
||||
else Owner.GiveInventory("BarrierPower",1);
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_barrier',1,Owner.player);
|
||||
return true;
|
||||
}
|
||||
override void Travelled()
|
||||
|
|
@ -2628,12 +2641,15 @@ Class Mykradvo : Inventory
|
|||
Amount++;
|
||||
return true;
|
||||
}
|
||||
if ( (targets.Size() == 1) && targets[0] && !targets[0].bBOSS )
|
||||
SWWMUtility.MarkAchievement('swwm_achievement_anone',Owner.player);
|
||||
let p = Spawn("MykradvoBurst",spawnpos);
|
||||
p.target = Owner;
|
||||
MykradvoBurst(p).targets.Move(targets);
|
||||
targets.Clear();
|
||||
if ( Owner is 'Demolitionist' )
|
||||
Demolitionist(Owner).lastbump *= 1.2;
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_anom',1,Owner.player);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -437,7 +437,8 @@ Class DemolitionistMenu : GenericMenu
|
|||
'swwm_achievement_snake',
|
||||
'swwm_achievement_smb',
|
||||
'swwm_achievement_tyrian',
|
||||
'swwm_achievement_bof'
|
||||
'swwm_achievement_bof',
|
||||
'swwm_achievement_wantdie'
|
||||
};
|
||||
// localized name
|
||||
static const String names[] =
|
||||
|
|
@ -524,7 +525,8 @@ Class DemolitionistMenu : GenericMenu
|
|||
"$SWWM_ACHIEVEMENT_SNAKE",
|
||||
"$SWWM_ACHIEVEMENT_SMB",
|
||||
"$SWWM_ACHIEVEMENT_TYRIAN",
|
||||
"$SWWM_ACHIEVEMENT_BOF"
|
||||
"$SWWM_ACHIEVEMENT_BOF",
|
||||
"$SWWM_ACHIEVEMENT_WANTDIE"
|
||||
};
|
||||
// has number in txt
|
||||
static const int number[] =
|
||||
|
|
@ -572,7 +574,7 @@ Class DemolitionistMenu : GenericMenu
|
|||
SA_ALLSECRETS,
|
||||
SA_REFLECT,
|
||||
0, // SEKIRO
|
||||
SA_WAVE,
|
||||
0, // WAVE
|
||||
SA_FRIEND,
|
||||
SA_SHOCK,
|
||||
SA_BALLS,
|
||||
|
|
@ -611,7 +613,8 @@ Class DemolitionistMenu : GenericMenu
|
|||
0, // SNAKE
|
||||
0, // SMB
|
||||
0, // TYRIAN
|
||||
0 // BOF
|
||||
0, // BOF
|
||||
0 // WANTDIE
|
||||
};
|
||||
// is ignored (hide away achievements that can't be done yet)
|
||||
static const bool ignoreme[] =
|
||||
|
|
@ -698,94 +701,96 @@ Class DemolitionistMenu : GenericMenu
|
|||
true, // SNAKE
|
||||
true, // SMB
|
||||
true, // TYRIAN
|
||||
true // BOF
|
||||
true, // BOF
|
||||
false // WANTDIE
|
||||
};
|
||||
// progress tracking cvar (if any)
|
||||
static const Name pvar[] =
|
||||
{
|
||||
'swwm_progress_gcsandwich', // GCSANDWICH
|
||||
'swwm_progress_gcsandwich',
|
||||
'None', // HDOOM
|
||||
'None', // ONESTANDING
|
||||
'None', // OOPSIE
|
||||
'swwm_progress_ghost', // GHOST
|
||||
'swwm_progress_ghost',
|
||||
'None', // CLONK
|
||||
'swwm_progress_allitems', // ALLITEMS
|
||||
'swwm_progress_conga', // CONGA
|
||||
'swwm_progress_explogun', // EXPLOGUN
|
||||
'swwm_progress_gravity', // GRAVITY
|
||||
'swwm_progress_flight', // FLIGHT
|
||||
'swwm_progress_allitems',
|
||||
'swwm_progress_conga',
|
||||
'swwm_progress_explogun',
|
||||
'swwm_progress_gravity',
|
||||
'swwm_progress_flight',
|
||||
'None', // CLIFFYB
|
||||
'swwm_progress_par', // PAR
|
||||
'swwm_progress_par',
|
||||
'None', // ONEGUY
|
||||
'swwm_progress_golden', // GOLDEN
|
||||
'swwm_progress_gib', // GIB
|
||||
'swwm_progress_barrier', // BARRIER
|
||||
'swwm_progress_bossdash', // BOSSDASH
|
||||
'swwm_progress_sneeze', // SNEEZE
|
||||
'swwm_progress_fuel', // FUEL
|
||||
'swwm_progress_slayer', // SLAYER
|
||||
'swwm_progress_golden',
|
||||
'swwm_progress_gib',
|
||||
'swwm_progress_barrier',
|
||||
'swwm_progress_bossdash',
|
||||
'swwm_progress_sneeze',
|
||||
'swwm_progress_fuel',
|
||||
'swwm_progress_slayer',
|
||||
'None', // BROCCOLIDOCCOLI
|
||||
'None', // DIME
|
||||
'swwm_progress_stomp', // STOMP
|
||||
'swwm_progress_stomp',
|
||||
'None', // CHEAT
|
||||
'None', // GOD
|
||||
'swwm_progress_thruwall', // THRUWALL
|
||||
'swwm_progress_thruwall',
|
||||
'None', // MASHIRO
|
||||
'swwm_progress_lead', // LEAD
|
||||
'swwm_progress_love', // LOVE
|
||||
'swwm_progress_butts', // BUTTS
|
||||
'swwm_progress_plush', // PLUSH
|
||||
'swwm_progress_bustin', // BUSTIN
|
||||
'swwm_progress_moth', // MOTH
|
||||
'None', // IWAD
|
||||
'swwm_progress_brake', // BRAKE
|
||||
'swwm_progress_rage', // RAGE
|
||||
'swwm_progress_lead',
|
||||
'swwm_progress_love',
|
||||
'swwm_progress_butts',
|
||||
'swwm_progress_plush',
|
||||
'swwm_progress_bustin',
|
||||
'swwm_progress_moth',
|
||||
'swwm_progress_iwad',
|
||||
'swwm_progress_brake',
|
||||
'swwm_progress_rage',
|
||||
'None', // ABORT
|
||||
'swwm_progress_parry', // PARRY
|
||||
'swwm_progress_allkills', // ALLKILLS
|
||||
'swwm_progress_allsecrets', // ALLSECRETS
|
||||
'swwm_progress_reflect', // REFLECT
|
||||
'swwm_progress_parry',
|
||||
'swwm_progress_allkills',
|
||||
'swwm_progress_allsecrets',
|
||||
'swwm_progress_reflect',
|
||||
'None', // SEKIRO
|
||||
'swwm_progress_wave', // WAVE
|
||||
'swwm_progress_friend', // FRIEND
|
||||
'swwm_progress_shock', // SHOCK
|
||||
'swwm_progress_balls', // BALLS
|
||||
'swwm_progress_refresh', // REFRESH
|
||||
'swwm_progress_step', // STEP
|
||||
'swwm_progress_sunny', // SUNNY
|
||||
'swwm_progress_thicc', // THICC
|
||||
'None', // WAVE
|
||||
'swwm_progress_friend',
|
||||
'swwm_progress_shock',
|
||||
'swwm_progress_balls',
|
||||
'swwm_progress_refresh',
|
||||
'swwm_progress_step',
|
||||
'swwm_progress_sunny',
|
||||
'swwm_progress_thicc',
|
||||
'None', // EVERYTHING
|
||||
'swwm_progress_allcoll', // ALLCOLL
|
||||
'swwm_progress_slemg', // SLEMG
|
||||
'swwm_progress_dosh', // DOSH
|
||||
'swwm_progress_jump', // JUMP
|
||||
'swwm_progress_ezkill', // EZKILL
|
||||
'swwm_progress_allcoll',
|
||||
'swwm_progress_slemg',
|
||||
'swwm_progress_dosh',
|
||||
'swwm_progress_jump',
|
||||
'swwm_progress_ezkill',
|
||||
'None', // LIGMA
|
||||
'None', // YEET
|
||||
'None', // MBF
|
||||
'None', // LIGHTNING
|
||||
'swwm_progress_dakka', // DAKKA
|
||||
'swwm_progress_roast', // ROAST
|
||||
'swwm_progress_dab', // DAB
|
||||
'swwm_progress_hnd', // HND
|
||||
'swwm_progress_gepgun', // GEPGUN
|
||||
'swwm_progress_dakka',
|
||||
'swwm_progress_roast',
|
||||
'swwm_progress_dab',
|
||||
'swwm_progress_hnd',
|
||||
'swwm_progress_gepgun',
|
||||
'None', // FULLER
|
||||
'swwm_progress_pene', // PENE
|
||||
'swwm_progress_acid', // ACID
|
||||
'swwm_progress_pene',
|
||||
'swwm_progress_acid',
|
||||
'None', // SALT
|
||||
'swwm_progress_mega', // MEGA
|
||||
'swwm_progress_sanic', // SANIC
|
||||
'swwm_progress_mega',
|
||||
'swwm_progress_sanic',
|
||||
'None', // TELE
|
||||
'swwm_progress_bune', // BUNE
|
||||
'swwm_progress_bonk', // BONK
|
||||
'swwm_progress_anom', // ANOM
|
||||
'swwm_progress_bune',
|
||||
'swwm_progress_bonk',
|
||||
'swwm_progress_anom',
|
||||
'None', // ANONE
|
||||
'None', // TETRIS
|
||||
'None', // PONG
|
||||
'None', // SNAKE
|
||||
'None', // SMB
|
||||
'None', // TYRIAN
|
||||
'None' // BOF
|
||||
'None', // BOF
|
||||
'None' // WANTDIE
|
||||
};
|
||||
achievements.Clear();
|
||||
for ( int i=0; i<vars.Size(); i++ )
|
||||
|
|
@ -817,6 +822,7 @@ Class DemolitionistMenu : GenericMenu
|
|||
else if ( vars[i] == 'swwm_achievement_dakka' ) ac.maxval = 60;
|
||||
else if ( vars[i] == 'swwm_achievement_dosh' ) ac.maxval = 1000000000;
|
||||
else if ( vars[i] == 'swwm_achievement_mega' ) ac.maxval = 1000000;
|
||||
else if ( vars[i] == 'swwm_achievement_iwad' ) ac.maxval = 7;
|
||||
achievements.Push(ac);
|
||||
}
|
||||
AchievementUnknown = TexMan.CheckForTexture("graphics/Achievements/AchievementUnknown.png",TexMan.Type_Any);
|
||||
|
|
@ -2662,13 +2668,33 @@ Class DemolitionistMenu : GenericMenu
|
|||
double afactor = adone?1.:0., bfactor = bdone?1.:0.;
|
||||
if ( a.progress )
|
||||
{
|
||||
int cur = min(a.progress.GetInt(),a.maxval);
|
||||
afactor = cur/double(a.maxval);
|
||||
int val = a.progress.GetInt();
|
||||
int mval = a.maxval;
|
||||
if ( a.tag == "$SWWM_ACHIEVEMENT_IWAD_TAG" )
|
||||
{
|
||||
// special case
|
||||
mval = 3;
|
||||
int bits = val;
|
||||
val = 0;
|
||||
for ( int i=0; i<3; i++ ) if ( bits&(1<<i) ) val++;
|
||||
}
|
||||
int cur = min(val,mval);
|
||||
afactor = cur/double(mval);
|
||||
}
|
||||
if ( b.progress )
|
||||
{
|
||||
int cur = min(b.progress.GetInt(),b.maxval);
|
||||
bfactor = cur/double(b.maxval);
|
||||
int val = b.progress.GetInt();
|
||||
int mval = b.maxval;
|
||||
if ( b.tag == "$SWWM_ACHIEVEMENT_IWAD_TAG" )
|
||||
{
|
||||
// special case
|
||||
mval = 3;
|
||||
int bits = val;
|
||||
val = 0;
|
||||
for ( int i=0; i<3; i++ ) if ( bits&(1<<i) ) val++;
|
||||
}
|
||||
int cur = min(val,mval);
|
||||
bfactor = cur/double(mval);
|
||||
}
|
||||
if ( adone && bdone )
|
||||
{
|
||||
|
|
@ -3054,7 +3080,7 @@ Class DemolitionistMenu : GenericMenu
|
|||
statlist.Push(str);
|
||||
str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATSTOMP"),stats.stompcount);
|
||||
statlist.Push(str);
|
||||
str = String.Format("\cx%s\c-%g\cu%s\c-",StringTable.Localize("$SWWM_STATFUEL"),stats.fuelusage/60.,StringTable.Localize("$SWWM_UNIT_LITER"));
|
||||
str = String.Format("\cx%s\c-%g\cu%s\c-",StringTable.Localize("$SWWM_STATFUEL"),stats.fuelusage,StringTable.Localize("$SWWM_UNIT_LITER"));
|
||||
statlist.Push(str);
|
||||
str = String.Format("\cx%s\c-%g\cu%s\c-",StringTable.Localize("$SWWM_STATSPEED"),(stats.topspeed*3600.*GameTicRate)/32000.,StringTable.Localize("$SWWM_UNIT_KPH"));
|
||||
statlist.Push(str);
|
||||
|
|
@ -3614,17 +3640,28 @@ Class DemolitionistMenu : GenericMenu
|
|||
// progress bar
|
||||
if ( a.progress )
|
||||
{
|
||||
if ( completed ) str = SWWMUtility.BlockBar(a.maxval,a.maxval,barsz,Font.CR_GOLD,Font.CR_BLACK);
|
||||
else str = SWWMUtility.BlockBar(a.progress.GetInt(),a.maxval,barsz,Font.CR_DARKGRAY,Font.CR_BLACK);
|
||||
int val = a.progress.GetInt();
|
||||
int mval = a.maxval;
|
||||
if ( a.tag == "$SWWM_ACHIEVEMENT_IWAD_TAG" )
|
||||
{
|
||||
// special case
|
||||
mval = 3;
|
||||
int bits = val;
|
||||
val = 0;
|
||||
for ( int i=0; i<3; i++ ) if ( bits&(1<<i) ) val++;
|
||||
}
|
||||
val = clamp(val,0,mval);
|
||||
if ( completed ) str = SWWMUtility.BlockBar(mval,mval,barsz,Font.CR_DARKGREEN,Font.CR_BLACK);
|
||||
else str = SWWMUtility.BlockBar(val,mval,barsz,Font.CR_DARKGRAY,Font.CR_BLACK);
|
||||
Screen.DrawText(TewiFont,Font.CR_UNTRANSLATED,origin.x+xx,origin.y+yy+34,str,DTA_Spacing,-5,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
||||
if ( completed ) str = String.Format("%s / %s",SWWMUtility.ThousandsNum(a.maxval),SWWMUtility.ThousandsNum(a.maxval));
|
||||
else str = String.Format("%s / %s",SWWMUtility.ThousandsNum(a.progress.GetInt()),SWWMUtility.ThousandsNum(a.maxval));
|
||||
if ( completed ) str = String.Format("%s / %s",SWWMUtility.ThousandsNum(mval),SWWMUtility.ThousandsNum(mval));
|
||||
else str = String.Format("%s / %s",SWWMUtility.ThousandsNum(val),SWWMUtility.ThousandsNum(mval));
|
||||
int ox = (barsz-MiniwiFont.StringWidth(str))/2;
|
||||
Screen.DrawText(MiniwiFont,Font.CR_WHITE,origin.x+xx+ox,origin.y+yy+38,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
||||
Screen.DrawText(MiniwiFont,completed?Font.CR_GREEN:hasprogress?Font.CR_WHITE:Font.CR_DARKGRAY,origin.x+xx+ox,origin.y+yy+37,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
||||
}
|
||||
else
|
||||
{
|
||||
str = SWWMUtility.BlockBar(completed,1,barsz,Font.CR_GOLD,Font.CR_BLACK);
|
||||
str = SWWMUtility.BlockBar(completed,1,barsz,Font.CR_DARKGREEN,Font.CR_BLACK);
|
||||
Screen.DrawText(TewiFont,Font.CR_UNTRANSLATED,origin.x+xx,origin.y+yy+34,str,DTA_Spacing,-5,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
||||
}
|
||||
// the text itself
|
||||
|
|
|
|||
|
|
@ -56,6 +56,25 @@ Class SWWMGesture : SWWMWeapon
|
|||
if ( !psp ) return;
|
||||
if ( (Owner.Health <= 0) && (psp.CurState != ResolveState("Deselect")) )
|
||||
Owner.player.SetPSprite(PSP_WEAPON,ResolveState("Deselect"));
|
||||
// check if we're waving at a dying enemy
|
||||
if ( (psp.frame >= 3) && (psp.frame <= 12) && (psp.sprite == GetSpriteIndex('XZW1')) )
|
||||
CheckWave();
|
||||
}
|
||||
|
||||
private void CheckWave()
|
||||
{
|
||||
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
|
||||
if ( !hnd ) return;
|
||||
for ( int i=0; i<hnd.suckableactors.Size(); i++ )
|
||||
{
|
||||
let a = hnd.suckableactors[i];
|
||||
if ( !a || (a.Health > 0) || (a.tics == -1) || !(a.bISMONSTER || a.player) || !a.IsHostile(Owner) ) continue;
|
||||
// check if we can see it
|
||||
if ( !SWWMUtility.InPlayerFOV(Owner.player,a) ) continue;
|
||||
// someone's dying
|
||||
SWWMUtility.MarkAchievement('swwm_achievement_wave',Owner.player);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static SWWMGesture SetGesture( PlayerPawn mo, int which )
|
||||
|
|
@ -232,6 +251,7 @@ Class SWWMGesture : SWWMWeapon
|
|||
{
|
||||
let s = Demolitionist(self).mystats;
|
||||
if ( s ) s.befriend++;
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_friend',1,player);
|
||||
}
|
||||
t.bFRIENDLY = true;
|
||||
if ( deathmatch )
|
||||
|
|
|
|||
|
|
@ -462,6 +462,7 @@ Class HeadpatTracker : Actor
|
|||
patter.player.cheats |= CF_TOTALLYFROZEN;
|
||||
Demolitionist(patter).scriptedinvul = true;
|
||||
target.bDORMANT = true;
|
||||
if ( SWWMUtility.IdentifyingDog(target) ) SWWMUtility.MarkAchievement('swwm_achievement_mbf',user.player);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -110,9 +110,10 @@ Class SWWMHandler : EventHandler
|
|||
if ( !(e.ActivationType&SPAC_Use) ) return;
|
||||
if ( !e.Thing || !e.Thing.player ) return;
|
||||
let w = SWWMWeapon(e.Thing.player.ReadyWeapon);
|
||||
if ( !w || !w.wallponch ) return;
|
||||
if ( (!w || !w.wallponch) && (!(e.Thing is 'Demolitionist') || !Demolitionist(e.Thing).hitactivate) ) return;
|
||||
let s = SWWMStats.Find(e.Thing.player);
|
||||
if ( s ) s.wponch++;
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_slemg',1,e.Thing.player);
|
||||
}
|
||||
|
||||
// stuff for hud
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ Class Demolitionist : PlayerPawn
|
|||
Vector3 dashdir;
|
||||
double dashfuel, dashboost;
|
||||
int dashcooldown, boostcooldown, fuelcooldown;
|
||||
bool fullfuel;
|
||||
bool sendtoground;
|
||||
bool key_reentrant;
|
||||
bool bInDefaultInventory;
|
||||
|
|
@ -55,6 +56,7 @@ Class Demolitionist : PlayerPawn
|
|||
Actor selflight;
|
||||
Actor oldencroached;
|
||||
Vector3 oldencroachedpos;
|
||||
int encroachtics;
|
||||
|
||||
Vector3 pretelepos;
|
||||
|
||||
|
|
@ -63,6 +65,7 @@ Class Demolitionist : PlayerPawn
|
|||
|
||||
int healcooldown, healtimer, oldhealth;
|
||||
bool scriptedinvul;
|
||||
bool hitactivate;
|
||||
|
||||
transient int lastuse, failcounter, failcooldown;
|
||||
|
||||
|
|
@ -445,24 +448,28 @@ Class Demolitionist : PlayerPawn
|
|||
}
|
||||
void A_Dash()
|
||||
{
|
||||
vel += dashdir*dashboost;
|
||||
vel += dashdir*dashboost*clamp(dashfuel/20.,0.,1.);
|
||||
player.vel *= 0.;
|
||||
if ( dashboost < .2 ) dashboost = 0.;
|
||||
else
|
||||
{
|
||||
if ( swwm_extraalert ) A_AlertMonsters(swwm_uncapalert?0:800);
|
||||
dashboost *= (player.cmd.buttons&BT_USER2)?.9:.1;
|
||||
if ( !(player.cmd.buttons&BT_USER2) ) dashboost *= .1;
|
||||
}
|
||||
mystats.fuelusage += dashfuel-max(0.,dashfuel-dashboost);
|
||||
double fueluse = (dashfuel-max(0.,dashfuel-dashboost))/60.;
|
||||
SWWMUtility.AchievementProgressIncDouble('swwm_progress_fuel',fueluse,player);
|
||||
mystats.fuelusage += fueluse;
|
||||
if ( !swwm_superfuel ) dashfuel = max(0.,dashfuel-dashboost);
|
||||
dashcooldown = min(40,max(10,int(dashcooldown*1.4)));
|
||||
fuelcooldown = max(30,fuelcooldown);
|
||||
if ( (dashfuel <= 0.) && fullfuel )
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_brake',1,player);
|
||||
if ( (dashfuel <= 0.) || (dashboost <= 0.) )
|
||||
SetStateLabel("DashEnd");
|
||||
}
|
||||
void A_BoostUp( bool initial = false )
|
||||
{
|
||||
vel += (0,0,1)*dashboost;
|
||||
vel += (0,0,1)*dashboost*clamp(dashfuel/10.,0,1.);
|
||||
player.vel *= 0.;
|
||||
if ( dashboost < .2 ) dashboost = 0.;
|
||||
else
|
||||
|
|
@ -471,7 +478,9 @@ Class Demolitionist : PlayerPawn
|
|||
dashboost *= (player.cmd.buttons&BT_JUMP)?.95:.4;
|
||||
last_boost = level.maptime+1;
|
||||
}
|
||||
mystats.fuelusage += dashfuel-max(0.,dashfuel-dashboost);
|
||||
double fueluse = (dashfuel-max(0.,dashfuel-dashboost))/60.;
|
||||
SWWMUtility.AchievementProgressIncDouble('swwm_progress_fuel',fueluse,player);
|
||||
mystats.fuelusage += fueluse;
|
||||
if ( !swwm_superfuel ) dashfuel = max(0.,dashfuel-dashboost);
|
||||
if ( ((dashfuel <= 0.) || (dashboost <= 0.)) )
|
||||
{
|
||||
|
|
@ -863,6 +872,8 @@ Class Demolitionist : PlayerPawn
|
|||
CheckUnderwaterAmb();
|
||||
if ( player.cmd.buttons&BT_USER3 ) SenseItems();
|
||||
if ( vel.length() > mystats.topspeed ) mystats.topspeed = vel.length();
|
||||
if ( vel.length() > ((3600*GameTicRate)/32000.) )
|
||||
SWWMUtility.AchievementProgress('swwm_progress_sanic',int((vel.length()*3600*GameTicRate)/32000.),player);
|
||||
if ( !myvoice ) myvoice = CVar.GetCVar('swwm_voicetype',player);
|
||||
if ( player.onground && !bNoGravity && !lastground && (waterlevel < 2) )
|
||||
{
|
||||
|
|
@ -942,7 +953,11 @@ Class Demolitionist : PlayerPawn
|
|||
SetOrigin(newp,true);
|
||||
if ( !TestMobjLocation() ) SetOrigin(oldp,true);
|
||||
}
|
||||
encroachtics++;
|
||||
if ( !(encroachtics%GameTicRate) )
|
||||
SWWMUtility.AchievementProgress('swwm_progress_step',encroachtics/GameTicRate,player);
|
||||
}
|
||||
else encroachtics = 0;
|
||||
oldencroached = encroached;
|
||||
oldencroachedpos = encroached.pos;
|
||||
}
|
||||
|
|
@ -952,6 +967,7 @@ Class Demolitionist : PlayerPawn
|
|||
// make sure we're not getting launched because an enemy just died under our feet, because that can cause some issues
|
||||
if ( oldencroached && (dashboost <= 0.) && (lastvelz >= -25) && (!oldencroached.bISMONSTER || (oldencroached.Health > 0)) ) vel += oldencroached.vel+level.Vec3Diff(oldencroachedpos,oldencroached.pos);
|
||||
oldencroached = null;
|
||||
encroachtics = 0;
|
||||
}
|
||||
if ( encroached && encroached.bSHOOTABLE && !encroached.bNODAMAGE && (lastvelz <= 0) && !(encroached is 'Demolitionist') )
|
||||
{
|
||||
|
|
@ -965,7 +981,7 @@ Class Demolitionist : PlayerPawn
|
|||
ps.target = self;
|
||||
ps.special1 = realdmg;
|
||||
}
|
||||
if ( !encroached.bNOBLOOD && !encroached.bINVULNERABLE )
|
||||
if ( encroached && !encroached.bNOBLOOD && !encroached.bINVULNERABLE )
|
||||
{
|
||||
encroached.TraceBleed(realdmg,self);
|
||||
encroached.SpawnBlood(pos,angle,realdmg);
|
||||
|
|
@ -1046,6 +1062,7 @@ Class Demolitionist : PlayerPawn
|
|||
else if ( diff.y < -(a.Radius+Radius) ) bnorm = (0,1,0);
|
||||
if ( dir dot bnorm > -.6 ) continue;
|
||||
}
|
||||
if ( !CheckSight(a,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) continue;
|
||||
// large monsters will stop the player (unless hit from above if we're going at ground pound speed)
|
||||
A_QuakeEx(4,4,4,10,0,128,"",QF_RELATIVE|QF_SCALEDOWN);
|
||||
A_AlertMonsters(swwm_uncapalert?0:800);
|
||||
|
|
@ -1057,6 +1074,7 @@ Class Demolitionist : PlayerPawn
|
|||
{
|
||||
if ( bumped ) continue;
|
||||
bumped = true;
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_bonk',1,player);
|
||||
A_QuakeEx(8,8,8,16,0,128,"",QF_RELATIVE|QF_SCALEDOWN);
|
||||
vel *= .2;
|
||||
vel -= dir*(10+(spd*30/mass));
|
||||
|
|
@ -1166,6 +1184,7 @@ Class Demolitionist : PlayerPawn
|
|||
{
|
||||
// headbump
|
||||
bumped = true;
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_bonk',1,player);
|
||||
A_StartSound("demolitionist/bump",CHAN_DAMAGE,CHANF_OVERLAP);
|
||||
bumptic = gametic+int(20+spd/4.);
|
||||
lastbump *= .8;
|
||||
|
|
@ -1260,6 +1279,7 @@ Class Demolitionist : PlayerPawn
|
|||
}
|
||||
// wallbump
|
||||
bumped = true;
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_bonk',1,player);
|
||||
A_StartSound("demolitionist/bump",CHAN_DAMAGE,CHANF_OVERLAP);
|
||||
bumptic = gametic+int(25+spd/4.);
|
||||
lastbump *= .8;
|
||||
|
|
@ -1281,7 +1301,11 @@ Class Demolitionist : PlayerPawn
|
|||
// activate it
|
||||
int locknum = SWWMUtility.GetLineLock(BlockingLine);
|
||||
if ( !locknum || CheckKeys(locknum,false,true) )
|
||||
{
|
||||
hitactivate = true;
|
||||
BlockingLine.Activate(self,lside,SPAC_Use);
|
||||
hitactivate = false;
|
||||
}
|
||||
BlockingLine.Activate(self,lside,SPAC_Impact);
|
||||
break;
|
||||
}
|
||||
|
|
@ -1391,6 +1415,8 @@ Class Demolitionist : PlayerPawn
|
|||
A_DemoPain();
|
||||
}
|
||||
PainChance = oldpchance;
|
||||
if ( (Health <= 0) && (source == self) && (flags&DMG_EXPLOSION) )
|
||||
SWWMUtility.MarkAchievement('swwm_achievement_dime',player);
|
||||
return realdmg;
|
||||
}
|
||||
override void CalcHeight()
|
||||
|
|
@ -1621,6 +1647,7 @@ Class Demolitionist : PlayerPawn
|
|||
}
|
||||
if ( (dodge.length() > 0) && (dashcooldown <= 0) && (dashfuel > 20.) && player.cmd.buttons&BT_USER2 && (player.onground || level.IsJumpingAllowed() || (player.cmd.buttons&BT_CROUCH)) && (gamestate == GS_LEVEL) )
|
||||
{
|
||||
fullfuel = (dashfuel >= default.dashfuel);
|
||||
dashdir = dodge.unit();
|
||||
dashcooldown = 10;
|
||||
dashboost = 20.;
|
||||
|
|
@ -1759,6 +1786,7 @@ Class Demolitionist : PlayerPawn
|
|||
{
|
||||
A_StartSound("demolitionist/kick",CHAN_FOOTSTEP,CHANF_OVERLAP);
|
||||
last_kick = level.maptime+1;
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_jump',1,player);
|
||||
}
|
||||
}
|
||||
bOnMobj = false;
|
||||
|
|
@ -1789,6 +1817,7 @@ Class Demolitionist : PlayerPawn
|
|||
// bunnyhop time
|
||||
if ( (player.cmd.buttons&BT_RUN) && (level.maptime < (lastairtic+10)) && !walljump && !wallclimb )
|
||||
{
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_bune',1,player);
|
||||
// bhop, z vel relative to vel size
|
||||
if ( vel.z < 25. ) // don't ramp up too hard
|
||||
vel.z += jumpvelz*(1.2+vel.length()*.01);
|
||||
|
|
@ -1863,6 +1892,7 @@ Class Demolitionist : PlayerPawn
|
|||
// reboot (if possible)
|
||||
if ( !FindInventory("ReviveCooldown") && (((swwm_revivecooldown >= 0) && (G_SkillPropertyInt(SKILLP_ACSReturn) < 4)) || !hasrevived) )
|
||||
{
|
||||
if ( hasrevived ) SWWMUtility.MarkAchievement('swwm_achievement_sekiro',player);
|
||||
hasrevived = true;
|
||||
player.Resurrect();
|
||||
player.damagecount = 0;
|
||||
|
|
@ -2265,6 +2295,7 @@ Class Demolitionist : PlayerPawn
|
|||
if ( hnd ) hnd.allsecrets = true;
|
||||
score = 1000;
|
||||
Console.Printf(StringTable.Localize("$SWWM_LASTSECRET"),player.GetUserName(),score);
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_allsecrets',1,player);
|
||||
}
|
||||
else Console.Printf(StringTable.Localize("$SWWM_FINDSECRET"),player.GetUserName(),score);
|
||||
if ( CheckLocalView() ) SWWMHandler.AddOneliner("findsecret",2,40);
|
||||
|
|
|
|||
|
|
@ -51,6 +51,13 @@ Class SWWMStaticHandler : StaticEventHandler
|
|||
Demolitionist(players[i].mo).CheckUnderwaterAmb(true);
|
||||
}
|
||||
}
|
||||
if ( players[consoleplayer].mo )
|
||||
{
|
||||
// recheck progress on collectibles
|
||||
int nc = 0;
|
||||
for ( Inventory i=players[consoleplayer].mo.inv; i; i=i.inv ) if ( i is 'SWWMCollectible' ) nc++;
|
||||
if ( !swwm_achievement_allcoll ) CVar.FindCVar('swwm_progress_allcoll').SetInt(nc);
|
||||
}
|
||||
SWWMHandler.ClearAllShaders(players[consoleplayer]);
|
||||
// force a reset of the minimap zoom in case it's set beyond safe levels
|
||||
double mmz = swwm_mm_zoom;
|
||||
|
|
@ -93,6 +100,13 @@ Class SWWMStaticHandler : StaticEventHandler
|
|||
Font.GetFont('TewiShaded');
|
||||
Font.GetFont('TewiShadedInverse');
|
||||
Font.GetFont('SWWMBigFont');
|
||||
// iwad progress
|
||||
if ( gameinfo.gametype&GAME_Doom )
|
||||
SWWMUtility.AchievementProgressOr('swwm_progress_iwad',1,players[consoleplayer]);
|
||||
else if ( gameinfo.gametype&GAME_Heretic )
|
||||
SWWMUtility.AchievementProgressOr('swwm_progress_iwad',2,players[consoleplayer]);
|
||||
else if ( gameinfo.gametype&GAME_Hexen )
|
||||
SWWMUtility.AchievementProgressOr('swwm_progress_iwad',4,players[consoleplayer]);
|
||||
}
|
||||
|
||||
override void ConsoleProcess( ConsoleEvent e )
|
||||
|
|
@ -118,6 +132,34 @@ Class SWWMStaticHandler : StaticEventHandler
|
|||
for ( int i=0; i<mmvars.Size(); i++ )
|
||||
CVar.FindCVar(mmvars[i]).ResetToDefault();
|
||||
}
|
||||
else if ( e.Name ~== "swwmgetplaytime" )
|
||||
{
|
||||
int val = swwm_playtime;
|
||||
int sec = (val%60);
|
||||
int min = ((val/60)%60);
|
||||
int hour = ((val/3600)%24);
|
||||
int day = val/86400;
|
||||
String str = "";
|
||||
if ( day ) str.AppendFormat("%d days",day);
|
||||
if ( hour )
|
||||
{
|
||||
if ( str != "" ) str = str..", ";
|
||||
str.AppendFormat("%d hours",hour);
|
||||
}
|
||||
if ( min )
|
||||
{
|
||||
if ( str != "" ) str = str..", ";
|
||||
str.AppendFormat("%d minutes",min);
|
||||
}
|
||||
if ( sec )
|
||||
{
|
||||
if ( str != "" ) str = str..", ";
|
||||
str.AppendFormat("%d seconds",sec);
|
||||
}
|
||||
if ( str == "" ) Console.Printf("No Data");
|
||||
else Console.Printf(str);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
override void NetworkProcess( ConsoleEvent e )
|
||||
|
|
@ -161,6 +203,12 @@ Class SWWMStaticHandler : StaticEventHandler
|
|||
|
||||
override void PostUiTick()
|
||||
{
|
||||
if ( (gametic > 0) && !(gametic%GameTicRate) )
|
||||
{
|
||||
let pt = CVar.FindCVar('swwm_playtime');
|
||||
int ct = pt.GetInt();
|
||||
pt.SetInt(ct+1);
|
||||
}
|
||||
if ( gamestate != GS_LEVEL ) return;
|
||||
CheckAllAchievements();
|
||||
if ( !mpsent )
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ Class SWWMDamageAccumulator : Thinker
|
|||
{
|
||||
Super.Tick();
|
||||
// so many damn safeguards in this
|
||||
if ( !victim )
|
||||
if ( !victim || (victim.Health <= 0) )
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
|
|
@ -396,3 +396,42 @@ Class SWWMCorpseCleaner : Thinker
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Class SWWMFlyTracker : Thinker
|
||||
{
|
||||
Actor tracked, instigator;
|
||||
Vector3 startpos;
|
||||
int gracepd;
|
||||
|
||||
static void Track( Actor b, Actor whomst )
|
||||
{
|
||||
if ( !b || !whomst ) return;
|
||||
let ti = ThinkerIterator.Create("SWWMFlyTracker",STAT_USER);
|
||||
SWWMFlyTracker ffd;
|
||||
while ( ffd = SWWMFlyTracker(ti.Next()) )
|
||||
{
|
||||
if ( ffd.tracked != b ) continue;
|
||||
ffd.instigator = whomst;
|
||||
return;
|
||||
}
|
||||
ffd = new("SWWMFlyTracker");
|
||||
ffd.ChangeStatNum(STAT_USER);
|
||||
ffd.tracked = b;
|
||||
ffd.instigator = whomst;
|
||||
ffd.startpos = b.pos;
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
if ( !tracked || tracked.bFLOAT || tracked.bNOGRAVITY || (tracked.waterlevel > 1) || (tracked.pos.z <= tracked.floorz) || !tracked.TestMobjZ(false) )
|
||||
{
|
||||
gracepd++;
|
||||
if ( gracepd < 10 ) return;
|
||||
if ( instigator ) SWWMUtility.AchievementProgress('swwm_progress_flight',int(level.Vec3Diff(startpos,tracked.pos).length()),instigator.player);
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
gracepd = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ Class SWWMStats : Thinker
|
|||
Array<bool> secretdone;
|
||||
// hackaround for stuff getting lost
|
||||
Array<Class<SWWMCollectible> > ownedcollectibles;
|
||||
int plushuses;
|
||||
// for pistol start info (to avoid it within hubs)
|
||||
int lastcluster;
|
||||
|
||||
|
|
@ -61,7 +62,7 @@ Class SWWMStats : Thinker
|
|||
Class<Weapon> which = myplayer.ReadyWeapon?myplayer.ReadyWeapon.GetClass():null;
|
||||
if ( inflictor is 'Weapon' ) which = Weapon(inflictor).GetClass();
|
||||
if ( which is 'DualExplodiumGun' ) which = 'ExplodiumGun'; // don't credit sister weapon
|
||||
if ( inflictor.FindInventory("ParriedBuff") ) which = 'DoomWeapon'; // gross hack
|
||||
if ( inflictor && inflictor.FindInventory("ParriedBuff") ) which = 'DoomWeapon'; // gross hack
|
||||
// properly credit some projectiles to their respective gun
|
||||
else if ( inflictor is 'AirBullet' ) which = 'DeepImpact';
|
||||
else if ( inflictor is 'PusherProjectile' ) which = 'PusherWeapon';
|
||||
|
|
@ -200,6 +201,14 @@ Class SWWMCredits : Thinker
|
|||
{
|
||||
PlayerInfo myplayer;
|
||||
int credits, hcredits;
|
||||
bool cheated;
|
||||
|
||||
static void HasCheated( PlayerInfo p )
|
||||
{
|
||||
let c = Find(p);
|
||||
if ( !c ) return;
|
||||
c.cheated = true;
|
||||
}
|
||||
|
||||
static void Give( PlayerInfo p, int amount, int hamount = 0 )
|
||||
{
|
||||
|
|
@ -220,6 +229,9 @@ Class SWWMCredits : Thinker
|
|||
s.hiscore = c.credits;
|
||||
s.hhiscore = c.hcredits;
|
||||
}
|
||||
if ( c.cheated ) return;
|
||||
if ( c.hcredits > 0 ) SWWMUtility.AchievementProgress('swwm_progress_dosh',1000000000,p);
|
||||
else SWWMUtility.AchievementProgress('swwm_progress_dosh',c.credits,p);
|
||||
}
|
||||
|
||||
static clearscope bool CanTake( PlayerInfo p, int amount, int hamount = 0 )
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ enum EDoExplosionFlags
|
|||
DE_NOTMISSILE = 16, // instigator is the source itself (normally it'd be its target pointer)
|
||||
DE_EXTRAZTHRUST = 32, // applies a higher Z thrust to enemies on ground
|
||||
DE_HOWL = 64, // 25% chance for hit enemies to howl
|
||||
DE_COUNTENEMIES = 128, // only count hits for hostiles
|
||||
DE_COUNTSTEALTH = 256, // only count hits for inactive monsters
|
||||
};
|
||||
|
||||
Class SWWMUtility
|
||||
|
|
@ -899,13 +901,15 @@ Class SWWMUtility
|
|||
if ( (flags&DE_BLAST) && a.bCANBLAST && !a.bDONTBLAST ) a.bBLASTED = true;
|
||||
}
|
||||
// hit it
|
||||
nhit++;
|
||||
bool inactive = (!a.player&&!a.target);
|
||||
bool hostile = (Instigator&&a.IsHostile(Instigator)&&(a.bISMONSTER||a.player));
|
||||
if ( (!(flags&DE_COUNTENEMIES) || hostile) && (!(flags&DE_COUNTSTEALTH) || inactive) ) nhit++;
|
||||
int dmg = int(Damage*damagescale);
|
||||
if ( dmg <= 0 ) continue; // no harm
|
||||
int ndmg = a.DamageMobj(Source,Instigator,dmg,(DamageType=='')?Source.DamageType:DamageType,DMG_EXPLOSION,atan2(-dir.y,-dir.x));
|
||||
if ( a && !(flags&DE_NOBLEED) ) a.TraceBleed((ndmg>0)?ndmg:dmg,Source);
|
||||
if ( (flags&DE_HOWL) && a && a.bISMONSTER && !Random[DoBlast](0,3) ) a.Howl();
|
||||
if ( !a || (a.Health <= 0) ) nkill++;
|
||||
if ( (flags&DE_HOWL) && a && (a.Health > 0) && a.bISMONSTER && !Random[DoBlast](0,3) ) a.Howl();
|
||||
if ( (!a || (a.Health <= 0)) && (!(flags&DE_COUNTENEMIES) || hostile) && (!(flags&DE_COUNTSTEALTH) || inactive) ) nkill++;
|
||||
}
|
||||
return nhit, nkill;
|
||||
}
|
||||
|
|
@ -1625,6 +1629,47 @@ Class SWWMUtility
|
|||
return false, checkme;
|
||||
}
|
||||
|
||||
// achievement helpers
|
||||
static clearscope void MarkAchievement( Name mvar, PlayerInfo p = null )
|
||||
{
|
||||
if ( !p || (p != players[consoleplayer]) ) return;
|
||||
let cv = CVar.FindCVar(mvar);
|
||||
if ( !cv ) return;
|
||||
if ( cv.GetInt() < 1 ) cv.SetInt(1);
|
||||
}
|
||||
static clearscope void AchievementProgress( Name pvar, int val, PlayerInfo p = null )
|
||||
{
|
||||
if ( !p || (p != players[consoleplayer]) ) return;
|
||||
let cv = CVar.FindCVar(pvar);
|
||||
if ( !cv ) return;
|
||||
int cval = cv.GetInt();
|
||||
cv.SetInt(max(cval,val));
|
||||
}
|
||||
static clearscope void AchievementProgressInc( Name pvar, int inc, PlayerInfo p = null )
|
||||
{
|
||||
if ( !p || (p != players[consoleplayer]) ) return;
|
||||
let cv = CVar.FindCVar(pvar);
|
||||
if ( !cv ) return;
|
||||
int cval = cv.GetInt();
|
||||
cv.SetInt(cval+inc);
|
||||
}
|
||||
static clearscope void AchievementProgressIncDouble( Name pvar, double inc, PlayerInfo p = null )
|
||||
{
|
||||
if ( !p || (p != players[consoleplayer]) ) return;
|
||||
let cv = CVar.FindCVar(pvar);
|
||||
if ( !cv ) return;
|
||||
double cval = cv.GetFloat();
|
||||
cv.SetFloat(cval+inc);
|
||||
}
|
||||
static clearscope void AchievementProgressOr( Name pvar, int val, PlayerInfo p = null )
|
||||
{
|
||||
if ( !p || (p != players[consoleplayer]) ) return;
|
||||
let cv = CVar.FindCVar(pvar);
|
||||
if ( !cv ) return;
|
||||
int cval = cv.GetInt();
|
||||
cv.SetInt(cval|val);
|
||||
}
|
||||
|
||||
// full reset of inventory (excluding collectibles, and optionally resetting the score)
|
||||
static play void WipeInventory( Actor mo, bool resetscore = false, bool allplayers = false )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ Class ParryField : Actor
|
|||
critsnd = true;
|
||||
}
|
||||
if ( s ) s.parries++;
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_parry',1,master.player);
|
||||
}
|
||||
if ( --special1 <= 0 ) Destroy();
|
||||
}
|
||||
|
|
@ -390,7 +391,10 @@ extend Class SWWMWeapon
|
|||
{
|
||||
int locknum = SWWMUtility.GetLineLock(ut.uses[i].hitline);
|
||||
if ( !locknum || CheckKeys(locknum,false,true) )
|
||||
{
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_slemg',1,player);
|
||||
ut.uses[i].hitline.RemoteActivate(self,ut.uses[i].hitside,SPAC_Use,ut.uses[i].pos);
|
||||
}
|
||||
if ( !(ut.uses[i].hitline.activation&SPAC_UseThrough) ) break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -546,14 +546,18 @@ Class HellblazerRavager : HellblazerMissile
|
|||
|
||||
Class HellblazerWarhead : HellblazerMissile
|
||||
{
|
||||
int nkill;
|
||||
|
||||
void A_BlazerWarheadExplode()
|
||||
{
|
||||
nkill = 0;
|
||||
bForceXYBillboard = true;
|
||||
bRollSprite = false;
|
||||
A_SetRenderStyle(1.0,STYLE_Add);
|
||||
A_SprayDecal("WumboRocketBlast",150);
|
||||
A_SetScale(7.);
|
||||
SWWMUtility.DoExplosion(self,1500,600000,400,200);
|
||||
int nhit;
|
||||
[nhit, nkill] = SWWMUtility.DoExplosion(self,1500,600000,400,200,DE_COUNTENEMIES);
|
||||
A_NoGravity();
|
||||
A_QuakeEx(9,9,9,150,0,12000,"",QF_RELATIVE|QF_SCALEDOWN,falloff:4000,rollIntensity:2.);
|
||||
A_StopSound(CHAN_BODY);
|
||||
|
|
@ -594,7 +598,11 @@ Class HellblazerWarhead : HellblazerMissile
|
|||
void A_WarheadSub()
|
||||
{
|
||||
if ( special1 < 40 )
|
||||
SWWMUtility.DoExplosion(self,320-special1*8,600000-special1*12000,200+special1*30);
|
||||
{
|
||||
int nhit, nkil;
|
||||
[nhit, nkil] = SWWMUtility.DoExplosion(self,320-special1*8,600000-special1*12000,200+special1*30,flags:DE_COUNTENEMIES);
|
||||
nkill += nkil;
|
||||
}
|
||||
special1++;
|
||||
if ( (special1 <= 30) && !(special1%2) )
|
||||
{
|
||||
|
|
@ -643,6 +651,7 @@ Class HellblazerWarhead : HellblazerMissile
|
|||
c.angle = ang;
|
||||
c.pitch = pt;
|
||||
c.target = target;
|
||||
c.master = self;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -658,9 +667,13 @@ Class HellblazerWarhead : HellblazerMissile
|
|||
TNT1 A 1
|
||||
{
|
||||
A_WarheadSub();
|
||||
A_FadeOut(.05);
|
||||
if ( special1 >= 40 )
|
||||
{
|
||||
if ( target ) SWWMUtility.AchievementProgress('swwm_progress_slayer',invoker.nkill,target.player);
|
||||
Destroy();
|
||||
}
|
||||
}
|
||||
Stop;
|
||||
Wait;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1221,7 +1234,9 @@ Class HellblazerWarheadArm : Actor
|
|||
TNT1 A 1
|
||||
{
|
||||
Spawn("HellblazerWarheadTrail",pos);
|
||||
SWWMUtility.DoExplosion(self,20+reactiontime*4,3000+500*reactiontime,120+4*reactiontime);
|
||||
int nhit, nkill;
|
||||
[nhit, nkill] = SWWMUtility.DoExplosion(self,20+reactiontime*4,3000+500*reactiontime,120+4*reactiontime,flags:DE_COUNTENEMIES);
|
||||
if ( HellblazerWarhead(master) ) HellblazerWarhead(master).nkill += nkill;
|
||||
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](1,5);
|
||||
let s = Spawn("SWWMHalfSmoke",pos);
|
||||
s.vel = pvel+vel*.2;
|
||||
|
|
|
|||
|
|
@ -421,6 +421,7 @@ Class Wallbuster : SWWMWeapon
|
|||
[x2, y2, z2] = swwm_CoordUtil.GetAxes(BulletSlope(),angle,roll);
|
||||
int alertness = 0;
|
||||
// second pass, play the fire effects
|
||||
int salts = 0;
|
||||
for ( int i=0; i<num; i++ )
|
||||
{
|
||||
// get physical index
|
||||
|
|
@ -446,12 +447,17 @@ Class Wallbuster : SWWMWeapon
|
|||
A_StartSound(sounds[which],CHAN_WEAPON,CHANF_OVERLAP,1./(howmany**rfact),.6-howmany*.004,1.-howmany*.015);
|
||||
if ( which == 0 ) redflashstr = max(120,redflashstr+10);
|
||||
else if ( which == 1 ) redflashstr = max(90,redflashstr+8);
|
||||
else if ( which == 2 ) blueflashstr = max(160,blueflashstr+10);
|
||||
else if ( which == 2 )
|
||||
{
|
||||
blueflashstr = max(160,blueflashstr+10);
|
||||
salts++;
|
||||
}
|
||||
else if ( which == 3 ) redflashstr = max(60,redflashstr+6);
|
||||
A_CBTFlash(flashes[which],i);
|
||||
if ( alertness > louds[which] ) alertness += louds[which]/4;
|
||||
else alertness += louds[which];
|
||||
}
|
||||
if ( salts >= 25 ) SWWMUtility.MarkAchievement('swwm_achievement_salt',player);
|
||||
if ( howmany < 3 ) player.SetPsprite(PSP_WEAPON,ResolveState("FireOne"));
|
||||
else if ( howmany < 15 ) player.SetPsprite(PSP_WEAPON,ResolveState("FireFive"));
|
||||
else player.SetPsprite(PSP_WEAPON,ResolveState("FireTwentyFive"));
|
||||
|
|
|
|||
|
|
@ -343,6 +343,7 @@ Class BusterWall : Thinker
|
|||
{
|
||||
let s = SWWMStats.Find(Instigator.player);
|
||||
if ( s ) s.busts++;
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_bustin',1,Instigator.player);
|
||||
}
|
||||
bust.busted = true;
|
||||
bust.busttics = 0;
|
||||
|
|
|
|||
|
|
@ -445,6 +445,7 @@ Class EvisceratorProjLight : PaletteLight
|
|||
Class EvisceratorProj : Actor
|
||||
{
|
||||
double heat;
|
||||
Vector3 startpos;
|
||||
Default
|
||||
{
|
||||
Obituary "$O_EVISCERATOR";
|
||||
|
|
@ -463,11 +464,17 @@ Class EvisceratorProj : Actor
|
|||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
startpos = pos;
|
||||
if ( waterlevel <= 0 ) vel.z += 3;
|
||||
heat = 1.5;
|
||||
}
|
||||
action void A_EvisExplode()
|
||||
{
|
||||
if ( target && tracer && (tracer.bIsMonster||tracer.player) && tracer.IsHostile(target) )
|
||||
{
|
||||
double dist = level.Vec3Diff(pos,invoker.startpos).length();
|
||||
SWWMUtility.AchievementProgress('swwm_progress_lead',int(dist),target.player);
|
||||
}
|
||||
bForceXYBillboard = true;
|
||||
A_SetRenderStyle(1.0,STYLE_Add);
|
||||
A_SprayDecal("BigRocketBlast",50);
|
||||
|
|
|
|||
|
|
@ -419,10 +419,20 @@ Class YnykronImpact : Actor
|
|||
gc.DoTheThing(true);
|
||||
gc.Amount--;
|
||||
}
|
||||
else if ( !tracer.FindInventory("GrilledCheeseSafeguard") ) tracer.DamageMobj(self,target,int.max,'Ynykron',DMG_FORCED|DMG_THRUSTLESS);
|
||||
else if ( !tracer.FindInventory("GrilledCheeseSafeguard") )
|
||||
{
|
||||
tracer.DamageMobj(self,target,int.max,'Ynykron',DMG_FORCED|DMG_THRUSTLESS);
|
||||
if ( target && tracer && (tracer.Health > 0) )
|
||||
SWWMUtility.MarkAchievement('swwm_achievement_god',target.player);
|
||||
}
|
||||
if ( tracer && (tracer.Health <= 0) )
|
||||
{
|
||||
if ( tracer.player ) PlayerGone.FeckOff(tracer);
|
||||
if ( tracer.player )
|
||||
{
|
||||
if ( tracer == target )
|
||||
SWWMUtility.MarkAchievement('swwm_achievement_oopsie',tracer.player);
|
||||
PlayerGone.FeckOff(tracer);
|
||||
}
|
||||
if ( tracer.FindState("YnykronDeath",true) )
|
||||
tracer.SetStateLabel("YnykronDeath"); // dedicated state
|
||||
else
|
||||
|
|
@ -437,6 +447,10 @@ Class YnykronImpact : Actor
|
|||
let r = Spawn("AshenRemains",tracer.pos);
|
||||
r.scale *= tracer.radius/16.;
|
||||
}
|
||||
if ( (tracer.bIsMonster || tracer.player) && tracer.IsHostile(target) && YnykronShot(master) )
|
||||
YnykronShot(master).enemykills++;
|
||||
if ( target && tracer.FindInventory("EndgameBossMarker") )
|
||||
SWWMUtility.MarkAchievement('swwm_achievement_ligma',target.player);
|
||||
}
|
||||
}
|
||||
if ( YnykronShot(master) )
|
||||
|
|
@ -499,7 +513,10 @@ Class YnykronImpact : Actor
|
|||
dirto /= dist;
|
||||
int trad = int(max(t.radius,t.height));
|
||||
if ( t && YnykronShot(master) )
|
||||
{
|
||||
YnykronShot(master).hitlist.Push(t);
|
||||
if ( t.bBOSS ) YnykronShot(master).hitboss = true;
|
||||
}
|
||||
// spawn blast that will propagate
|
||||
let b = Spawn("YnykronDelayedImpact",t.pos);
|
||||
Vector3 ofs = level.Vec3Diff(t.pos,level.Vec3Offset(pos,dirto*min(rad,dist)));
|
||||
|
|
@ -666,7 +683,10 @@ Class YnykronBeam : Actor
|
|||
continue;
|
||||
int trad = int(max(t.hitlist[i].hitactor.radius,t.hitlist[i].hitactor.height));
|
||||
if ( t.hitlist[i].hitactor && YnykronShot(master) )
|
||||
{
|
||||
YnykronShot(master).hitlist.Push(t.hitlist[i].hitactor);
|
||||
if ( t.hitlist[i].hitactor.bBOSS ) YnykronShot(master).hitboss = true;
|
||||
}
|
||||
// spawn blast that will propagate
|
||||
let b = Spawn("YnykronImpact",t.hitlist[i].hitlocation);
|
||||
b.tracer = t.HitList[i].hitactor;
|
||||
|
|
@ -763,7 +783,10 @@ Class YnykronBeam : Actor
|
|||
continue;
|
||||
int trad = int(max(it.hitlist[i].hitactor.radius,it.hitlist[i].hitactor.height));
|
||||
if ( it.hitlist[i].hitactor && YnykronShot(master) )
|
||||
{
|
||||
YnykronShot(master).hitlist.Push(it.hitlist[i].hitactor);
|
||||
if ( it.hitlist[i].hitactor.bBOSS ) YnykronShot(master).hitboss = true;
|
||||
}
|
||||
// spawn blast that will propagate
|
||||
let b = Spawn("YnykronImpact",it.hitlist[i].hitlocation);
|
||||
b.tracer = it.hitlist[i].hitactor;
|
||||
|
|
@ -1040,6 +1063,8 @@ Class YnykronImpactRing : Actor
|
|||
Class YnykronShot : Actor
|
||||
{
|
||||
Array<Actor> hitlist;
|
||||
bool hitboss;
|
||||
int enemykills;
|
||||
int beamcount;
|
||||
int blastcount;
|
||||
int lastimpact;
|
||||
|
|
@ -1115,13 +1140,19 @@ Class YnykronShot : Actor
|
|||
}
|
||||
}
|
||||
// wait until we're no longer needed and all effects are over
|
||||
if ( IsActorPlayingSound(CHAN_VOICE) || (beamcount > 0) || (blastcount > 0) )
|
||||
{
|
||||
special1 = min(special1,50);
|
||||
if ( (beamcount > 0) || (blastcount > 0) )
|
||||
return;
|
||||
if ( target && enemykills )
|
||||
{
|
||||
if ( (enemykills == 1) && !hitboss )
|
||||
SWWMUtility.MarkAchievement('swwm_achievement_oneguy',target.player);
|
||||
SWWMUtility.AchievementProgress('swwm_progress_ezkill',enemykills,target.player);
|
||||
enemykills = 0;
|
||||
}
|
||||
// we're done here, but wait for a while just in case
|
||||
if ( special1 > 350 ) Destroy();
|
||||
if ( IsActorPlayingSound(CHAN_VOICE) )
|
||||
return;
|
||||
// we're done here
|
||||
Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2395,10 +2426,20 @@ Class YnykronSingularity : Actor
|
|||
gc.DoTheThing(true);
|
||||
gc.Amount--;
|
||||
}
|
||||
else if ( !a.FindInventory("GrilledCheeseSafeguard") ) a.DamageMobj(self,target,int.max,'Ynykron',DMG_FORCED|DMG_THRUSTLESS);
|
||||
else if ( !a.FindInventory("GrilledCheeseSafeguard") )
|
||||
{
|
||||
a.DamageMobj(self,target,int.max,'Ynykron',DMG_FORCED|DMG_THRUSTLESS);
|
||||
if ( target && a && (a.Health > 0) )
|
||||
SWWMUtility.MarkAchievement('swwm_achievement_god',target.player);
|
||||
}
|
||||
if ( a && (a.Health <= 0) )
|
||||
{
|
||||
if ( a.player ) PlayerGone.FeckOff(a);
|
||||
if ( a.player )
|
||||
{
|
||||
if ( a == target )
|
||||
SWWMUtility.MarkAchievement('swwm_achievement_oopsie',a.player);
|
||||
PlayerGone.FeckOff(a);
|
||||
}
|
||||
if ( a.FindState("YnykronAltDeath",true) )
|
||||
a.SetStateLabel("YnykronAltDeath"); // dedicated state
|
||||
else
|
||||
|
|
@ -2408,6 +2449,8 @@ Class YnykronSingularity : Actor
|
|||
a.A_ChangeLinkFlags(false); // remove from blockmap, should guarantee archviles not raising this
|
||||
IDontFeelSoGood.DeletThis(a,true); // ensures corpse is deleted too
|
||||
}
|
||||
if ( target && a.FindInventory("EndgameBossMarker") )
|
||||
SWWMUtility.MarkAchievement('swwm_achievement_ligma',target.player);
|
||||
}
|
||||
if ( !a || (a.Health <= 0) )
|
||||
specialf2 += min(100.,capmass*.6); // partial absorption
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@ Class DeepImpact : SWWMWeapon
|
|||
}
|
||||
let ti = ThinkerIterator.Create("Actor");
|
||||
Actor m;
|
||||
let s = Demolitionist(self).mystats;
|
||||
while ( m = Actor(ti.Next()) )
|
||||
{
|
||||
if ( !(SWWMUtility.ValidProjectile(m) && (m.target != self)) ) continue;
|
||||
|
|
@ -231,6 +232,8 @@ Class DeepImpact : SWWMWeapon
|
|||
let pb = Inventory(Spawn("ParriedBuff"));
|
||||
pb.AttachToOwner(m);
|
||||
}
|
||||
if ( s ) s.parries++;
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_parry',1,player);
|
||||
}
|
||||
int numpt = Random[Impact](7,12);
|
||||
for ( int i=0; i<numpt; i++ )
|
||||
|
|
|
|||
|
|
@ -618,6 +618,7 @@ Class Spreadgun : SWWMWeapon
|
|||
s.vel += vel*.5+x*FRandom[Spreadgun](1.,20.)+y*FRandom[Spreadgun](-2,2)+z*FRandom[Spreadgun](-2,2);
|
||||
}
|
||||
SWWMUtility.DoKnockback(self,-x,30000.);
|
||||
SWWMUtility.AchievementProgressInc('swwm_progress_golden',1,player);
|
||||
break;
|
||||
default:
|
||||
st = new("SpreadgunTracer");
|
||||
|
|
|
|||
|
|
@ -780,6 +780,7 @@ Class CorrodeDebuff : Inventory
|
|||
// forcibly update
|
||||
wasalive = true;
|
||||
cnt = -1;
|
||||
if ( instigator ) SWWMUtility.AchievementProgressInc('swwm_progress_acid',1,instigator.player);
|
||||
}
|
||||
override void DoEffect()
|
||||
{
|
||||
|
|
@ -1186,6 +1187,7 @@ Class TheBall : Actor
|
|||
s.vel = pvel;
|
||||
}
|
||||
crit = true;
|
||||
if ( target ) SWWMUtility.AchievementProgressInc('swwm_progress_balls',1,target.player);
|
||||
}
|
||||
SWWMUtility.DoKnockback(victim,vel.unit(),slamforce);
|
||||
bool bleeds = (victim && !victim.bINVULNERABLE && !victim.bNOBLOOD && !victim.bDORMANT && is_schutt);
|
||||
|
|
@ -1215,6 +1217,8 @@ Class TheBall : Actor
|
|||
}
|
||||
if ( crit )
|
||||
SWWMUtility.DoExplosion(self,dmg/2,25000,150,80,ignoreme:target);
|
||||
if ( crit && victim && (victim.Health <= 0) && victim.bBOSS && target )
|
||||
SWWMUtility.MarkAchievement('swwm_achievement_clonk',target.player);
|
||||
// only rip shootables
|
||||
if ( (slamforce > girth) && is_schutt )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1127,6 +1127,7 @@ Class BiosparkBeam : Actor
|
|||
s.Args[0] = t.hitlist[i].hitactor.target.special1;
|
||||
}
|
||||
t.hitlist[i].hitactor.target.Destroy();
|
||||
if ( target ) SWWMUtility.AchievementProgressInc('swwm_progress_shock',1,target.player);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ Class ExplodiumGun : SWWMWeapon
|
|||
double casex, casey;
|
||||
transient ui TextureID WeaponBox;
|
||||
transient ui Font TewiFont;
|
||||
transient Actor deadeye_tgt;
|
||||
transient int deadeye_cnt;
|
||||
|
||||
Property ClipCount : ClipCount;
|
||||
|
||||
|
|
@ -110,6 +112,17 @@ Class ExplodiumGun : SWWMWeapon
|
|||
SWWMBulletTrail.DoTrail(self,origin,dir,10000,2);
|
||||
if ( d.HitType == TRACE_HitActor )
|
||||
{
|
||||
if ( invoker.deadeye_tgt && (d.HitActor != invoker.deadeye_tgt) )
|
||||
{
|
||||
invoker.deadeye_tgt = null;
|
||||
invoker.deadeye_cnt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
invoker.deadeye_tgt = d.HitActor;
|
||||
invoker.deadeye_cnt++;
|
||||
SWWMUtility.AchievementProgress('swwm_progress_explogun',invoker.deadeye_cnt,player);
|
||||
}
|
||||
int dmg = 15;
|
||||
// might as well apply explosion on top
|
||||
if ( dmg >= d.HitActor.Health ) dmg += 20;
|
||||
|
|
@ -131,33 +144,38 @@ Class ExplodiumGun : SWWMWeapon
|
|||
b.pitch = asin(d.HitDir.z);
|
||||
b.target = self;
|
||||
}
|
||||
else if ( d.HitType != TRACE_HitNone )
|
||||
else
|
||||
{
|
||||
Vector3 hitnormal = -d.HitDir;
|
||||
if ( d.HitType == TRACE_HitFloor )
|
||||
invoker.deadeye_tgt = null;
|
||||
invoker.deadeye_cnt = 0;
|
||||
if ( d.HitType != TRACE_HitNone )
|
||||
{
|
||||
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal;
|
||||
else hitnormal = d.HitSector.floorplane.Normal;
|
||||
Vector3 hitnormal = -d.HitDir;
|
||||
if ( d.HitType == TRACE_HitFloor )
|
||||
{
|
||||
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal;
|
||||
else hitnormal = d.HitSector.floorplane.Normal;
|
||||
}
|
||||
else if ( d.HitType == TRACE_HitCeiling )
|
||||
{
|
||||
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal;
|
||||
else hitnormal = d.HitSector.ceilingplane.Normal;
|
||||
}
|
||||
else if ( d.HitType == TRACE_HitWall )
|
||||
{
|
||||
hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
|
||||
if ( !d.LineSide ) hitnormal *= -1;
|
||||
}
|
||||
let p = Spawn("SWWMBulletImpact",d.HitLocation+hitnormal*0.01);
|
||||
p.angle = atan2(hitnormal.y,hitnormal.x);
|
||||
p.pitch = asin(-hitnormal.z);
|
||||
if ( d.HitLine ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
|
||||
let b = Spawn("ExplodiumBulletImpact",d.HitLocation+hitnormal*4.);
|
||||
b.angle = atan2(hitnormal.y,hitnormal.x);
|
||||
b.pitch = asin(-hitnormal.z);
|
||||
b.target = self;
|
||||
if ( swwm_omnibust ) BusterWall.BustLinetrace(d,50,self,d.HitDir,d.HitLocation.z);
|
||||
}
|
||||
else if ( d.HitType == TRACE_HitCeiling )
|
||||
{
|
||||
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal;
|
||||
else hitnormal = d.HitSector.ceilingplane.Normal;
|
||||
}
|
||||
else if ( d.HitType == TRACE_HitWall )
|
||||
{
|
||||
hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
|
||||
if ( !d.LineSide ) hitnormal *= -1;
|
||||
}
|
||||
let p = Spawn("SWWMBulletImpact",d.HitLocation+hitnormal*0.01);
|
||||
p.angle = atan2(hitnormal.y,hitnormal.x);
|
||||
p.pitch = asin(-hitnormal.z);
|
||||
if ( d.HitLine ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
|
||||
let b = Spawn("ExplodiumBulletImpact",d.HitLocation+hitnormal*4.);
|
||||
b.angle = atan2(hitnormal.y,hitnormal.x);
|
||||
b.pitch = asin(-hitnormal.z);
|
||||
b.target = self;
|
||||
if ( swwm_omnibust ) BusterWall.BustLinetrace(d,50,self,d.HitDir,d.HitLocation.z);
|
||||
}
|
||||
for ( int i=0; i<6; i++ )
|
||||
{
|
||||
|
|
@ -283,7 +301,12 @@ Class ExplodiumGun : SWWMWeapon
|
|||
XZW1 A -1;
|
||||
Stop;
|
||||
Select:
|
||||
XZW2 B 2 A_FullRaise();
|
||||
XZW2 B 2
|
||||
{
|
||||
invoker.deadeye_tgt = null;
|
||||
invoker.deadeye_cnt = 0;
|
||||
A_FullRaise();
|
||||
}
|
||||
XZW2 CDEFGH 2;
|
||||
Goto Ready;
|
||||
Ready:
|
||||
|
|
@ -348,6 +371,8 @@ Class ExplodiumGun : SWWMWeapon
|
|||
Reload:
|
||||
XZW2 A 1
|
||||
{
|
||||
invoker.deadeye_tgt = null;
|
||||
invoker.deadeye_cnt = 0;
|
||||
if ( invoker.clipcount >= invoker.default.clipcount ) return ResolveState("CheckBullet");
|
||||
A_PlayerReload();
|
||||
if ( invoker.clipcount <= 0 ) return ResolveState("ReloadEmpty");
|
||||
|
|
@ -455,6 +480,8 @@ Class DualExplodiumGun : SWWMWeapon
|
|||
double casex, casey, lcasex, lcasey;
|
||||
transient ui TextureID WeaponBox;
|
||||
transient ui Font TewiFont;
|
||||
transient Actor deadeye_tgt;
|
||||
transient int deadeye_cnt;
|
||||
|
||||
Property ClipCount : ClipCount;
|
||||
|
||||
|
|
@ -552,6 +579,17 @@ Class DualExplodiumGun : SWWMWeapon
|
|||
SWWMBulletTrail.DoTrail(self,origin,dir,10000,2);
|
||||
if ( d.HitType == TRACE_HitActor )
|
||||
{
|
||||
if ( invoker.deadeye_tgt && (d.HitActor != invoker.deadeye_tgt) )
|
||||
{
|
||||
invoker.deadeye_tgt = null;
|
||||
invoker.deadeye_cnt = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
invoker.deadeye_tgt = d.HitActor;
|
||||
invoker.deadeye_cnt++;
|
||||
SWWMUtility.AchievementProgress('swwm_progress_explogun',invoker.deadeye_cnt,player);
|
||||
}
|
||||
int dmg = 15;
|
||||
// might as well apply explosion on top
|
||||
if ( dmg >= d.HitActor.Health ) dmg += 20;
|
||||
|
|
@ -573,33 +611,38 @@ Class DualExplodiumGun : SWWMWeapon
|
|||
b.pitch = asin(d.HitDir.z);
|
||||
b.target = self;
|
||||
}
|
||||
else if ( d.HitType != TRACE_HitNone )
|
||||
else
|
||||
{
|
||||
Vector3 hitnormal = -d.HitDir;
|
||||
if ( d.HitType == TRACE_HitFloor )
|
||||
invoker.deadeye_tgt = null;
|
||||
invoker.deadeye_cnt = 0;
|
||||
if ( d.HitType != TRACE_HitNone )
|
||||
{
|
||||
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal;
|
||||
else hitnormal = d.HitSector.floorplane.Normal;
|
||||
Vector3 hitnormal = -d.HitDir;
|
||||
if ( d.HitType == TRACE_HitFloor )
|
||||
{
|
||||
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.top.Normal;
|
||||
else hitnormal = d.HitSector.floorplane.Normal;
|
||||
}
|
||||
else if ( d.HitType == TRACE_HitCeiling )
|
||||
{
|
||||
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal;
|
||||
else hitnormal = d.HitSector.ceilingplane.Normal;
|
||||
}
|
||||
else if ( d.HitType == TRACE_HitWall )
|
||||
{
|
||||
hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
|
||||
if ( !d.LineSide ) hitnormal *= -1;
|
||||
}
|
||||
let p = Spawn("SWWMBulletImpact",d.HitLocation+hitnormal*0.01);
|
||||
p.angle = atan2(hitnormal.y,hitnormal.x);
|
||||
p.pitch = asin(-hitnormal.z);
|
||||
if ( d.HitLine ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
|
||||
let b = Spawn("ExplodiumBulletImpact",d.HitLocation+hitnormal*4.);
|
||||
b.angle = atan2(hitnormal.y,hitnormal.x);
|
||||
b.pitch = asin(-hitnormal.z);
|
||||
b.target = self;
|
||||
if ( swwm_omnibust ) BusterWall.BustLinetrace(d,50,self,d.HitDir,d.HitLocation.z);
|
||||
}
|
||||
else if ( d.HitType == TRACE_HitCeiling )
|
||||
{
|
||||
if ( d.Hit3DFloor ) hitnormal = -d.Hit3DFloor.bottom.Normal;
|
||||
else hitnormal = d.HitSector.ceilingplane.Normal;
|
||||
}
|
||||
else if ( d.HitType == TRACE_HitWall )
|
||||
{
|
||||
hitnormal = (-d.HitLine.delta.y,d.HitLine.delta.x,0).unit();
|
||||
if ( !d.LineSide ) hitnormal *= -1;
|
||||
}
|
||||
let p = Spawn("SWWMBulletImpact",d.HitLocation+hitnormal*0.01);
|
||||
p.angle = atan2(hitnormal.y,hitnormal.x);
|
||||
p.pitch = asin(-hitnormal.z);
|
||||
if ( d.HitLine ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation);
|
||||
let b = Spawn("ExplodiumBulletImpact",d.HitLocation+hitnormal*4.);
|
||||
b.angle = atan2(hitnormal.y,hitnormal.x);
|
||||
b.pitch = asin(-hitnormal.z);
|
||||
b.target = self;
|
||||
if ( swwm_omnibust ) BusterWall.BustLinetrace(d,50,self,d.HitDir,d.HitLocation.z);
|
||||
}
|
||||
for ( int i=0; i<6; i++ )
|
||||
{
|
||||
|
|
@ -674,7 +717,12 @@ Class DualExplodiumGun : SWWMWeapon
|
|||
States
|
||||
{
|
||||
Select:
|
||||
XZW2 B 2 A_FullRaise();
|
||||
XZW2 B 2
|
||||
{
|
||||
invoker.deadeye_tgt = null;
|
||||
invoker.deadeye_cnt = 0;
|
||||
A_FullRaise();
|
||||
}
|
||||
XZW2 C 2;
|
||||
XZW2 D 2 { player.SetPSprite(PSP_WEAPON+1,ResolveState("LeftSelect")); }
|
||||
XZW2 EFGHAA 2;
|
||||
|
|
@ -789,7 +837,12 @@ Class DualExplodiumGun : SWWMWeapon
|
|||
XZWB A 1;
|
||||
Goto LeftReady;
|
||||
Reload:
|
||||
XZW2 A 9 { player.SetPSPrite(PSP_WEAPON+1,ResolveState("LeftLower")); }
|
||||
XZW2 A 9
|
||||
{
|
||||
invoker.deadeye_tgt = null;
|
||||
invoker.deadeye_cnt = 0;
|
||||
player.SetPSPrite(PSP_WEAPON+1,ResolveState("LeftLower"));
|
||||
}
|
||||
XZW2 A 1
|
||||
{
|
||||
A_PlayerReload();
|
||||
|
|
@ -845,7 +898,12 @@ Class DualExplodiumGun : SWWMWeapon
|
|||
XZW2 A 0 { player.SetPSPrite(PSP_WEAPON+1,ResolveState("LeftRaise")); }
|
||||
Goto Ready;
|
||||
LeftReload:
|
||||
XZWB A 9 { player.SetPSPrite(PSP_WEAPON,ResolveState("Lower")); }
|
||||
XZWB A 9
|
||||
{
|
||||
invoker.deadeye_tgt = null;
|
||||
invoker.deadeye_cnt = 0;
|
||||
player.SetPSPrite(PSP_WEAPON,ResolveState("Lower"));
|
||||
}
|
||||
XZWB A 1
|
||||
{
|
||||
A_PlayerReload();
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ Class HitListEntry
|
|||
Actor hitactor;
|
||||
Vector3 hitlocation, x;
|
||||
int hitdamage;
|
||||
bool pastwall; // used by silver bullet
|
||||
}
|
||||
|
||||
Class CandyBeamTracer : LineTracer
|
||||
|
|
@ -536,6 +537,26 @@ Class CandyGunProj : Actor
|
|||
}
|
||||
void A_BlowUp()
|
||||
{
|
||||
bool bossbrains = false;
|
||||
for ( Actor a=CurSector.thinglist; a; a=a.snext )
|
||||
{
|
||||
if ( a is 'BossBrain' )
|
||||
{
|
||||
let ti = ThinkerIterator.Create('BossEye');
|
||||
if ( ti.Next() )
|
||||
{
|
||||
bossbrains = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( a is 'BossEye' )
|
||||
{
|
||||
bossbrains = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( bossbrains && target )
|
||||
SWWMUtility.MarkAchievement('swwm_achievement_yeet',target.player);
|
||||
angle = atan2(cvel.y,cvel.x);
|
||||
pitch = asin(-cvel.z);
|
||||
bNOGRAVITY = true;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ Class WallPenetrate
|
|||
Line hitline;
|
||||
Sector hitsector;
|
||||
F3DFloor hitffloor;
|
||||
bool pastwall;
|
||||
}
|
||||
|
||||
Class AuxiliarySilverBulletTracer : LineTracer
|
||||
|
|
@ -27,6 +28,7 @@ Class AuxiliarySilverBulletTracer : LineTracer
|
|||
|
||||
Class SilverBulletTracer : SpreadSlugTracer
|
||||
{
|
||||
bool pastwall;
|
||||
Array<WallPenetrate> WallPenetrateList;
|
||||
|
||||
override ETraceStatus TraceCallback()
|
||||
|
|
@ -55,6 +57,7 @@ Class SilverBulletTracer : SpreadSlugTracer
|
|||
ent.hitactor = Results.HitActor;
|
||||
ent.hitlocation = Results.HitPos;
|
||||
ent.x = Results.HitVector;
|
||||
ent.pastwall = pastwall;
|
||||
if ( (Results.HitActor.Health >= int(penetration)) || Results.HitActor.bNODAMAGE )
|
||||
{
|
||||
ent.hitdamage = int(penetration);
|
||||
|
|
@ -94,7 +97,9 @@ Class SilverBulletTracer : SpreadSlugTracer
|
|||
wp.penetration = int(penetration);
|
||||
wp.hitnormal = (-Results.HitLine.delta.y,Results.HitLine.delta.x,0).unit();
|
||||
if ( !Results.Side ) wp.hitnormal *= -1;
|
||||
wp.pastwall = pastwall;
|
||||
WallPenetrateList.Push(wp);
|
||||
pastwall = true;
|
||||
penetration = max(0,penetration-i*4);
|
||||
// trace backwards to find exit surface
|
||||
let at = new("AuxiliarySilverBulletTracer");
|
||||
|
|
@ -124,6 +129,7 @@ Class SilverBulletTracer : SpreadSlugTracer
|
|||
wp2.hitnormal = at.Results.HitSector.ceilingplane.Normal;
|
||||
else if ( at.Results.HitType == TRACE_HitFloor )
|
||||
wp2.hitnormal = at.Results.HitSector.floorplane.Normal;
|
||||
wp2.pastwall = pastwall;
|
||||
WallPenetrateList.Push(wp2);
|
||||
}
|
||||
return TRACE_Skip;
|
||||
|
|
@ -162,7 +168,9 @@ Class SilverBulletTracer : SpreadSlugTracer
|
|||
wp.hitnormal = Results.HitSector.ceilingplane.Normal;
|
||||
else if ( Results.HitType == TRACE_HitFloor )
|
||||
wp.hitnormal = Results.HitSector.floorplane.Normal;
|
||||
wp.pastwall = pastwall;
|
||||
WallPenetrateList.Push(wp);
|
||||
pastwall = true;
|
||||
penetration = max(0,penetration-i*4);
|
||||
// trace backwards to find exit surface
|
||||
let at = new("AuxiliarySilverBulletTracer");
|
||||
|
|
@ -192,6 +200,7 @@ Class SilverBulletTracer : SpreadSlugTracer
|
|||
wp2.hitnormal = at.Results.HitSector.ceilingplane.Normal;
|
||||
else if ( at.Results.HitType == TRACE_HitFloor )
|
||||
wp2.hitnormal = at.Results.HitSector.floorplane.Normal;
|
||||
wp2.pastwall = pastwall;
|
||||
WallPenetrateList.Push(wp2);
|
||||
}
|
||||
return TRACE_Skip;
|
||||
|
|
@ -249,6 +258,7 @@ Class SilverBullet : SWWMWeapon
|
|||
ui int lastammo;
|
||||
int clipcount;
|
||||
double casex, casey;
|
||||
int nkills;
|
||||
|
||||
transient ui TextureID WeaponBox[2], ZoomBar, BulletIcon[2], AmmoIcon[2];
|
||||
transient ui Font TewiFont;
|
||||
|
|
@ -433,17 +443,24 @@ Class SilverBullet : SWWMWeapon
|
|||
}
|
||||
for ( int i=0; i<t.HitList.Size(); i++ )
|
||||
{
|
||||
int realdmg = t.HitList[i].HitDamage;
|
||||
SWWMDamageAccumulator.Accumulate(t.HitList[i].HitActor,realdmg,invoker,self,'shot',false,DMG_FOILINVUL);
|
||||
SWWMUtility.DoKnockback(t.HitList[i].HitActor,t.HitList[i].x+(0,0,0.025),realdmg*20.*FRandom[SilverBullet](.8,1.2));
|
||||
SWWMUtility.DoKnockback(t.HitList[i].HitActor,t.HitList[i].x+(0,0,0.025),t.Hitlist[i].HitDamage*20.*FRandom[SilverBullet](.8,1.2));
|
||||
int dmg = t.HitList[i].HitActor.DamageMobj(invoker,self,t.Hitlist[i].HitDamage,'shot',DMG_FOILINVUL|DMG_USEANGLE|DMG_THRUSTLESS,atan2(t.Results.HitVector.y,t.Results.HitVector.x));
|
||||
if ( (t.HitList[i].HitActor.Health <= 0) && (t.HitList[i].HitActor.bIsMonster || t.HitList[i].HitActor.player) && t.HitList[i].HitActor.IsHostile(self) )
|
||||
{
|
||||
invoker.nkills++;
|
||||
SWWMUtility.AchievementProgress('swwm_progress_conga',invoker.nkills,player);
|
||||
if ( t.Hitlist[i].pastwall ) SWWMUtility.AchievementProgressInc('swwm_progress_thruwall',1,player);
|
||||
}
|
||||
if ( t.HitList[i].HitActor && !t.HitList[i].HitActor.bNOBLOOD && !t.HitList[i].HitActor.bDORMANT )
|
||||
{
|
||||
t.HitList[i].HitActor.TraceBleed(realdmg,self);
|
||||
t.HitList[i].HitActor.SpawnBlood(t.HitList[i].HitLocation,atan2(t.HitList[i].x.y,t.HitList[i].x.x)+180,realdmg);
|
||||
t.HitList[i].HitActor.TraceBleed(dmg,self);
|
||||
t.HitList[i].HitActor.SpawnBlood(t.HitList[i].HitLocation,atan2(t.HitList[i].x.y,t.HitList[i].x.x)+180,dmg);
|
||||
t.HitList[i].HitActor.A_StartSound("silverbullet/flesh",CHAN_DAMAGE,CHANF_OVERLAP,1.,2.);
|
||||
let p = Spawn("SilverImpact",t.HitList[i].HitLocation);
|
||||
p.special1 = 1;
|
||||
p.target = self;
|
||||
p.master = invoker;
|
||||
p.bAMBUSH = t.HitList[i].pastwall;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -451,6 +468,8 @@ Class SilverBullet : SWWMWeapon
|
|||
p.angle = atan2(t.HitList[i].x.y,t.HitList[i].x.x)+180;
|
||||
p.pitch = asin(t.HitList[i].x.z);
|
||||
p.target = self;
|
||||
p.master = invoker;
|
||||
p.bAMBUSH = t.HitList[i].pastwall;
|
||||
}
|
||||
}
|
||||
LineTracer faketracer = new("LineTracer");
|
||||
|
|
@ -462,6 +481,8 @@ Class SilverBullet : SWWMWeapon
|
|||
p.angle = atan2(hitnormal.y,hitnormal.x);
|
||||
p.pitch = asin(-hitnormal.z);
|
||||
p.target = self;
|
||||
p.master = invoker;
|
||||
p.bAMBUSH = t.WallPenetrateList[i].pastwall;
|
||||
if ( t.WallPenetrateList[i].hittype == TRACE_HitWall )
|
||||
t.WallPenetrateList[i].hitline.Activate(self,t.WallPenetrateList[i].hitside,SPAC_Impact);
|
||||
if ( swwm_omnibust )
|
||||
|
|
@ -497,15 +518,45 @@ Class SilverBullet : SWWMWeapon
|
|||
p.angle = atan2(hitnormal.y,hitnormal.x);
|
||||
p.pitch = asin(-hitnormal.z);
|
||||
p.target = self;
|
||||
p.master = invoker;
|
||||
if ( t.WallPenetrateList.Size() > 0 ) p.bAMBUSH = true;
|
||||
if ( t.Results.HitType == TRACE_HitWall ) t.Results.HitLine.RemoteActivate(self,t.Results.Side,SPAC_Impact,t.Results.HitPos);
|
||||
if ( swwm_omnibust ) BusterWall.Bust(t.Results,int(t.penetration),self,t.Results.HitVector,t.Results.HitPos.z);
|
||||
}
|
||||
for ( int i=0; i<t.Results.Distance; i+=16 )
|
||||
if ( t.WallPenetrateList.Size() > 0 )
|
||||
{
|
||||
Vector3 ofs = level.Vec3Offset(origin,dir*i);
|
||||
if ( !level.IsPointInLevel(ofs) ) continue;
|
||||
let s = Spawn("SilverAirRip",ofs);
|
||||
Vector3 start = origin;
|
||||
Vector3 end = t.WallPenetrateList[0].hitpos;
|
||||
Vector3 dir = level.Vec3Diff(start,end);
|
||||
double dist = dir.length();
|
||||
dir /= dist;
|
||||
for ( int i=0; i<dist; i+=16 )
|
||||
{
|
||||
let s = Spawn("SilverAirRip",level.Vec3Offset(start,dir*i));
|
||||
s.target = self;
|
||||
s.master = invoker;
|
||||
}
|
||||
for ( int i=1; i<t.WallPenetrateList.Size(); i+=2 )
|
||||
{
|
||||
start = t.WallPenetrateList[i].hitpos;
|
||||
if ( i >= t.WallPenetrateList.Size()-1 ) end = t.Results.HitPos;
|
||||
else end = t.WallPenetrateList[i+1].hitpos;
|
||||
dir = level.Vec3Diff(start,end);
|
||||
dist = dir.length();
|
||||
for ( int j=0; j<dist; j+=16 )
|
||||
{
|
||||
let s = Spawn("SilverAirRip",level.Vec3Offset(start,dir*j));
|
||||
s.target = self;
|
||||
s.master = invoker;
|
||||
s.bAMBUSH = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else for ( int i=0; i<t.Results.Distance; i+=16 )
|
||||
{
|
||||
let s = Spawn("SilverAirRip",level.Vec3Offset(origin,dir*i));
|
||||
s.target = self;
|
||||
s.master = invoker;
|
||||
}
|
||||
}
|
||||
action void ProcessAltTraceHit( FatChodeTracer t, Vector3 origin, Vector3 dir )
|
||||
|
|
@ -620,7 +671,9 @@ Class SilverBullet : SWWMWeapon
|
|||
sst.shootthroughlist.Clear();
|
||||
sst.waterhitlist.Clear();
|
||||
sst.wallpenetratelist.Clear();
|
||||
sst.pastwall = false;
|
||||
sst.Trace(origin,level.PointInSector(origin.xy),x2,20000.,TRACE_HitSky);
|
||||
invoker.nkills = 0;
|
||||
ProcessTraceHit(sst,origin,x2);
|
||||
}
|
||||
for ( int i=0; i<16; i++ )
|
||||
|
|
|
|||
|
|
@ -55,7 +55,14 @@ Class SilverAirRip : Actor
|
|||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
SWWMUtility.DoExplosion(self,40,2000,40,ignoreme:target);
|
||||
int nhit, nkill;
|
||||
[nhit, nkill] = SWWMUtility.DoExplosion(self,40,2000,40,flags:DE_COUNTENEMIES,ignoreme:target);
|
||||
if ( SilverBullet(master) )
|
||||
{
|
||||
Silverbullet(master).nkills += nkill;
|
||||
SWWMUtility.AchievementProgress('swwm_progress_conga',Silverbullet(master).nkills,target.player);
|
||||
if ( bAMBUSH ) SWWMUtility.AchievementProgressInc('swwm_progress_thruwall',nkill,target.player);
|
||||
}
|
||||
Destroy();
|
||||
}
|
||||
}
|
||||
|
|
@ -100,7 +107,14 @@ Class SilverImpact : Actor
|
|||
override void PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
SWWMUtility.DoExplosion(self,100,8000,100,20);
|
||||
int nhit, nkill;
|
||||
[nhit, nkill] = SWWMUtility.DoExplosion(self,100,8000,100,20,DE_COUNTENEMIES);
|
||||
if ( SilverBullet(master) )
|
||||
{
|
||||
Silverbullet(master).nkills += nkill;
|
||||
SWWMUtility.AchievementProgress('swwm_progress_conga',Silverbullet(master).nkills,target.player);
|
||||
if ( bAMBUSH ) SWWMUtility.AchievementProgressInc('swwm_progress_thruwall',nkill,target.player);
|
||||
}
|
||||
A_AlertMonsters(swwm_uncapalert?0:2500);
|
||||
A_QuakeEx(4,4,4,20,0,400,"",QF_RELATIVE|QF_SCALEDOWN,falloff:100,rollIntensity:.9);
|
||||
if ( special1 )
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue