Implement "dropped item magnet".
This commit is contained in:
parent
b518dfef64
commit
3fcab013b7
11 changed files with 215 additions and 47 deletions
|
|
@ -944,8 +944,6 @@ Class Chancebox : Actor
|
|||
// spawn another smaller chancebox
|
||||
// (chance increases for the inner box, up until a scale factor of 50% is reached)
|
||||
let a = Spawn("Chancebox",pos+(0,0,3*scale.y));
|
||||
a.bDROPPED = false;
|
||||
a.bNOGRAVITY = false;
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
a.angle = angle;
|
||||
a.scale *= scale.x-.125;
|
||||
|
|
@ -964,7 +962,13 @@ Class Chancebox : Actor
|
|||
if ( !vipitemdrop ) vipitemdrop = "GrilledCheeseSandwich";
|
||||
let a = Spawn((!Random[Chancebox](0,2)&&vipammodrop)?vipammodrop:vipitemdrop,pos);
|
||||
a.bDROPPED = false;
|
||||
a.bNOGRAVITY = false;
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
}
|
||||
else if ( !Random[Chancebox](0,2) && SWWMUtility.CheckNeedsItem("ItamexHammer") )
|
||||
{
|
||||
// sometimes mapsets don't have chainsaw spawns for whatever reason
|
||||
let a = Spawn("ItamexHammer",pos);
|
||||
a.bDROPPED = false;
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
}
|
||||
else if ( !Random[Chancebox](0,2) && SWWMUtility.ItemExists("CandyGun") )
|
||||
|
|
@ -972,8 +976,7 @@ Class Chancebox : Actor
|
|||
for ( int i=0; i<=6; i++ )
|
||||
{
|
||||
let a = Spawn((i==0)?"CandyGun":"CandyGunBullets",pos);
|
||||
a.bDROPPED = false;
|
||||
a.bNOGRAVITY = false;
|
||||
a.bDROPPED = (i!=0);
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
if ( i > 0 ) a.vel.xy = (cos(i*60),sin(i*60))*FRandom[Chancebox](1,2);
|
||||
}
|
||||
|
|
@ -983,16 +986,14 @@ Class Chancebox : Actor
|
|||
for ( int i=0; i<3; i++ )
|
||||
{
|
||||
let a = Spawn("SilverBullets2",pos);
|
||||
a.bDROPPED = false;
|
||||
a.bNOGRAVITY = false;
|
||||
a.bDROPPED = true;
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
a.vel.xy = (cos(i*120),sin(i*120))*FRandom[Chancebox](1,2);
|
||||
}
|
||||
for ( int i=0; i<6; i++ )
|
||||
{
|
||||
let a = Spawn("SilverBullets",pos);
|
||||
a.bDROPPED = false;
|
||||
a.bNOGRAVITY = false;
|
||||
a.bDROPPED = true;
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
a.vel.xy = (cos(i*60),sin(i*60))*FRandom[Chancebox](3,4);
|
||||
}
|
||||
|
|
@ -1000,65 +1001,87 @@ Class Chancebox : Actor
|
|||
else if ( Random[Chancebox](0,1) && SWWMUtility.ItemExists("Hellblazer") )
|
||||
{
|
||||
let a = Spawn("HellblazerWarheads",pos);
|
||||
a.bDROPPED = false;
|
||||
a.bNOGRAVITY = false;
|
||||
a.bDROPPED = true;
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
for ( int i=0; i<3; i++ )
|
||||
{
|
||||
a = Spawn("HellblazerRavagers",pos);
|
||||
a.bDROPPED = false;
|
||||
a.bNOGRAVITY = false;
|
||||
a.bDROPPED = true;
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
a.vel.xy = (cos(i*120),sin(i*120))*FRandom[Chancebox](1,2);
|
||||
}
|
||||
for ( int i=0; i<5; i++ )
|
||||
{
|
||||
a = Spawn("HellblazerCrackshots",pos);
|
||||
a.bDROPPED = false;
|
||||
a.bNOGRAVITY = false;
|
||||
a.bDROPPED = true;
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
a.vel.xy = (cos(i*72),sin(i*72))*FRandom[Chancebox](3,4);
|
||||
}
|
||||
for ( int i=0; i<8; i++ )
|
||||
{
|
||||
a = Spawn("HellblazerMissiles",pos);
|
||||
a.bDROPPED = false;
|
||||
a.bNOGRAVITY = false;
|
||||
a.bDROPPED = true;
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
a.vel.xy = (cos(i*45),sin(i*45))*FRandom[Chancebox](5,6);
|
||||
}
|
||||
}
|
||||
else if ( Random[Chancebox](0,1) && SWWMUtility.ItemExists("HeavyMahSheenGun") )
|
||||
{
|
||||
let a = Spawn("SheenBigAmmo",pos);
|
||||
a.bDROPPED = true;
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
for ( int i=0; i<5; i++ )
|
||||
{
|
||||
a = Spawn("SheenSmallAmmo",pos);
|
||||
a.bDROPPED = true;
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
a.vel.xy = (cos(i*72),sin(i*72))*FRandom[Chancebox](3,4);
|
||||
}
|
||||
}
|
||||
else if ( Random[Chancebox](0,1) && SWWMUtility.ItemExists("Spreadgun") )
|
||||
{
|
||||
let a = Spawn("BlackShell",pos);
|
||||
a.bDROPPED = false;
|
||||
a.bNOGRAVITY = false;
|
||||
a.bDROPPED = true;
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
for ( int i=0; i<8; i++ )
|
||||
{
|
||||
a = Spawn((i%2)?"PurpleShell":"BlueShell",pos);
|
||||
a.bDROPPED = false;
|
||||
a.bNOGRAVITY = false;
|
||||
a.bDROPPED = true;
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
a.vel.xy = (cos(i*72),sin(i*72))*FRandom[Chancebox](2,3);
|
||||
a.vel.xy = (cos(i*45),sin(i*45))*FRandom[Chancebox](2,3);
|
||||
}
|
||||
for ( int i=0; i<12; i++ )
|
||||
{
|
||||
a = Spawn((i%2)?"RedShell":"GreenShell",pos);
|
||||
a.bDROPPED = false;
|
||||
a.bNOGRAVITY = false;
|
||||
a.bDROPPED = true;
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
a.vel.xy = (cos(i*30),sin(i*30))*FRandom[Chancebox](4,5);
|
||||
}
|
||||
}
|
||||
else if ( Random[Chancebox](0,1) && SWWMUtility.ItemExists("Wallbuster") )
|
||||
{
|
||||
for ( int i=0; i<12; i++ )
|
||||
{
|
||||
let a = Spawn((i%2)?"PurpleShell":"BlueShell",pos);
|
||||
a.bDROPPED = true;
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
a.vel.xy = (cos(i*30),sin(i*30))*FRandom[Chancebox](2,3);
|
||||
}
|
||||
for ( int i=0; i<20; i++ )
|
||||
{
|
||||
let a = Spawn((i%2)?"RedShell":"GreenShell",pos);
|
||||
a.bDROPPED = true;
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
a.vel.xy = (cos(i*18),sin(i*18))*FRandom[Chancebox](4,5);
|
||||
}
|
||||
}
|
||||
else if ( Random[Chancebox](0,1) )
|
||||
{
|
||||
Class<Actor> which = Random[Chancebox](1,0)?"HealthNuggetItem":"ArmorNuggetItem";
|
||||
for ( int i=0; i<20; i++ )
|
||||
{
|
||||
let a = Spawn(which,pos);
|
||||
a.bDROPPED = false;
|
||||
a.bNOGRAVITY = false;
|
||||
a.bDROPPED = true;
|
||||
a.vel.z = FRandom[Chancebox](2,8);
|
||||
a.vel.xy = (cos(i*18),sin(i*18))*FRandom[Chancebox](1,8);
|
||||
}
|
||||
|
|
@ -1068,8 +1091,7 @@ Class Chancebox : Actor
|
|||
for ( int i=0; i<=15; i++ )
|
||||
{
|
||||
let a = Spawn((i==0)?"RefresherItem":(i%3)?"HealthNuggetItem":"ArmorNuggetItem",pos);
|
||||
a.bDROPPED = false;
|
||||
a.bNOGRAVITY = false;
|
||||
a.bDROPPED = (i!=0);
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
if ( i > 0 ) a.vel.xy = (cos(i*24),sin(i*24))*FRandom[Chancebox](1,2);
|
||||
}
|
||||
|
|
@ -1080,7 +1102,6 @@ Class Chancebox : Actor
|
|||
// pop one at random
|
||||
let a = Spawn(candidates[Random[Chancebox](0,candidates.Size()-1)],pos);
|
||||
a.bDROPPED = false;
|
||||
a.bNOGRAVITY = false;
|
||||
a.vel.z = FRandom[Chancebox](2,4);
|
||||
}
|
||||
int numpt = Random[ExploS](16,32);
|
||||
|
|
|
|||
|
|
@ -118,6 +118,10 @@ Class Demolitionist : PlayerPawn
|
|||
transient CVar tagcolor;
|
||||
int oldtagcolor;
|
||||
|
||||
transient int magtime;
|
||||
SWWMMagItem magitem;
|
||||
int magitem_cnt;
|
||||
|
||||
Default
|
||||
{
|
||||
Tag "$T_DEMOLITIONIST";
|
||||
|
|
@ -857,6 +861,75 @@ Class Demolitionist : PlayerPawn
|
|||
rings += 2;
|
||||
}
|
||||
}
|
||||
void CheckItemMagnet()
|
||||
{
|
||||
if ( magtime > 40 )
|
||||
{
|
||||
if ( !(player.cmd.buttons&BT_USE) || swwm_usetopickup )
|
||||
{
|
||||
magtime = 0;
|
||||
SWWMMagItem mi = magitem;
|
||||
while ( mi )
|
||||
{
|
||||
let next = mi.next;
|
||||
mi.Destroy();
|
||||
mi = next;
|
||||
}
|
||||
magitem_cnt = 0;
|
||||
return;
|
||||
}
|
||||
if ( !swwm_usetopickup )
|
||||
{
|
||||
let bt = BlockThingsIterator.Create(self,400);
|
||||
while ( bt.Next() )
|
||||
{
|
||||
let t = bt.Thing;
|
||||
if ( !t || !(t is 'Inventory') || !t.bSPECIAL || !t.bDROPPED || t.bINVISIBLE || Inventory(t).Owner || !SWWMUtility.SphereIntersect(t,pos,400) || !CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) )
|
||||
continue;
|
||||
let i = Inventory(t);
|
||||
Class<Inventory> cls = i.GetClass();
|
||||
if ( i is 'Ammo' ) cls = Ammo(i).GetParentAmmo();
|
||||
else if ( i is 'MaGammo' ) cls = MagAmmo(i).GetParentMagAmmo();
|
||||
let oi = FindInventory(cls);
|
||||
if ( !i.bALWAYSPICKUP && oi && (oi.Amount >= oi.MaxAmount) ) continue;
|
||||
bool addme = true;
|
||||
for ( SWWMMagItem mi=magitem; mi; mi=mi.next )
|
||||
{
|
||||
if ( mi.item != i ) continue;
|
||||
addme = false;
|
||||
break;
|
||||
}
|
||||
if ( !addme ) continue;
|
||||
let nmi = new("SWWMMagItem");
|
||||
nmi.target = self;
|
||||
nmi.item = i;
|
||||
nmi.next = magitem;
|
||||
i.A_StartSound("misc/magitem",CHAN_AMBEXTRA,CHANF_LOOP,.2,3.,.2);
|
||||
magitem = nmi;
|
||||
magitem_cnt++;
|
||||
}
|
||||
bt.Destroy();
|
||||
}
|
||||
SWWMMagItem itm = magitem;
|
||||
SWWMMagItem prev = null, next;
|
||||
while ( itm )
|
||||
{
|
||||
next = itm.next;
|
||||
if ( itm.Tick() )
|
||||
{
|
||||
if ( prev ) prev.next = next;
|
||||
else magitem = next;
|
||||
if ( itm.item ) itm.item.A_StopSound(CHAN_AMBEXTRA);
|
||||
itm.Destroy();
|
||||
magitem_cnt--;
|
||||
}
|
||||
else prev = itm;
|
||||
itm = next;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ( player.cmd.buttons&BT_USE ) magtime++;
|
||||
}
|
||||
void CheckUnderwaterAmb( bool restore = false )
|
||||
{
|
||||
Vector3 headpos = Vec3Offset(0,0,player.viewheight);
|
||||
|
|
@ -1227,6 +1300,7 @@ Class Demolitionist : PlayerPawn
|
|||
}
|
||||
CheckUnderwaterAmb();
|
||||
SenseItems();
|
||||
CheckItemMagnet();
|
||||
if ( vel.length() > mystats.topspeed ) mystats.topspeed = vel.length();
|
||||
if ( vel.length() > ((3600*GameTicRate)/32000.) )
|
||||
SWWMUtility.AchievementProgress("sanic",int((vel.length()*3600*GameTicRate)/32000.),player);
|
||||
|
|
@ -3219,6 +3293,23 @@ Class Demolitionist : PlayerPawn
|
|||
{
|
||||
// clean up attached actors
|
||||
if ( selflight ) selflight.Destroy();
|
||||
// clean up our objects
|
||||
SWWMItemSense si = itemsense;
|
||||
while ( si )
|
||||
{
|
||||
let next = si.next;
|
||||
si.Destroy();
|
||||
si = next;
|
||||
}
|
||||
itemsense_cnt = 0;
|
||||
SWWMMagItem mi = magitem;
|
||||
while ( mi )
|
||||
{
|
||||
let next = mi.next;
|
||||
mi.Destroy();
|
||||
mi = next;
|
||||
}
|
||||
magitem_cnt = 0;
|
||||
// disable death exits
|
||||
if ( player && (player.playerstate == PST_DEAD) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -223,6 +223,41 @@ Class AmmoOrbTrail : SlayerOrbTrail
|
|||
}
|
||||
}
|
||||
|
||||
// simple object for moving a dropped item towards the player
|
||||
Class SWWMMagItem play
|
||||
{
|
||||
SWWMMagItem next;
|
||||
Inventory item;
|
||||
Demolitionist target;
|
||||
|
||||
bool Tick()
|
||||
{
|
||||
if ( !target || (target.Health <= 0) ) return true;
|
||||
if ( !item || item.Owner || !item.bSPECIAL ) return true;
|
||||
Class<Inventory> cls = item.GetClass();
|
||||
if ( item is 'Ammo' ) cls = Ammo(item).GetParentAmmo();
|
||||
else if ( item is 'MaGammo' ) cls = MagAmmo(item).GetParentMagAmmo();
|
||||
let oi = target.FindInventory(cls);
|
||||
if ( !item.bALWAYSPICKUP && oi && (oi.Amount >= oi.MaxAmount) ) return true;
|
||||
Vector3 dirto = level.Vec3Diff(item.pos,target.Vec3Offset(0,0,target.height/2));
|
||||
double dist = dirto.length();
|
||||
if ( SWWMUtility.BoxIntersect(item,target) )
|
||||
{
|
||||
item.Touch(target);
|
||||
return false;
|
||||
}
|
||||
dirto /= dist;
|
||||
double fact = clamp(dist/400.,0.,1.)**.5;
|
||||
item.vel += dirto*SWWMUtility.Lerp(4.,.1,fact);
|
||||
item.A_SoundVolume(CHAN_AMBEXTRA,1.-.8*fact);
|
||||
item.A_SoundPitch(CHAN_AMBEXTRA,SWWMUtility.Lerp(1.5,.2,fact));
|
||||
let s = item.Spawn("SWWMHalfSmoke",item.pos);
|
||||
s.vel += dirto*8.*fact;
|
||||
s.alpha *= .2*fact;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Class DashTrail : Actor
|
||||
{
|
||||
Default
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue