Sigil 2 (v1.0) and Eviternity 2 (RC5) support.
+ Invinciball activation now voiced by Demo (thanks, Vyolette). + Retooled exit line merging (should fix those pesky duplicate exit markers). Note: Oneliners for the Eviternity 2 final boss are not voiced yet.
This commit is contained in:
parent
9a252b72fe
commit
cbb1b2a8cb
36 changed files with 1177 additions and 165 deletions
|
|
@ -185,7 +185,18 @@ Class SWWMHandler : EventHandler
|
|||
if ( !SWWMUtility.IsKnownMap() ) break;
|
||||
if ( s.myplayer != players[consoleplayer] ) continue;
|
||||
int clust = level.cluster;
|
||||
if ( SWWMUtility.IsEviternity() )
|
||||
if ( SWWMUtility.IsEviternityTwo() )
|
||||
{
|
||||
// clusters have to be remapped here
|
||||
if ( clust == 5 ) clust = 1;
|
||||
else if ( (clust == 6) || (clust == 13) ) clust = 2;
|
||||
else if ( (clust == 7) || (clust == 14) ) clust = 3;
|
||||
else if ( (clust == 8) || (clust == 15) ) clust = 4;
|
||||
else if ( (clust == 9) || (clust == 16) ) clust = 5;
|
||||
else if ( (clust == 10) || (clust == 17) ) clust = 6;
|
||||
else if ( (clust == 11) || (clust == 12) || (clust == 18) || (clust == 19) ) clust = 7;
|
||||
}
|
||||
else if ( SWWMUtility.IsEviternity() )
|
||||
{
|
||||
// we have to do some heavy lifting here because episodes don't match clusters
|
||||
if ( level.levelnum <= 5 ) clust = 1;
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ extend Class SWWMHandler
|
|||
l.DirectAdd("Saya");
|
||||
l.DirectAdd("UAC");
|
||||
l.DirectAdd("DemonInvasion");
|
||||
if ( SWWMUtility.IsEviternity() )
|
||||
if ( SWWMUtility.IsEviternity() || SWWMUtility.IsEviternityTwo() )
|
||||
{
|
||||
l.DirectAdd("Gods");
|
||||
l.DirectAdd("SUSAN");
|
||||
|
|
|
|||
|
|
@ -721,7 +721,8 @@ extend Class SWWMHandler
|
|||
else if ( e.Replacee is 'KeyBlue' ) e.Replacement = 'SWWMKeyBlue';
|
||||
else if ( e.Replacee is 'KeyYellow' ) e.Replacement = 'SWWMKeyYellow';
|
||||
else if ( e.Replacee.GetClassName() == 'KeyRed' ) e.Replacement = 'SWWMKeyRed';
|
||||
else if ( (e.Replacee is 'Chainsaw') || (e.Replacee is 'Gauntlets') || (e.Replacee is 'FWeapAxe') ) e.Replacement = SWWMUtility.PickSWWMSlot1();
|
||||
else if ( (e.Replacee is 'Chainsaw') || (e.Replacee is 'Gauntlets') || (e.Replacee is 'FWeapAxe') ) e.Replacement = SWWMUtility.IsEviternityTwo()?SWWMUtility.PickSWWMSlot0():SWWMUtility.PickSWWMSlot1();
|
||||
else if ( (e.Replacee.GetClassName() == 'Perforator') && SWWMUtility.IsEviternityTwo() ) SWWMUtility.PickSWWMSlot0(); // Eviternity 2
|
||||
else if ( (e.Replacee is 'Fist') || (e.Replacee is 'Staff') ) e.Replacement = 'DeepImpact';
|
||||
else if ( (e.Replacee is 'Pistol') || (e.Replacee is 'GoldWand') || (e.Replacee is 'FWeapFist') || (e.Replacee is 'CWeapMace') || (e.Replacee is 'MWeapWand') ) e.Replacement = SWWMUtility.PickSWWMSlot2();
|
||||
else if ( (e.Replacee is 'Shotgun') || (e.Replacee is 'CWeapStaff') ) e.Replacement = SWWMUtility.IsDoomOne()?SWWMUtility.PickDoomSlot3():SWWMUtility.PickSWWMSlot3();
|
||||
|
|
|
|||
|
|
@ -98,6 +98,10 @@ extend Class SWWMHandler
|
|||
ui int cummdamage, lastcummtic; // please do not misread
|
||||
ui Font mSmallFont, mTinyFont;
|
||||
|
||||
bool archangelus_zapped; // skips second phase dialogue
|
||||
bool eviternatus_zapped; // bonus dlg for ynykron survival
|
||||
bool eviternatus_postzap; // so the bonus dlg doesn't play twice
|
||||
|
||||
enum EVanillaMap
|
||||
{
|
||||
MAP_NONE,
|
||||
|
|
@ -118,7 +122,8 @@ extend Class SWWMHandler
|
|||
MAP_HMAP38,
|
||||
MAP_HMAP40,
|
||||
MAP_HMAP60,
|
||||
MAP_EVMAP30 // eviternity
|
||||
MAP_EVMAP30, // eviternity
|
||||
MAP_EVIIMAP30 // eviternity 2
|
||||
};
|
||||
|
||||
static play void AddBoss( int tid, String tag, bool endgame = false )
|
||||
|
|
@ -228,6 +233,8 @@ extend Class SWWMHandler
|
|||
return MAP_HMAP60;
|
||||
if ( mapsum ~== "5C5E5C08AF3572F31CF27318679F2B4E" )
|
||||
return MAP_EVMAP30;
|
||||
if ( mapsum ~== "966EF50BC1C9994F0F303CD1835014FF" ) // subject to change, not final
|
||||
return MAP_EVIIMAP30;
|
||||
return MAP_NONE;
|
||||
}
|
||||
private void VanillaBossSpawn( WorldEvent e )
|
||||
|
|
@ -459,7 +466,74 @@ extend Class SWWMHandler
|
|||
bosstag = "$BT_ARCHANGELUS";
|
||||
e.Thing.GiveInventory('BossMarker',1);
|
||||
e.Thing.GiveInventory('EndgameBossMarker',1);
|
||||
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EVIB");
|
||||
if ( !archangelus_zapped )
|
||||
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EVIB");
|
||||
}
|
||||
}
|
||||
else if ( bossmap == MAP_EVIIMAP30 )
|
||||
{
|
||||
if ( e.Thing.GetClassName() == "EviternatusAntaSpawner" )
|
||||
{
|
||||
bossactors.Push(e.Thing);
|
||||
bossviewactor = e.Thing;
|
||||
bosstag = "$BT_EVITERNATUS";
|
||||
// hack to avoid "all clear" between phases
|
||||
level.total_monsters += 3;
|
||||
}
|
||||
else if ( e.Thing.GetClassName() == "EviternatusAnta" )
|
||||
{
|
||||
// first phase
|
||||
bossactors.Clear();
|
||||
bossviewactor = null;
|
||||
initialized = false;
|
||||
bossactors.Push(e.Thing);
|
||||
e.Thing.StartHealth = e.Thing.Health *= 5;
|
||||
bosstag = "$BT_EVITERNATUS";
|
||||
e.Thing.GiveInventory('BossMarker',1);
|
||||
e.Thing.GiveInventory('EndgameBossMarker',1);
|
||||
// undo the hack (part 1)
|
||||
level.total_monsters--;
|
||||
}
|
||||
else if ( e.Thing.GetClassName() == "EviternatusBete" )
|
||||
{
|
||||
// second phase
|
||||
bossactors.Clear();
|
||||
bossviewactor = null;
|
||||
initialized = false;
|
||||
bossactors.Push(e.Thing);
|
||||
e.Thing.StartHealth = e.Thing.Health *= 5;
|
||||
bosstag = "$BT_EVITERNATUS";
|
||||
e.Thing.GiveInventory('BossMarker',1);
|
||||
e.Thing.GiveInventory('EndgameBossMarker',1);
|
||||
if ( eviternatus_zapped )
|
||||
{
|
||||
eviternatus_postzap = true;
|
||||
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2N");
|
||||
}
|
||||
else SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2L");
|
||||
// undo the hack (part 2)
|
||||
level.total_monsters--;
|
||||
}
|
||||
else if ( e.Thing.GetClassName() == "EviternatusCeph" )
|
||||
{
|
||||
// third phase
|
||||
bossactors.Clear();
|
||||
bossviewactor = null;
|
||||
initialized = false;
|
||||
bossactors.Push(e.Thing);
|
||||
e.Thing.StartHealth = e.Thing.Health *= 5;
|
||||
bosstag = "$BT_EVITERNATUS";
|
||||
e.Thing.GiveInventory('BossMarker',1);
|
||||
e.Thing.GiveInventory('EndgameBossMarker',1);
|
||||
if ( eviternatus_zapped )
|
||||
{
|
||||
if ( eviternatus_postzap )
|
||||
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2O");
|
||||
else SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2N");
|
||||
}
|
||||
else SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2M");
|
||||
// undo the hack (part 3)
|
||||
level.total_monsters--;
|
||||
}
|
||||
}
|
||||
if ( ccloaded && (e.Thing.GetClassName() == "CCards_Boss_Romero") )
|
||||
|
|
@ -481,7 +555,7 @@ extend Class SWWMHandler
|
|||
{
|
||||
if ( !a ) continue;
|
||||
if ( (!a.target || !a.CheckSight(a.target,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY))
|
||||
&& (!bossviewactor || (bossviewactor && !bossviewactor.target)) ) continue;
|
||||
&& (!bossviewactor || (bossviewactor && !bossviewactor.InStateSequence(bossviewactor.CurState,bossviewactor.SeeState))) ) continue;
|
||||
initialized = true;
|
||||
// oneliners
|
||||
if ( bossmap == MAP_DMAP30 )
|
||||
|
|
@ -505,6 +579,16 @@ extend Class SWWMHandler
|
|||
highesttic = gametic;
|
||||
lastcombat = AddOneliner("archangelus",1,300);
|
||||
}
|
||||
else if ( bossmap == MAP_EVIIMAP30 )
|
||||
{
|
||||
highesttic = gametic;
|
||||
if ( a.GetClassName() == "EviternatusAnta" )
|
||||
lastcombat = AddOneliner("eviternatus1",1,40);
|
||||
else if ( a.GetClassName() == "EviternatusBete" )
|
||||
lastcombat = AddOneliner("eviternatus2",1,40);
|
||||
else if ( a.GetClassName() == "EviternatusCeph" )
|
||||
lastcombat = AddOneliner("eviternatus3",1,40);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,19 @@ extend Class SWWMHandler
|
|||
{
|
||||
int clust = 0;
|
||||
bool secret = false;
|
||||
if ( SWWMUtility.IsEviternity() )
|
||||
if ( SWWMUtility.IsEviternityTwo() )
|
||||
{
|
||||
// clusters have to be remapped here
|
||||
let clus = level.cluster;
|
||||
if ( clus == 5 ) clust = 1;
|
||||
else if ( (clus == 6) || (clus == 13) ) clust = 2;
|
||||
else if ( (clus == 7) || (clus == 14) ) clust = 3;
|
||||
else if ( (clus == 8) || (clus == 15) ) clust = 4;
|
||||
else if ( (clus == 9) || (clus == 16) ) clust = 5;
|
||||
else if ( (clus == 10) || (clus == 17) ) clust = 6;
|
||||
else if ( (clus == 11) || (clus == 12) || (clus == 18) || (clus == 19) ) clust = 7;
|
||||
}
|
||||
else if ( SWWMUtility.IsEviternity() )
|
||||
{
|
||||
// we have to do some heavy lifting here because episodes don't match clusters
|
||||
if ( level.levelnum <= 5 ) clust = 1;
|
||||
|
|
@ -270,6 +282,9 @@ extend Class SWWMHandler
|
|||
case MAP_EVMAP30:
|
||||
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EVIA");
|
||||
break;
|
||||
case MAP_EVIIMAP30:
|
||||
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2K");
|
||||
break;
|
||||
case MAP_HE1M8_HE4M8:
|
||||
if ( level.mapname ~== "E1M8" ) SendInterfaceEvent(consoleplayer,"swwmsetdialogue.MAW");
|
||||
else SendInterfaceEvent(consoleplayer,"swwmsetdialogue.HEADS");
|
||||
|
|
@ -309,6 +324,9 @@ extend Class SWWMHandler
|
|||
|| (csum ~== "09B30C9DA9D73D3D5A709502FBB947AA")
|
||||
|| (csum ~== "6EAD80DA1F30B4B3546FA294EEF9F87C") )
|
||||
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.SIGIL");
|
||||
// SIGIL 2 E6M8
|
||||
if ( csum ~== "5BA3D00F6B64F6268E11C6851D47ECBF" )
|
||||
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.SIGIL2");
|
||||
// Doom 2 MAP11
|
||||
else if ( (csum ~== "73D9E03CEE7BF1A97EFD2EAD86688EF8")
|
||||
|| (csum ~== "F4F2A769609988837458772AAE99008C")
|
||||
|
|
@ -334,6 +352,28 @@ extend Class SWWMHandler
|
|||
// MAP25
|
||||
else if ( csum ~== "196BC735473C593F924A59B238574C35" )
|
||||
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.SLA");
|
||||
// Eviternity 2 (RC5)
|
||||
// MAP01
|
||||
else if ( csum ~== "3907915FEC75DEE3A53374D90C4F4B65" )
|
||||
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2A");
|
||||
// MAP05
|
||||
else if ( csum ~== "58A6A5A8214B0C2C28C9DADC349F2853" )
|
||||
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2E");
|
||||
// MAP10
|
||||
else if ( csum ~== "9525AF4F176085C925124CF118E91DF1" )
|
||||
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2F");
|
||||
// MAP15
|
||||
else if ( csum ~== "24EFC6868344643D3D4C56BDF2D1E8C7" )
|
||||
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2G");
|
||||
// MAP20
|
||||
else if ( csum ~== "81B7BDE4BD0E98A9B8741B0405FAB839" )
|
||||
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2H");
|
||||
// MAP25
|
||||
else if ( csum ~== "56A3EB18F91B2AE42DCF327888AEAA0A" )
|
||||
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2I");
|
||||
// MAP33
|
||||
else if ( csum ~== "043FE06534270E95882CA128AF7B0402" )
|
||||
SendInterfaceEvent(consoleplayer,"swwmsetdialogue.EV2P");
|
||||
// Deathkings
|
||||
// Blight
|
||||
else if ( csum ~== "E3EFB0156A20ADF2DF00915A0EA85DF5" )
|
||||
|
|
@ -425,9 +465,10 @@ extend Class SWWMHandler
|
|||
allclearsector = 18414; // only check all-clear if the player is standing in this sector
|
||||
gdat.disablerevive = true; // ONE TRY
|
||||
}
|
||||
// for skipping over merged exit lines (sharing vertices)
|
||||
Array<Line> skipme;
|
||||
skipme.Clear();
|
||||
Array<Line> exits;
|
||||
Array<int> exittypes;
|
||||
exits.Clear();
|
||||
exittypes.Clear();
|
||||
// find exit lines, and use lines that aren't exits
|
||||
foreach ( l:level.Lines )
|
||||
{
|
||||
|
|
@ -442,68 +483,51 @@ extend Class SWWMHandler
|
|||
}
|
||||
let [isexit, exittype] = SWWMUtility.IsExitLine(l);
|
||||
if ( !isexit ) continue;
|
||||
exits.Push(l);
|
||||
exittypes.Push(exittype);
|
||||
}
|
||||
// for skipping over merged exit lines (sharing vertices)
|
||||
Array<Line> skipme;
|
||||
skipme.Clear();
|
||||
for ( int i=0; i<exits.Size(); i++ )
|
||||
{
|
||||
let l = exits[i];
|
||||
if ( skipme.Find(l) < skipme.Size() ) continue;
|
||||
skipme.Push(l);
|
||||
// look for connected lines
|
||||
// only stop once we cannot find more
|
||||
Array<Line> con;
|
||||
con.Clear();
|
||||
con.Push(l);
|
||||
int found;
|
||||
if ( l.frontsector )
|
||||
do
|
||||
{
|
||||
do
|
||||
found = 0;
|
||||
for ( int j=0; j<exits.Size(); j++ )
|
||||
{
|
||||
found = 0;
|
||||
foreach ( l2:l.frontsector.Lines )
|
||||
let l2 = exits[j];
|
||||
if ( (l2 == l) || !SWWMUtility.SameSpecial(l,l2) || (skipme.Find(l2) < skipme.Size()) || (con.Find(l2) < con.size()) ) continue;
|
||||
// needs to have at least one point in common with this one or any of the added lines
|
||||
bool nomatches = true;
|
||||
foreach ( c:con )
|
||||
{
|
||||
if ( (l2.special != l.special) || (con.Find(l2) < con.Size()) ) continue;
|
||||
// needs to have a point in common with this one or any of the added lines
|
||||
bool nomatches = true;
|
||||
foreach ( c:con )
|
||||
{
|
||||
if ( (l2.v1 != c.v1) && (l2.v2 != c.v2) && (l2.v1 != c.v2) && (l2.v2 != c.v1) )
|
||||
continue;
|
||||
nomatches = false;
|
||||
break;
|
||||
}
|
||||
if ( nomatches ) continue;
|
||||
skipme.Push(l2);
|
||||
con.Push(l2);
|
||||
found++;
|
||||
if ( (l2.v1.p != c.v1.p) && (l2.v2.p != c.v2.p) && (l2.v1.p != c.v2.p) && (l2.v2.p != c.v1.p) )
|
||||
continue;
|
||||
nomatches = false;
|
||||
break;
|
||||
}
|
||||
if ( nomatches ) continue;
|
||||
found++;
|
||||
skipme.Push(l2);
|
||||
con.Push(l2);
|
||||
}
|
||||
while ( found > 0 );
|
||||
}
|
||||
if ( l.backsector )
|
||||
{
|
||||
do
|
||||
{
|
||||
found = 0;
|
||||
foreach ( l2:l.backsector.Lines )
|
||||
{
|
||||
if ( (l2.special != l.special) || (con.Find(l2) < con.Size()) ) continue;
|
||||
// needs to have a point in common with this one or any of the added lines
|
||||
bool nomatches = true;
|
||||
foreach ( s:skipme )
|
||||
{
|
||||
if ( (l2.v1 != s.v1) && (l2.v2 != s.v2) && (l2.v1 != s.v2) && (l2.v2 != s.v1) )
|
||||
continue;
|
||||
nomatches = false;
|
||||
break;
|
||||
}
|
||||
if ( nomatches ) continue;
|
||||
skipme.Push(l2);
|
||||
con.Push(l2);
|
||||
found++;
|
||||
}
|
||||
}
|
||||
while ( found > 0 );
|
||||
}
|
||||
while ( found > 0 );
|
||||
Vector3 lpos = (0,0,0);
|
||||
foreach ( c:con )
|
||||
lpos += SWWMUtility.UseLinePos(c);
|
||||
lpos /= con.Size();
|
||||
SWWMInterest.Spawn(self,lpos,theline:l,theexit:exittype);
|
||||
SWWMInterest.Spawn(self,lpos,theline:l,theexit:exittypes[i]);
|
||||
}
|
||||
// spawn loot
|
||||
if ( !deathmatch ) Chancebox.SpawnChanceboxes();
|
||||
|
|
|
|||
|
|
@ -116,6 +116,13 @@ extend Class SWWMHandler
|
|||
let t = new("KoraxYeeted");
|
||||
t.ChangeStatNum(Thinker.STAT_USER);
|
||||
}
|
||||
// Archangelus instakill
|
||||
if ( (e.Thing.GetClassName() == "ArchangelusA") && (e.Thing.DamageType == 'Ynykron') )
|
||||
{
|
||||
// this will skip the second phase dialogue
|
||||
// (note that you can only have an Ynykron in this fight by cheating, tho)
|
||||
archangelus_zapped = true;
|
||||
}
|
||||
// Archangelus death
|
||||
if ( e.Thing.GetClassName() == "ArchangelusB" )
|
||||
{
|
||||
|
|
@ -128,6 +135,12 @@ extend Class SWWMHandler
|
|||
a.DamageMobj(e.Thing,e.Thing,a.Health,'EndMii',DMG_FORCED|DMG_THRUSTLESS);
|
||||
}
|
||||
}
|
||||
// Eviternatus instakill
|
||||
if ( ((e.Thing.GetClassName() == "EviternatusAnta") || (e.Thing.GetClassName() == "EviternatusBete")) && (e.Thing.DamageType == 'Ynykron') )
|
||||
{
|
||||
// this will trigger special dialogue on the next phase
|
||||
eviternatus_zapped = true;
|
||||
}
|
||||
if ( swwm_partytime )
|
||||
{
|
||||
let pt = Actor.Spawn("PartyTime",e.Thing.pos);
|
||||
|
|
@ -264,6 +277,35 @@ extend Class SWWMHandler
|
|||
e.Thing.SetTag("$FN_FCAPTAIN");
|
||||
else if ( e.Thing.GetClassName() == "NightmareDemon" )
|
||||
e.Thing.SetTag("$FN_NDEMON");
|
||||
// eviternity 2 stuff
|
||||
else if ( e.Thing.GetClassName() == "FormerCorporal" )
|
||||
e.Thing.SetTag("$FN_FCORPORAL");
|
||||
else if ( e.Thing.GetClassName() == "AstralArachnotron" )
|
||||
e.Thing.SetTag("$FN_ASTRALARACH");
|
||||
else if ( e.Thing.GetClassName() == "AstralCacodemon" )
|
||||
e.Thing.SetTag("$FN_ASTRAL");
|
||||
else if ( e.Thing.GetClassName() == "Veilimp" )
|
||||
e.Thing.SetTag("$FN_VEILIMP");
|
||||
else if ( (e.Thing.GetClassName() == "GoldenAstralCaco")
|
||||
|| (e.Thing.GetClassName() == "GoldenAstralCacoBoss") )
|
||||
e.Thing.SetTag("$FN_ASTRALGOLD");
|
||||
else if ( e.Thing.GetClassName() == "DukeOfHell" )
|
||||
e.Thing.SetTag("$FN_DUKE");
|
||||
else if ( e.Thing.GetClassName() == "AstralBabycaco" )
|
||||
e.Thing.SetTag("$FN_ASTRALBABY");
|
||||
else if ( e.Thing.GetClassName() == "NAC" )
|
||||
e.Thing.SetTag("$FN_NAC");
|
||||
else if ( e.Thing.GetClassName() == "AstralMancubus" )
|
||||
e.Thing.SetTag("$FN_ASTRALFATSO");
|
||||
else if ( (e.Thing.GetClassName() == "NecromenaceA")
|
||||
|| (e.Thing.GetClassName() == "NecromenaceB")
|
||||
|| (e.Thing.GetClassName() == "NecromenaceC")
|
||||
|| (e.Thing.GetClassName() == "NecromenaceD") )
|
||||
e.Thing.SetTag("$FN_NECROMENACE");
|
||||
else if ( (e.Thing.GetClassName() == "EviternatusAnta")
|
||||
|| (e.Thing.GetClassName() == "EviternatusBete")
|
||||
|| (e.Thing.GetClassName() == "EviternatusCeph") )
|
||||
e.Thing.SetTag("$FN_EVITERNATUS");
|
||||
// doom vacation stuff
|
||||
else if ( indoomvacation )
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue