More finetunin'.

Added forced fall damage option.
This commit is contained in:
Mari the Deer 2020-06-20 22:20:44 +02:00
commit 202bdce0e2
13 changed files with 101 additions and 25 deletions

View file

@ -58,3 +58,4 @@ user noarchive bool swwm_cbttime = false; // debug: times how long a reload take
server bool swwm_crouchjump = false; // allows crouch-jumping (which looks weird af but some maps may need it)
user noarchive int swwm_cbtlast = 0; // last selected ammo for the wallbuster
server bool swwm_cbtall = true; // wallbuster breaks any wall, not just movable ones
server bool swwm_doomfall = false; // monsters take fall damage outside of hexen

View file

@ -100,6 +100,7 @@ SWWM_FUZZ = "Enable Animated Menu BG";
SWWM_BUSTERPAUSE = "Pause on Wallbuster Reload";
SWWM_CROUCHJUMP = "Allow Crouch-Jump";
SWWM_CBTALL = "Unlimited Wallbuster Destruction";
SWWM_DOOMFALL = "Force Monster Fall Damage";
TOOLTIP_SWWM_VOICETYPE = "Sets the voice pack for the player.";
TOOLTIP_SWWM_MUTEVOICE = "Control what gets muted, if you'd rather have a more silent protagonist.";
TOOLTIP_SWWM_FLASHSTRENGTH = "Screen flashes usually happen when firing some weapons, you can lower this if these effects are harmful for you.";
@ -146,6 +147,7 @@ TOOLTIP_SWWM_FUZZ = "Toggling this off is recommended if you're recording/stream
TOOLTIP_SWWM_CBTPAUSE = "The game will pause while the Wallbuster reload menu is open (only in singleplayer).";
TOOLTIP_SWWM_CROUCHJUMP = "Allow the player to crouch-jump (which may be needed on some maps). Note that there are no animations for this and it'll look weird.";
TOOLTIP_SWWM_CBTALL = "Allows the Wallbuster to break pretty much anything, not just doors and platforms. Note that this can break some maps, which is why this option is here.";
TOOLTIP_SWWM_DOOMFALL = "Makes monsters take fall damage outside of Hexen.";
// knowledge base
SWWM_COMINGSOON = "(coming soon)";
SWWM_MISSTAB = "Mission";
@ -328,4 +330,4 @@ SWWM_BUSTERKEYS =
"\cfBackspace:\c- Clear Ammo\n"
"\cfEnter:\c- Initiate Reload\n"
"\cfEnter (if empty):\c- Full Reload\n"
"\cfEsc:\c- Cancel Reload\n";
"\cfEsc:\c- Cancel Reload\n";

View file

@ -97,6 +97,7 @@ SWWM_FUZZ = "Habilitar Fondo Animado de Menú";
SWWM_BUSTERPAUSE = "Pausar en Regarga de Wallbuster";
SWWM_CROUCHJUMP = "Permitir Salto Agachado";
SWWM_CBTALL = "Destrucción Ilimitada de Wallbuster";
SWWM_DOOMFALL = "Forzar Daño por Caída en Monstruos";
TOOLTIP_SWWM_VOICETYPE = "Selecciona el pack de voz para el jugador.";
TOOLTIP_SWWM_MUTEVOICE = "Controla lo que se mutea, si prefieres tener un protagonista más silencioso.";
TOOLTIP_SWWM_FLASHSTRENGTH = "Los destellos en pantalla suelen ocurrir al disparar algunas armas, puedes reducirlo si este tipo de effectos te causan malestar.";
@ -143,6 +144,7 @@ TOOLTIP_SWWM_FUZZ = "Desactivar ésto es recomendado si estás grabando o hacien
TOOLTIP_SWWM_CBTPAUSE = "El juego será pausado mientras el menú de recarga de Wallbuster está abierto (sólo en modo de un jugador).";
TOOLTIP_SWWM_CROUCHJUMP = "Permite al jugador agacharse saltando (lo cual puede ser necesario en algunos mapas). Ten en cuenta que no hay animaciones para esto, así que se verá raro.";
TOOLTIP_SWWM_CBTALL = "Permite a la Wallbuster romper casi cualquier cosa, no solo puertas y plataformas. Ten en cuenta que esto puede romper algunos mapas, razón de que haya esta opción.";
TOOLTIP_SWWM_DOOMFALL = "Hace que los monstruos reciban daño por caída fuera de Hexen.";
// knowledge base
SWWM_COMINGSOON = "(próximamente)";
SWWM_MISSTAB = "Misión";
@ -325,4 +327,4 @@ SWWM_BUSTERKEYS =
"\cfRetroceso:\c- Limpiar Munición\n"
"\cfEnter:\c- Iniciar Recarga\n"
"\cfEnter (si vacío):\c- Recarga Completa\n"
"\cfEsc:\c- Calcelar recarga\n";
"\cfEsc:\c- Calcelar recarga\n";

View file

@ -1,2 +1,2 @@
[default]
SWWM_MODVER="\cxSWWM GZ\c- r366 (Sat 20 Jun 17:21:12 CEST 2020)";
SWWM_MODVER="\chSWWM \cwGZ\c- r367 (Sat 20 Jun 22:20:44 CEST 2020)";

View file

@ -62,6 +62,9 @@ OptionMenu "SWWMOptionMenu"
StaticText "$SWWM_BTITLE", "Gold"
Option "$SWWM_EXTRAALERT", "swwm_extraalert", "YesNo"
Option "$SWWM_BOSSENHANCE", "swwm_upgradebosses", "YesNo"
Option "$SWWM_DOOMFALL", "swwm_doomfall", "YesNo"
Option "$SWWM_BALLUSE", "swwm_balluse", "YesNo"
Option "$SWWM_CBTALL", "swwm_cbtall", "YesNo"
StaticText " "
StaticText "$SWWM_ITITLE", "Gold"
Option "$SWWM_ARMORUSE", "swwm_autousearmor", "YesNo"
@ -69,8 +72,6 @@ OptionMenu "SWWMOptionMenu"
Option "$SWWM_AMMOUSE", "swwm_autouseammo", "YesNo"
Option "$SWWM_EARBUSTER", "swwm_earbuster", "YesNo"
Option "$SWWM_BUSTERPAUSE", "swwm_cbtpause", "YesNo"
Option "$SWWM_BALLUSE", "swwm_balluse", "YesNo"
Option "$SWWM_CBTALL", "swwm_cbtall", "YesNo"
StaticText " "
StaticText "$SWWM_CTITLE", "Gold"
Option "$SWWM_SKEYS", "swwm_sharekeys", "YesNo"

View file

@ -30,9 +30,11 @@ GameInfo
"SilverBullet",
"CandyGun",
"YnykronArtifact"
// make easter egg not stutter
// precache long sounds
PrecacheSounds = "wallbuster/olddays",
"wallbuster/cbt"
"wallbuster/cbt",
"ynykron/idle",
"ynykron/ready"
}
Map TITLEMAP "SWWM GZ - Title Map"

View file

@ -457,7 +457,7 @@ Class BusterWall : Thinker
if ( busted )
{
busttics++;
if ( busttics > 16 )
if ( busttics > 12 )
{
Destroy();
return;
@ -485,7 +485,7 @@ Class BusterWall : Thinker
if ( level.PointInSector(spot.xy) != hitsector ) continue;
spot += (FRandom[Wallbuster](-step.x,step.x),FRandom[Wallbuster](-step.y,step.y),FRandom[Wallbuster](-step.z,step.z));
if ( !level.IsPointInLevel(spot) ) continue;
if ( initial || !(busttics%3) )
if ( (initial || !(busttics%3)) && !Random[Wallbuster](0,2) )
{
Vector3 pvel = (bustdir+(FRandom[Wallbuster](-1.,1.),FRandom[Wallbuster](-1.,1.),FRandom[Wallbuster](-1.,1.))).unit()*FRandom[Wallbuster](-2.,8.);
let s = Actor.Spawn("SWWMSmoke",spot);
@ -508,7 +508,7 @@ Class BusterWall : Thinker
Vector3 pvel = (bustdir+(FRandom[Wallbuster](-.6,.6),FRandom[Wallbuster](-.6,.6),FRandom[Wallbuster](-.6,.6))).unit()*FRandom[Wallbuster](2.,16.);
let s = Actor.Spawn("SWWMChip",spot);
s.vel = pvel;
s.scale *= FRandom[Wallbuster](2.,4.);
s.scale *= FRandom[Wallbuster](1.2,2.4);
s.A_SetTranslation('Rubble');
}
}

View file

@ -1081,8 +1081,11 @@ Class SWWMCombatTracker : Thinker
int newhealth = mytarget.Health;
if ( (mytarget.bISMONSTER || mytarget.player) && !mytarget.bINVISIBLE )
{
bool straifu = false;
if ( ((gameinfo.gametype&GAME_Strife) && !mytarget.bINCOMBAT && !mytarget.bJUSTATTACKED) || (mytarget is 'Beggar') || (mytarget is 'Peasant') )
straifu = true;
// enemies within 2000mu that have us as target
if ( mytarget.target && (mytarget.target.Health > 0) && (mytarget.target.player == players[consoleplayer]) && mytarget.CheckSight(mytarget.target) && (mytarget.Vec3To(mytarget.target).length() < 2000) ) updated = level.maptime+70;
if ( mytarget.target && (mytarget.target.Health > 0) && (mytarget.target.player == players[consoleplayer]) && mytarget.CheckSight(mytarget.target) && (mytarget.Vec3To(mytarget.target).length() < 2000) && !straifu ) updated = level.maptime+70;
// players (but not voodoo dolls), always visible in sp/coop
if ( !deathmatch && mytarget.player && (mytarget.player.mo == mytarget) ) updated = level.maptime+35;
// any visible enemies within 600mu
@ -1558,7 +1561,7 @@ Class SWWMChip : Actor
override void PostBeginPlay()
{
Super.PostBeginPlay();
deadtimer = 0;
deadtimer = Random[Junk](-30,30);
rollvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
frame = Random[Junk](0,5);
scale *= Frandom[Junk](0.8,1.2);
@ -1621,7 +1624,7 @@ Class FancyConfetti : Actor
override void PostBeginPlay()
{
Super.PostBeginPlay();
deadtimer = 0;
deadtimer = Random[Junk](-30,30);
anglevel = FRandom[Junk](3,12)*RandomPick[Junk](-1,1);
pitchvel = FRandom[Junk](3,12)*RandomPick[Junk](-1,1);
rollvel = FRandom[Junk](3,12)*RandomPick[Junk](-1,1);
@ -2062,6 +2065,59 @@ Class UglyBoyGetsFuckedUp : Thinker
}
}
// Gotta force it someway
Class ForcedFallerDamager : Thinker
{
Actor mybody, instigator;
double lastvelz;
bool wasflying;
static void TrackBody( Actor b )
{
if ( !b ) return;
let ffd = new("ForcedFallerDamager");
ffd.ChangeStatNum(STAT_USER);
ffd.mybody = b;
ffd.lastvelz = b.vel.z;
ffd.wasflying = ((b.pos.z>b.floorz)&&b.TestMobjZ());
}
static void SetInstigator( Actor b, Actor whomst )
{
if ( !b || !whomst ) return;
let ti = ThinkerIterator.Create("ForcedFallerDamager",STAT_USER);
ForcedFallerDamager ffd;
while ( ffd = ForcedFallerDamager(ti.Next()) )
{
if ( ffd.mybody != b ) continue;
ffd.instigator = whomst;
break;
}
}
override void Tick()
{
if ( !mybody )
{
Destroy();
return;
}
bool isflying = ((mybody.pos.z>mybody.floorz)&&mybody.TestMobjZ());
if ( wasflying && !isflying && (lastvelz < -23) && !level.monsterfallingdamage && !(mybody.floorsector.flags&Sector.SECF_NOFALLINGDAMAGE) && swwm_doomfall )
{
// big hurt
int dmg;
if ( lastvelz < -35 ) dmg = Actor.TELEFRAG_DAMAGE;
else dmg = int((-lastvelz-23)*6);
mybody.DamageMobj(instigator,instigator,dmg,'Falling');
}
if ( !isflying && wasflying ) instigator = null;
wasflying = isflying;
lastvelz = mybody.vel.z;
// wait until body is dead
if ( mybody.Health > 0 ) return;
Destroy();
}
}
// Handler responsible for item replacements and whatever else
Class SWWMHandler : EventHandler
{
@ -2605,6 +2661,8 @@ Class SWWMHandler : EventHandler
break;
}
}
// fall dmg
ForcedFallerDamager.SetInstigator(e.Thing,e.DamageSource);
}
if ( e.Thing.player )
{
@ -2621,7 +2679,7 @@ Class SWWMHandler : EventHandler
}
if ( e.DamageSource && (e.DamageSource != e.Thing) )
{
if ( (e.DamageSource.bISMONSTER || e.DamageSource.player) && (e.Thing == players[consoleplayer].mo) && (e.Thing.Health > 0) )
if ( (e.DamageSource.bISMONSTER || e.DamageSource.player || (e.DamageSource is 'ScriptedMarine')) && (e.Thing == players[consoleplayer].mo) && (e.Thing.Health > 0) )
{
if ( !lastcombat || (gametic > lastcombat+40) )
{
@ -2632,7 +2690,7 @@ Class SWWMHandler : EventHandler
highesttic = gametic;
}
// friendly fire lines only fire up if we didn't kill them right away (because then the teamkill line should take priority)
if ( (e.DamageSource == players[consoleplayer].mo) && (e.Thing.bISMONSTER || e.Thing.player) && (e.Thing.Health > 0) )
if ( (e.DamageSource == players[consoleplayer].mo) && (e.Thing.bISMONSTER || e.Thing.player || (e.Thing is 'ScriptedMarine')) && (e.Thing.Health > 0) )
{
// make sure it's not a moth, because otherwise they won't shut up about accidentally hurting them (it happens a lot)
if ( (e.Thing.IsFriend(e.DamageSource) || SWWMUtility.IsCivilian(e.Thing)) && !(e.Thing is 'LampMoth') )
@ -2644,7 +2702,7 @@ Class SWWMHandler : EventHandler
}
}
if ( (e.Thing.Health > 0) || e.Thing.bKilled || e.Thing.bCorpse ) return;
if ( !e.Thing.player && !e.Thing.bIsMonster && !e.Thing.bCountKill ) return;
if ( !e.Thing.player && !e.Thing.bIsMonster && !e.Thing.bCountKill && !(e.Thing is 'ScriptedMarine') ) return;
if ( (e.DamageSource && e.DamageSource.player && (e.DamageSource != e.Thing)) )
{
let s = SWWMStats.Find(e.DamageSource.player);
@ -2664,7 +2722,8 @@ Class SWWMHandler : EventHandler
lastcombat = AddOneliner("scorekill",1,15);
}
}
if ( !e.Thing.default.bCountKill ) // no credits
// no credits unless it's a counted kill or marine (that isn't friendly)
if ( e.Thing.IsFriend(e.DamageSource) || (!e.Thing.default.bCountKill && !(e.Thing is 'ScriptedMarine')) )
return;
int pnum = e.DamageSource.PlayerNumber();
if ( level.maptime < (lastkill[pnum]+5*Thinker.TICRATE) )
@ -2801,6 +2860,8 @@ Class SWWMHandler : EventHandler
{
if ( e.Thing is 'Inventory' )
CopyFloatBob(e.Thing);
if ( e.Thing.bISMONSTER && !level.monsterfallingdamage )
ForcedFallerDamager.TrackBody(e.Thing);
if ( e.Thing is 'Key' )
{
DoKeyTagFix(e.Thing);

View file

@ -367,7 +367,10 @@ Class DeepImpact : SWWMWeapon
Vector3 rdir = level.Vec3Diff(origin,m.pos).unit();
if ( LineTrace(atan2(rdir.y,rdir.x),rdist,asin(-rdir.z),TRF_THRUACTORS|TRF_ABSPOSITION,origin.z,origin.x,origin.y) || (rdist > 150) || (rdir dot x < 0.7) ) continue;
m.speed = m.vel.length();
m.vel = m.speed*(m.vel.unit()*.2+rdir).unit();
m.vel = m.speed*1.5*(m.vel.unit()*.2+rdir).unit();
Vector3 ndir = m.vel.unit();
m.angle = atan2(ndir.y,ndir.x);
m.pitch = asin(-ndir.z);
if ( m.target == self ) continue;
if ( m.bSEEKERMISSILE ) m.tracer = m.target;
m.target = self;

View file

@ -695,9 +695,9 @@ Class SWWMStatusBar : BaseStatusBar
{
// damage falls down
int initspd = (128-snum.seed);
if ( initspd >= 0 && initspd < 32 ) initspd = 32;
if ( initspd < 0 && initspd > -32 ) initspd = -32;
int boostup = 64+snum.seed2/2;
//if ( initspd >= 0 && initspd < 32 ) initspd = 32;
//if ( initspd < 0 && initspd > -32 ) initspd = -32;
int boostup = 64+snum.seed2;
fo.x = (.05*initspd)*((snum.initialspan-(snum.lifespan-fractic))**.8);
fo.y = -((snum.initialspan-(snum.lifespan-fractic))**1.5)+boostup*sin((90./snum.initialspan)*(level.maptime+fractic-snum.starttic));
}
@ -705,8 +705,8 @@ Class SWWMStatusBar : BaseStatusBar
{
// health falls up (?)
int initspd = (128-snum.seed);
if ( initspd >= 0 && initspd < 32 ) initspd = 32;
if ( initspd < 0 && initspd > -32 ) initspd = -32;
//if ( initspd >= 0 && initspd < 32 ) initspd = 32;
//if ( initspd < 0 && initspd > -32 ) initspd = -32;
int boostup = 16+snum.seed2/4;
fo.x = (.15*initspd)*((snum.initialspan-(snum.lifespan-fractic))**.6);
fo.y = ((snum.initialspan-(snum.lifespan-fractic))**1.2)-boostup*sin((90./snum.initialspan)*(level.maptime+fractic-snum.starttic));

View file

@ -371,7 +371,7 @@ Class SWWMCasing : Actor abstract
override void PostBeginPlay()
{
Super.PostBeginPlay();
deadtimer = 0;
deadtimer = Random[Junk](-30,30);
pitchvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
anglevel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
heat = 1.0;

View file

@ -317,6 +317,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
if ( gameinfo.gametype&GAME_Doom ) str = StringTable.Localize("$SWWM_MISSION_DOOM");
else if ( gameinfo.gametype&GAME_Heretic ) str = StringTable.Localize("$SWWM_MISSION_HERETIC");
else if ( gameinfo.gametype&GAME_Hexen ) str = StringTable.Localize("$SWWM_MISSION_HEXEN");
else if ( gameinfo.gametype&GAME_Strife ) str = StringTable.Localize(players[consoleplayer].logtext);
BrokenLines l = fnt.BreakLines(str,629);
if ( l.Count() > 28 ) l = fnt.BreakLines(str,620);
if ( (l.Count() > 28) && (sel0 < l.Count()-28) )
@ -693,6 +694,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
if ( gameinfo.gametype&GAME_Doom ) str = StringTable.Localize("$SWWM_MISSION_DOOM");
else if ( gameinfo.gametype&GAME_Heretic ) str = StringTable.Localize("$SWWM_MISSION_HERETIC");
else if ( gameinfo.gametype&GAME_Hexen ) str = StringTable.Localize("$SWWM_MISSION_HEXEN");
else if ( gameinfo.gametype&GAME_Strife ) str = StringTable.Localize(players[consoleplayer].logtext);
BrokenLines l = fnt.BreakLines(str,629);
if ( l.Count() > 28 ) l = fnt.BreakLines(str,620);
else return res; // no scrollbar
@ -1180,6 +1182,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
if ( gameinfo.gametype&GAME_Doom ) str = StringTable.Localize("$SWWM_MISSION_DOOM");
else if ( gameinfo.gametype&GAME_Heretic ) str = StringTable.Localize("$SWWM_MISSION_HERETIC");
else if ( gameinfo.gametype&GAME_Hexen ) str = StringTable.Localize("$SWWM_MISSION_HEXEN");
else if ( gameinfo.gametype&GAME_Strife ) str = StringTable.Localize(players[consoleplayer].logtext);
BrokenLines l = fnt.BreakLines(str,629);
if ( l.Count() > 28 ) l = fnt.BreakLines(str,620);
else return res; // no scrollbar
@ -1881,6 +1884,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu
if ( gameinfo.gametype&GAME_Doom ) str = StringTable.Localize("$SWWM_MISSION_DOOM");
else if ( gameinfo.gametype&GAME_Heretic ) str = StringTable.Localize("$SWWM_MISSION_HERETIC");
else if ( gameinfo.gametype&GAME_Hexen ) str = StringTable.Localize("$SWWM_MISSION_HEXEN");
else if ( gameinfo.gametype&GAME_Strife ) str = StringTable.Localize(players[consoleplayer].logtext);
else str = StringTable.Localize("$SWWM_MISSION_NONE");
BrokenLines l = fnt.BreakLines(str,629);
if ( l.Count() > 28 ) l = fnt.BreakLines(str,620);

View file

@ -1889,7 +1889,7 @@ Class DemolitionistShockwave : Actor
let r = Spawn("DemolitionistRadiusShockwave",Vec3Angle(10,i));
r.target = target;
r.angle = i;
r.vel.xy = (cos(i),sin(i))*r.speed;
r.vel.xy = (cos(i),sin(i))*(r.speed+min(special1*.15,20));
r.alpha *= .1+min(special1*.03,.9);
}
for ( int i=0; i<360; i+=5 )