Page 1 of 1

DXMP soccer mod

Posted: Sat May 31, 2014 4:10 am
by machina
EDIT: The soccer mod has been released. For those wondering what it turned out like:
http://www.moddb.com/mods/soccer-mod


Old post:
Me and WCCC are working on a soccer mod for DXMP. We're having a problem with the soccerball code. When the ball is about to stop bouncing it starts shaking like mad for a little while before it stops rolling. Does anyone know how to fix this? Here's the code.

Code: Select all

//=============================================================================
// Football.
//=============================================================================
class Football extends PoolBall;

//our adjustable (by mapper) z axis multipliers, velocity multipliers, and gravity multiplier
var(SoccerPhysics) float BumpMult, FrobZMult, KickPower, GravityRate;
var DeusExPlayer LastInvoker;

var float rollTimer;
var float pushTimer;
var vector pushVel;
var bool bJustPushed;

function BeginPlay()
{
 Super(DeusExDecoration).BeginPlay();
}

/*function StartRolling(vector vel)
{
	// Transfer momentum
	SetPhysics(PHYS_Rolling);
	pushVel = (Vel + (vect(0,0,1) * BumpZMult)) * BumpPower;
	pushVel.Z = 0;
	Velocity = pushVel;
	rollTimer = 2;
	bJustPushed = True;
	pushTimer = 0.5;
	//AmbientSound = Sound'UtilityCart';
}*/

//
// give us velocity in the direction of the push
//
//---------------------------------------------
//Note: this guy already compensates for mass!
//Adjust mass to adjust bump speed! ~WCCC
/*function Bump(actor Other)
{
	if (bJustPushed)
		return;

	if ((Other != None) && (Physics != PHYS_Falling))
		if (abs(Location.Z-Other.Location.Z) < (CollisionHeight+Other.CollisionHeight-1))  // no bump if landing on cart
		{
			if (Other.IsA('DeusExPlayer')) LastInvoker = DeusExPlayer(Other);
			StartRolling(0.25*Other.Velocity*Other.Mass/Mass);
		}
}*/

//========================
//We use this guy now.
//========================
function Bump(actor Other)
{
 local Vector HitNormal;

 if (Other.IsA('DeusExPlayer'))
 {
  if (!bJustHit)
  {
   LastInvoker = DeusExPlayer(Other);

   //PlaySound(sound'PoolballClack', SLOT_None);
   HitNormal = Normal(Location - Other.Location);
   Velocity = HitNormal * VSize(Other.Velocity) * BumpMult;
   Velocity.Z = 0;
   bJustHit = True;
  // Poolball(Other).bJustHit = True;
   SetTimer(0.02, False);
  // Poolball(Other).SetTimer(0.02, False);
  }
 }
}

//
// simulate less friction (wheels)
//
function Tick(float deltaTime)
{
 Super.Tick(deltaTime);

   if ((Physics == PHYS_Rolling) && (rollTimer > 0))
   {
   rollTimer -= deltaTime;

   if (PushVel.Z > 0) pushVel.Z -= deltaTime * GravityRate;
   Velocity = pushVel;

   if (pushTimer > 0)
   pushTimer -= deltaTime;
   else
   bJustPushed = False;
   }

   if ((Physics == PHYS_Falling) && VSize(Velocity) > 20)
   Velocity = Velocity - (vect(0,0,1) * deltaTime * GravityRate);

   bFixedRotationDir = True;

   if (VSize(Velocity) > 50)
    RotationRate = Rotator(Velocity / 3);
   else
    RotationRate = Rot(0,0,0);

 // make the sound pitch depend on the velocity
 if (VSize(Velocity) > 1)
 {
  //SoundPitch = Clamp(2*VSize(Velocity), 32, 64);
 }
 else
 {
  // turn off the sound when it stops
  //AmbientSound = None;
  //SoundPitch = Default.SoundPitch;
 }
}

event HitWall(vector HitNormal, actor HitWall)
{
	local float speed;

	Velocity = 0.8*((Velocity dot HitNormal) * HitNormal * (-2.0) + Velocity);   // Reflect off Wall w/damping
	speed = VSize(Velocity);
	bFixedRotationDir = True;
	//RotationRate = RotRand(False);
	if ((Physics != PHYS_Rolling) && (speed < 30) && (HitNormal.Z > 0.7))
	{
		SetPhysics(PHYS_Rolling, HitWall);
		if (Physics == PHYS_None)
			bFixedRotationDir = False;
	}
	else if (speed > 30)
	{
		PlaySound(sound'BasketballBounce', SLOT_None);
		AISendEvent('LoudNoise', EAITYPE_Audio);
	}
}

function Frob(Actor Frobber, Inventory FrobWith)
{
	if (Frobber.IsA('DeusExPlayer'))
	{
	 LastInvoker = DeusExPlayer(Frobber);

	 SetPhysics(PHYS_Falling);
	 if (DeusExPlayer(Frobber).bDuck > 0) Velocity = ((vect(1,0,0) >> LastInvoker.Rotation) + (vect(0,0,2) * FrobZMult)) * KickPower;
	 if (DeusExPlayer(Frobber).bDuck <= 0) Velocity = ((vect(1,0,0) >> LastInvoker.Rotation) + (vect(0,0,1) * FrobZMult)) * KickPower;
	}
}

defaultproperties
{
     bInvincible=True
     ItemName="Football"
     Mesh=LodMesh'Soccermod.FootballMesh'
     CollisionRadius=32.000000
     CollisionHeight=32.000000
     bBounce=True
     Mass=0.000000
     Buoyancy=2.000000

     FrobZMult=0.500000
     BumpMult=4.000000
     KickPower=750.000000
     GravityRate=166.666666
     bPushable=False
     DrawScale=1.500000
     BCanTeleport=True
     RemoteRole=ROLE_SimulatedProxy
     Physics=PHYS_Rolling
}
If you want to know more don't hesitate to ask. I could give you a list of the things we've tried so far or what the ball is supposed to do but I didn't want to start with a long post, considering the code is already long.

Re: Need help coding physics of a soccerball

Posted: Sat May 31, 2014 7:45 am
by Hanfling
Maybe you should should use Basketball as a starting point not poolball. Using a simulated proxy probably requires additional simulation code. You should also put netupdatefrequency / netpriority as high as the players.

/edit:
Also you should check DeusExDecorations' Tick(). Maybe this line of code is relevant for you:

Code: Select all

   if ((Level.Netmode != NM_Standalone) && (VSize(Velocity) > 0) && (VSize(Velocity) < 5))
   {
      Velocity *= 0;
   }

Re: Need help coding physics of a soccerball

Posted: Wed Jun 04, 2014 7:45 am
by machina
Hey, thanks for the help! We've used some of your suggestions in the new code, unfortunately we've run into new problems now. WCCC is looking into it atm, if he can't figure it out I'll post again. For now we're only testing in SP btw, it's not a MP issue.

Re: Need help coding physics of a soccerball

Posted: Thu Jan 15, 2015 11:39 pm
by machina
Well, this thing has been released by now. For those wondering what it turned out like:
http://www.moddb.com/mods/soccer-mod