// Inventory stuff Mixin Class SWWMAutoUseFix { override bool HandlePickup( Inventory item ) { if ( GetClass() == item.GetClass() ) { if ( deathmatch && !bALWAYSPICKUP ) { // don't allow picking up any more than just one copy in DM unless it can be auto-used if ( Use(true) ) Amount--; else return true; } else if ( Use(true) ) Amount--; // sell excess if there's a price if ( !deathmatch && bALWAYSPICKUP && (Amount+item.Amount > MaxAmount) && (Stamina != 0) ) { if ( Owner.player ) { int sellprice = abs(Stamina)/2; SWWMCredits.Give(Owner.player,sellprice); if ( Owner.player == players[consoleplayer] ) { SWWMScoreObj.SpawnAtActorBunch(sellprice,Owner); Console.Printf(StringTable.Localize(SWWMUtility.SellFemaleItem(item)?"$SWWM_SELLEXTRA_FEM":"$SWWM_SELLEXTRA"),GetTag(),sellprice); } else Console.Printf(StringTable.Localize(SWWMUtility.SellFemaleItem(item)?"$SWWM_SELLEXTRAREM_FEM":"$SWWM_SELLEXTRAREM"),Owner.player.GetUserName(),GetTag(),sellprice); } item.bPickupGood = true; } } return Super.HandlePickup(item); } override bool TryPickup( Actor &toucher ) { if ( !deathmatch ) return Super.TryPickup(toucher); // pretend to have a max amount of 0 so we can only be picked up if we can be used int oldmax = MaxAmount; MaxAmount = 0; bool ret = Super.TryPickup(toucher); MaxAmount = oldmax; return ret; } } Class CrossLineFinder : LineTracer { Array clines; Array csides; override ETraceStatus TraceCallback() { if ( (Results.HitType == TRACE_HitWall) && (Results.HitLine.activation&SPAC_Cross) ) { clines.Push(Results.HitLine); csides.Push(Results.Side); } return TRACE_Skip; } } Mixin Class SWWMUseToPickup { bool bUsePickup; // allow pickup by use override bool Used( Actor user ) { // can't pick up if ( !bSPECIAL ) return false; // no use through melee if ( (user.player.ReadyWeapon is 'SWWMWeapon') && SWWMWeapon(user.player.ReadyWeapon).wallponch ) return false; Vector3 itempos = Vec3Offset(0,0,Height/2), userpos = user.Vec2OffsetZ(0,0,user.player.viewz); // test vertical range Vector3 diff = level.Vec3Diff(user.Vec3Offset(0,0,user.Height/2),Vec3Offset(0,0,Height/2)); double rang = user.player?PlayerPawn(user.player.mo).UseRange:(user.Height/2); if ( abs(diff.z) > rang ) return false; bUsePickup = true; Touch(user); bUsePickup = false; // we got picked up if ( bDestroyed || Owner || !bSPECIAL ) { Vector3 tracedir = level.Vec3Diff(userpos,itempos); double dist = tracedir.length(); tracedir /= dist; let cf = new('CrossLineFinder'); cf.Trace(userpos,level.PointInSector(userpos.xy),tracedir,dist,0,ignoreallactors:true); // trigger all player cross lines found between user and item for ( int i=0; i 0 ) { freezetics--; return; } if ( isFrozen() ) return; double str = 1.-special2/double(special1); int freq = int(clamp(30*(1.-str),3,30)); if ( (level.maptime+args[3])%freq ) return; if ( !flare.texture ) { flare.color1 = Color(args[0]*85,args[1]*85,args[2]*85); flare.texture = TexMan.CheckForTexture("graphics/Particles/xflare.png"); flare.style = STYLE_AddShaded; flare.flags = SPF_FULLBRIGHT; flare.fadestep = -1; } flare.pos = pos+(0,0,16); int numpt = int(Random[ExploS](0,10)*str); for ( int i=0; i