Yet more deathmatch stuff.

This commit is contained in:
Mari the Deer 2021-06-04 21:35:17 +02:00
commit da703e3e35
8 changed files with 178 additions and 25 deletions

View file

@ -632,6 +632,11 @@ SWWM_GAMMAMODE1 = "Semi-Auto";
SWWM_GAMMAMODE2 = "3-Round Burst";
SWWM_GAMMAMODE3 = "Full Auto";
SWWM_GAMMAMODE4 = "FULLER AUTO";
SWWM_DMRANK = "Rank:";
SWWM_DMSPREAD = "Spread:";
SWWM_PLACE1 = "1st";
SWWM_PLACE2 = "2nd";
SWWM_PLACE3 = "3rd";
// NOTE: do not localize these
SWWM_ZNVTXT1 = "\cdDemolitionist\c-, it is me, \chZanaveth The Corruptor\c-. I have been witness of the act you have now acted, yes.";
SWWM_ZNVTXT2 = "It is \cf%d\c- years since... and those magic words, I can see them again. Much impressed, very much impressed.";

View file

@ -543,6 +543,14 @@ SWWM_GAMMAMODE1 = "Semiautomático";
SWWM_GAMMAMODE2 = "Triple Ráfaga";
SWWM_GAMMAMODE3 = "Automático";
SWWM_GAMMAMODE4 = "SUPERAUTOMÁTICO";
SWWM_DMRANK = "Posición:";
SWWM_DMSPREAD = "Distancia:";
SWWM_PLACE1 = "1º";
SWWM_PLACE2 = "2º";
SWWM_PLACE3 = "3º";
SWWM_PLACE1_GENDER1 = "1ª";
SWWM_PLACE2_GENDER1 = "2ª";
SWWM_PLACE3_GENDER1 = "3ª";
// boss tags
BT_BRUISERS = "Hermanos de Guerra";
BT_CYBIE = "Tirano de Babel";

View file

@ -1,3 +1,3 @@
[default]
SWWM_MODVER="\chSWWM \czGZ\c- \cw0.9.11b-pre r525 \cu(Fri 4 Jun 18:59:04 CEST 2021)\c-";
SWWM_SHORTVER="\cw0.9.11b-pre r525 \cu(2021-06-04 18:59:04)\c-";
SWWM_MODVER="\chSWWM \czGZ\c- \cw0.9.11b-pre r526 \cu(Fri 4 Jun 21:35:17 CEST 2021)\c-";
SWWM_SHORTVER="\cw0.9.11b-pre r526 \cu(2021-06-04 21:35:17)\c-";

View file

@ -73,7 +73,8 @@ extend Class SWWMHandler
}
if ( spawnme ) SWWMScoreObj.Spawn(-e.Damage,e.Thing.Vec3Offset(FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8)+e.Thing.Height/2),ST_Damage,e.Thing);
// update combat tracker for it
if ( !(e.Thing is 'BossBrain') )
// note: don't update if it's a hostile player unless hurt by you or a friend
if ( !(e.Thing is 'BossBrain') && (!e.Thing.player || (!e.Thing.IsFriend(players[consoleplayer].mo) && e.DamageSource && e.DamageSource.IsFriend(players[consoleplayer].mo))) )
{
for ( SWWMCombatTracker t=trackers; t; t=t.next )
{

View file

@ -235,7 +235,7 @@ extend Class SWWMHandler
continue;
if ( !a.player && !a.bSOLID && !a.bSHOOTABLE && !a.bISMONSTER && !a.bFRIENDLY && !(a is 'Inventory') && !(a is 'Chancebox') )
continue;
if ( !thesight && !(a.IsFriend(players[consoleplayer].mo) && !(a.player && (a.player.mo != a))) && !players[consoleplayer].Camera.CheckSight(a,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) )
if ( !thesight && !(deathmatch && (a is 'Inventory') && !a.bDROPPED) && !(a.IsFriend(players[consoleplayer].mo) && !(a.player && (a.player.mo != a))) && !players[consoleplayer].Camera.CheckSight(a,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) )
continue;
if ( a.bKILLED || (a.Health <= 0) )
continue;
@ -291,7 +291,7 @@ extend Class SWWMHandler
continue;
if ( !a.player && !a.bSOLID && !a.bSHOOTABLE && !a.bISMONSTER && !a.bFRIENDLY && !(a is 'Inventory') && !(a is 'Chancebox') )
continue;
if ( !thesight && !a.IsFriend(players[consoleplayer].mo) && !players[consoleplayer].Camera.CheckSight(a,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) )
if ( !thesight && !(deathmatch && (a is 'Inventory') && !a.bDROPPED) && !a.IsFriend(players[consoleplayer].mo) && !players[consoleplayer].Camera.CheckSight(a,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) )
continue;
if ( a.bKILLED || (a.Health <= 0) )
continue;

View file

@ -70,6 +70,13 @@ Class SWWMStatusBar : BaseStatusBar
Color mm_backcolor, mm_cdwallcolor, mm_efwallcolor, mm_fdwallcolor, mm_gridcolor, mm_interlevelcolor, mm_intralevelcolor, mm_lockedcolor, mm_notseencolor, mm_portalcolor, mm_secretsectorcolor, mm_secretwallcolor, mm_specialwallcolor, mm_thingcolor, mm_thingcolor_citem, mm_thingcolor_friend, mm_thingcolor_item, mm_thingcolor_monster, mm_thingcolor_ncmonster, mm_thingcolor_shootable, mm_thingcolor_vipitem, mm_thingcolor_missile, mm_tswallcolor, mm_unexploredsecretcolor, mm_wallcolor, mm_xhaircolor, mm_yourcolor;
bool mm_displaylocks, mm_drawautopage;
// deathmatch stuff
int playercount, rank, lead;
bool tiedscore;
Array<PlayerInfo> sortplayers;
Array<bool> teamactive;
Array<int> teamscore;
// if playing in Japanese, returns an alternate font of the same height
// Tewi -> MPlus
// Miniwi -> k6x8
@ -375,6 +382,34 @@ Class SWWMStatusBar : BaseStatusBar
qsort_itemsense(a,p+1,h);
}
// quicksort (player scores)
private int partition_playerscore( Array<PlayerInfo> a, int l, int h )
{
PlayerInfo pv = a[h];
int i = (l-1);
for ( int j=l; j<=(h-1); j++ )
{
if ( pv.fragcount < a[j].fragcount )
{
i++;
PlayerInfo tmp = a[j];
a[j] = a[i];
a[i] = tmp;
}
}
PlayerInfo tmp = a[h];
a[h] = a[i+1];
a[i+1] = tmp;
return i+1;
}
private void qsort_playerscore( Array<PlayerInfo> a, int l, int h )
{
if ( l >= h ) return;
int p = partition_playerscore(a,l,h);
qsort_playerscore(a,l,p-1);
qsort_playerscore(a,p+1,h);
}
override void Tick()
{
Super.Tick();
@ -465,7 +500,6 @@ Class SWWMStatusBar : BaseStatusBar
if ( !trk.mytarget || trk.mytarget.bDORMANT || trk.mytarget.bINVISIBLE ) continue;
// ignore local player
if ( trk.mytarget == CPlayer.mo ) continue;
if ( trk.myplayer && deathmatch ) continue; // no players in dm
if ( trk.mytarget is 'PlayerGone' ) continue; // ignore "gone" players
int mtime = 35;
if ( thesight && (trk.lasthealth > 0) ) mtime += 105;
@ -587,6 +621,55 @@ Class SWWMStatusBar : BaseStatusBar
// also try with different endianness, just in case
DetachMessageID(0x4e504557); // WEPN
DetachMessageID(0x564e4953); // SINV
// deathmatch stuff
if ( !deathmatch ) return;
if ( teamplay )
{
if ( teamactive.Size() != Teams.Size() ) teamactive.Resize(Teams.Size());
if ( teamscore.Size() != Teams.Size() ) teamscore.Resize(Teams.Size());
for ( int i=0; i<Teams.Size(); i++ )
{
teamactive[i] = false;
teamscore[i] = 0;
}
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] ) continue;
int team = players[i].GetTeam();
if ( team != -1 )
{
teamactive[team] = true;
teamscore[team] += players[i].fragcount;
}
}
return;
}
playercount = 0;
int highscore = int.min;
tiedscore = false;
rank = 1;
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] ) continue;
playercount++;
if ( players[i] == CPlayer ) continue;
if ( players[i].fragcount > CPlayer.fragcount )
rank += 1;
else if ( players[i].fragcount == CPlayer.fragcount )
tiedscore = true;
if ( players[i].fragcount > highscore )
highscore = players[i].fragcount;
}
if ( sortplayers.Size() != playercount ) sortplayers.Resize(playercount);
for ( int i=0, j=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] ) continue;
sortplayers[j++] = players[i];
}
// sort players by score
qsort_playerscore(sortplayers,0,playercount-1);
if ( playercount <= 1 ) highscore = CPlayer.fragcount;
lead = CPlayer.fragcount-highscore;
}
override void Init()
@ -748,7 +831,7 @@ Class SWWMStatusBar : BaseStatusBar
if ( ndc.z >= 1. ) continue;
Vector2 vpos = SWWMUtility.NDCToViewport(projdata,ndc);
tag = targ.mytag;
if ( tag != "" )
if ( (tag != "") && !targ.myplayer )
{
if ( targ.legged && (targ.mutated || swwm_ldspoil) )
{
@ -767,8 +850,15 @@ Class SWWMStatusBar : BaseStatusBar
Vector2 barpos = vpos-(barsiz/2.);
barpos.y -= 16.;
Font fnt = LangFont(swwm_bigtags?mTewiFont:mMiniwiFont);
int col = Font.CR_WHITE;
if ( teamplay )
{
int team = targ.myplayer.GetTeam();
if ( team != -1 ) col = Font.FindFontColor(Teams[team].mName); // this works in practice because team names are the same as their text colors
if ( col == -1 ) col = Font.CR_WHITE;
}
if ( swwm_targettags || targ.myplayer && (tag != "") )
Screen.DrawText(fnt,Font.CR_WHITE,(barpos.x+barsiz.x/2.-(fnt.StringWidth(tag)*hsb.x)/2.)/hsb.x,(barpos.y-fnt.GetHeight()*hsb.y)/hsb.y,tag,DTA_VirtualWidthF,ssb.x,DTA_VirtualHeightF,ssb.y,DTA_KeepRatio,true,DTA_Alpha,alph,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
Screen.DrawText(fnt,col,(barpos.x+barsiz.x/2.-(fnt.StringWidth(tag)*hsb.x)/2.)/hsb.x,(barpos.y-fnt.GetHeight()*hsb.y)/hsb.y,tag,DTA_VirtualWidthF,ssb.x,DTA_VirtualHeightF,ssb.y,DTA_KeepRatio,true,DTA_Alpha,alph,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
Screen.DrawTexture(EnemyBTex,false,barpos.x/hsb.x,barpos.y/hsb.y,DTA_VirtualWidthF,ssb.x,DTA_VirtualHeightF,ssb.y,DTA_KeepRatio,true,DTA_Alpha,alph,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
double ht = clamp(targ.intp.GetValue(),0,targ.maxhealth*10);
double hw = (min(ht,targ.maxhealth)*50.)/targ.maxhealth;
@ -1479,6 +1569,14 @@ Class SWWMStatusBar : BaseStatusBar
}
}
private String OrdinalStr( int val, int gender )
{
String lstr = "SWWM_PLACE"..val.."_GENDER"..gender;
String str = StringTable.Localize("$"..lstr);
if ( str != lstr ) return str;
return StringTable.Localize("$SWWM_PLACE"..val);
}
private void DrawScore()
{
String sstr;
@ -1539,19 +1637,19 @@ Class SWWMStatusBar : BaseStatusBar
yy += fnt.GetHeight();
}
fnt = LangFont(mMiniwiFont);
if ( (level.total_monsters > 0) && am_showmonsters )
if ( (level.total_monsters > 0) && am_showmonsters && !deathmatch )
{
str = String.Format("\cxK \c-%d\cu/\c-%d",level.killed_monsters,level.total_monsters);
Screen.DrawText(fnt,(level.killed_monsters>=level.total_monsters)?Font.CR_GOLD:Font.CR_WHITE,xx-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy += fnt.GetHeight();
}
if ( (level.total_items > 0) && am_showitems )
if ( (level.total_items > 0) && am_showitems && !deathmatch )
{
str = String.Format("\cxI \c-%d\cu/\c-%d",level.found_items,level.total_items);
Screen.DrawText(fnt,(level.found_items>=level.total_items)?Font.CR_GOLD:Font.CR_WHITE,xx-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy += fnt.GetHeight();
}
if ( (level.total_secrets > 0) && am_showsecrets )
if ( (level.total_secrets > 0) && am_showsecrets && !deathmatch )
{
str = String.Format("\cxS \c-%d\cu/\c-%d",level.found_secrets,level.total_secrets);
Screen.DrawText(fnt,(level.found_secrets>=level.total_secrets)?Font.CR_GOLD:Font.CR_WHITE,xx-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
@ -1574,8 +1672,47 @@ Class SWWMStatusBar : BaseStatusBar
}
yy += 3;
}
if ( deathmatch )
{
yy += 9;
if ( playercount <= 1 ) return;
xx = int(ss.x-(margin+2));
String str;
Font fnt = LangFont(mTewiFont);
if ( teamplay )
{
// draw team scores
for ( int i=0; i<teamscore.Size(); i++ )
{
if ( !teamactive[i] ) continue;
str = String.Format("\cx%s \c-%d",Teams[i].mName,teamscore[i]);
Screen.DrawText(fnt,Font.CR_WHITE,xx-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy += fnt.GetHeight();
}
}
else
{
// draw rank and spread like in UT
if ( tiedscore ) str = String.Format("\cx%s \cg%d\cr/\cg%d\c-",StringTable.Localize("$SWWM_DMRANK"),rank,playercount);
else str = String.Format("\cx%s \cj%d\cu/\cj%d\c-",StringTable.Localize("$SWWM_DMRANK"),rank,playercount);
Screen.DrawText(fnt,Font.CR_WHITE,xx-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy += fnt.GetHeight();
if ( lead > 0 ) str = String.Format("\cx%s \cj+%d\c-",StringTable.Localize("$SWWM_DMSPREAD"),lead);
else str = String.Format("\cx%s \cj%d\c-",StringTable.Localize("$SWWM_DMSPREAD"),lead);
Screen.DrawText(fnt,Font.CR_WHITE,xx-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy += fnt.GetHeight()+3;
// draw top 3 players
for ( int i=0; i<min(3,playercount); i++ )
{
if ( sortplayers[i].fragcount < 0 ) str = String.Format("\cx#%d: \c-%s\c- \cr(\cg%d\cr)\c-",i+1,sortplayers[i].GetUserName(),sortplayers[i].fragcount);
else str = String.Format("\cx%s: \c-%s\c- \cu(\cj%d\cu)\c-",OrdinalStr(i+1,sortplayers[i].GetGender()),sortplayers[i].GetUserName(),sortplayers[i].fragcount);
Screen.DrawText(fnt,Font.CR_WHITE,xx-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy += fnt.GetHeight();
}
}
return;
}
// draw key icons
if ( deathmatch ) return;
Vector2 keypos = (ss.x-(margin+2),yy);
int colc = 0;
double colh = 0;

View file

@ -1963,6 +1963,10 @@ Class Demolitionist : PlayerPawn
player.mo.CalcHeight();
if ( player.damagecount ) player.damagecount--;
if ( player.poisoncount ) player.poisoncount--;
// solid unless we can respawn, for safety
if ( multiplayer || level.AllowRespawn || sv_singleplayerrespawn || G_SkillPropertyInt(SKILLP_PlayerRespawn) )
bSolid = false;
else bSolid = true;
if ( player.viewheight <= 6 )
{
deadtimer++;
@ -3129,7 +3133,7 @@ Class Demolitionist : PlayerPawn
XZW7 M 2
{
A_DemoScream();
bSOLID = true; // we need this to avoid clipping into things
A_NoBlocking();
}
XZW8 GHIJK 2;
XZW8 L 1 A_DMFade();

View file

@ -343,7 +343,7 @@ Class SWWMCombatTracker : Thinker
t.myplayer = target.player;
t.next = hnd.trackers;
t.bBOSS = target.bBOSS;
t.bFRIENDLY = target.bFRIENDLY;
t.bFRIENDLY = target.IsFriend(players[consoleplayer].mo);
if ( hnd.trackers )
{
hnd.trackers.prev = t;
@ -403,13 +403,6 @@ Class SWWMCombatTracker : Thinker
// don't update dormant targets
if ( mytarget.bDORMANT )
return;
// in deathmatch, don't update for hostile players
if ( deathmatch && mytarget.player && (mytarget.player.mo == mytarget) )
{
if ( teamplay && (mytarget.player.GetTeam() != players[consoleplayer].GetTeam()) )
return;
else if ( !teamplay ) return;
}
// only update height/position while alive
bool heightchanged = false;
if ( height != mytarget.height ) heightchanged = true;
@ -456,12 +449,12 @@ Class SWWMCombatTracker : Thinker
Console.Printf(StringTable.Localize("$SWWM_LTFORM"),mytag);
}
}
bFRIENDLY = mytarget.bFRIENDLY;
bFRIENDLY = mytarget.IsFriend(players[consoleplayer].mo);
if ( mytarget.Health < lasthealth ) firsthit = true;
lasthealth = mytarget.Health;
intp.Update(lasthealth);
// special update conditions
if ( dbar )
if ( dbar && !mytarget.player )
{
if ( (dbar == 2) && (lasthealth >= maxhealth) )
return;
@ -470,8 +463,13 @@ Class SWWMCombatTracker : Thinker
}
if ( (mytarget.bISMONSTER || mytarget.player) && !mytarget.bINVISIBLE && !mytarget.bCORPSE )
{
// players (but not voodoo dolls), always visible
if ( mytarget.player && (mytarget.player.mo == mytarget) ) updated = level.maptime+35;
// players (but not voodoo dolls), always if friendly, otherwise only update if visible
if ( mytarget.player && (mytarget.player.mo == mytarget) )
{
if ( mytarget.IsFriend(players[consoleplayer].mo) ) updated = level.maptime+35;
else if ( ((mxdist <= 0) || (mytarget.Vec3To(players[consoleplayer].Camera).length() < mxdist)) && players[consoleplayer].Camera.CheckSight(mytarget,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) )
updated = level.maptime;
}
// friendlies within a set distance
else if ( mytarget.bFRIENDLY && ((mxdist <= 0) || (mytarget.Vec3To(players[consoleplayer].Camera).length() < mxdist)) && players[consoleplayer].Camera.CheckSight(mytarget,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) ) updated = level.maptime+35;
// enemies within a set distance that have us as target