RuneStorm
http://www.runestorm.com/forums/

Why no sir, I can't code! Why do you ask?
http://www.runestorm.com/forums/viewtopic.php?f=69&t=76622
Page 1 of 1

Author:  Herr General [ Fri Jan 14, 2011 6:14 pm ]
Post subject:  Why no sir, I can't code! Why do you ask?

Well, after a hiatus of moderate length I decided to tweak my airstrike project. I hate to be one of these people, but I can't code at all and I basically need help.

What I want to do is basically offset the bomb dropped from the autobomber. As it is, when the bomb is dropped with momentum added (as i would like) the bomb misses the target, since it is released directly over it. I need for the bomb to be dropped earlier so it falls in an awesome ballistic path directly on target, but I have no idea how.

Secondly, I would like an airdropped cluster bomb mine. The mine code is done, but it doesn't recognize players and explode since it is spawned by the clusterbomb.

And while I'm at it, I'll be ridiculously ambitious. Is a sensor fused weapon (CBU-97) possible? Look it up if you need info.

Author:  Sgt. Kelly [ Fri Jan 14, 2011 10:28 pm ]
Post subject:  Re: Why no sir, I can't code! Why do you ask?

I'll probably be able to help you if I can see the code in question. You could potentially trick the bomber into thinking it's closer to its target than it is. I would suggest editing the code that triggers the projectile to be spawned.

Author:  Herr General [ Fri Jan 14, 2011 10:50 pm ]
Post subject:  Re: Why no sir, I can't code! Why do you ask?

Code:
class CBU100PainterFire extends PainterFire;

var class<CBU100AutoBomberReal> BomberClass;
var float MinZDist, MaxZDist;

function bool SpawnBomber(rotator BombDirection)
{
   local vector BomberStart, BomberStart2, BombTargetCenter, HitNormal, Extent, Temp;
   local CBU100AutoBomberReal Bomber;

   BombDirection.Pitch = 0;
   Extent = BomberClass.default.CollisionRadius * vect(1,1,0);
   Extent.Z = BomberClass.default.CollisionHeight;
   if (Weapon.Trace(BombTargetCenter, HitNormal, MarkLocation + MaxZDist * vect(0,0,1), MarkLocation + Extent.Z * vect(0,0,2), false, Extent) == None)
      BombTargetCenter = MarkLocation + MaxZDist * vect(0,0,1);
   BombTargetCenter.Z -= BomberClass.default.CollisionHeight;
   if (VSize(BombTargetCenter - MarkLocation) < MinZDist)
      return false;

   if (Weapon.Trace(BomberStart, HitNormal, BombTargetCenter - vector(BombDirection) * 100000, BombTargetCenter, false, Extent) == None)
      BomberStart = BombTargetCenter - vector(BombDirection) * 100000;
   if (Weapon.Trace(BomberStart2, HitNormal, BombTargetCenter + vector(BombDirection) * 100000, BombTargetCenter, false, Extent) == None)
      BomberStart2 = BombTargetCenter + vector(BombDirection) * 100000;
   if (VSize(BomberStart - BombTargetCenter) < VSize(BomberStart2 - BombTargetCenter))
   {
      Temp = BomberStart;
      BomberStart = BomberStart2;
      BomberStart2 = Temp;
   }

   Bomber = Weapon.spawn(BomberClass, Instigator,, BomberStart, rotator(BombTargetCenter - BomberStart));
   if (Bomber == None)
      return false;
   Bomber.Bomb(BombTargetCenter);
   return true;
}

state Paint
{
    function BeginState()
    {
        IonCannon = None;

        if (Weapon.Role == ROLE_Authority)
        {
            if (Beam == None)
            {
                Beam = Weapon.Spawn(class'PainterBeamEffect', Instigator);
                Beam.bOnlyRelevantToOwner = true;
                Beam.EffectOffset = vect(-25, 35, 14);
            }
            bInitialMark = true;
            bValidMark = false;
            MarkTime = Level.TimeSeconds;
            SetTimer(0.25, true);
        }

        ClientPlayForceFeedback(TAGFireForce);
    }

    function ModeTick(float dt)
    {
        local Vector StartTrace, EndTrace, X,Y,Z;
        local Vector HitLocation, HitNormal;
        local Actor Other;
        local Rotator Aim;

        if (!bIsFiring)
        {
            StopFiring();
        }

        Weapon.GetViewAxes(X,Y,Z);

        // the to-hit trace always starts right in front of the eye
        StartTrace = Instigator.Location + Instigator.EyePosition() + X*Instigator.CollisionRadius;

   Aim = AdjustAim(StartTrace, AimError);
        X = Vector(Aim);
        EndTrace = StartTrace + TraceRange * X;

        Other = Weapon.Trace(HitLocation, HitNormal, EndTrace, StartTrace, false);

        if (Other != None && Other != Instigator)
        {
            if ( bDoHit )
            {
                bValidMark = false;

                if (Other.bWorldGeometry)
                {
                    if (VSize(HitLocation - MarkLocation) < 50.0)
                    {
         Instigator.MakeNoise(3.0);
                        if (Level.TimeSeconds - MarkTime > 0.3)
                        {
             bValidMark = CBU100Painter(Weapon).CanBomb(HitLocation, BomberClass.default.CollisionRadius);

             if (bValidMark)
             {
                                if (Level.TimeSeconds - MarkTime > PaintDuration && SpawnBomber(Instigator.Rotation))
                                {
                Instigator.PendingWeapon = None;
                                    Painter(Weapon).ReallyConsumeAmmo(ThisModeNum, 1);
                                    Instigator.Controller.ClientSwitchToBestWeapon();

                                    if (Beam != None)
                                        Beam.SetTargetState(PTS_Aquired);

                                    StopForceFeedback(TAGMarkForce);
                                    ClientPlayForceFeedback(TAGAquiredForce);

                                    StopFiring();
                                }
                                else
                                {
                                    if (!bMarkStarted)
                                    {
               bMarkStarted = true;
               ClientPlayForceFeedback(TAGMarkForce);
                }
                                }
                            }
                            else
                            {
                                MarkTime = Level.TimeSeconds;
                                bMarkStarted = false;
                                if ( Bot(Instigator.Controller) != None )
                                {
               Instigator.Controller.Focus = Instigator.Controller.Enemy;
               MarkLocation = Bot(Instigator.Controller).Enemy.Location - Bot(Instigator.Controller).Enemy.CollisionHeight * vect(0,0,2);
            }
                            }
                        }
                    }
                    else
                    {
         bAlreadyMarked = true;
                        MarkTime = Level.TimeSeconds;
                        MarkLocation = HitLocation;
                        bValidMark = false;
                        bMarkStarted = false;
                    }
                }
                else
                {
                    MarkTime = Level.TimeSeconds;
                    bValidMark = false;
                    bMarkStarted = false;
                }
                bDoHit = false;
            }

            EndEffect = HitLocation;
        }
        else
        {
            EndEffect = EndTrace;
        }

        Painter(Weapon).EndEffect = EndEffect;

        if (Beam != None)
        {
            Beam.EndEffect = EndEffect;
            if (bValidMark)
                Beam.SetTargetState(PTS_Marked);
            else
                Beam.SetTargetState(PTS_Aiming);
        }
    }
}

defaultproperties
{
     BomberClass=Class'Airstrikes.CBU100AutoBomberReal'
     MinZDist=5000.000000
     MaxZDist=7500.000000
     TraceRange=65000.000000
}

Thats the basic target painter fire code, which hasn't really been changed.
This is the bomber code which is where the heart of the problem lies (I think). The "offset" value in the defaultproperties offsets it by world coordinates- which doesn't work when using the autobomber.
Code:
class CBU100AutoBomberReal extends ONSAutoBomber;


var() Vector BombOffset;/*
var vector BombTargetCenter;
var float Speed, MinSpeed, BombRange;
var class<Projectile> BombClass;
var int Health;
var byte Team;
var Controller DelayedDamageInstigatorController;
var bool bShotDown;

// Damage attributes.
var float Damage;
var float DamageRadius;
var float MomentumTransfer;
var class<DamageType> MyDamageType;

// camera shakes //
var() vector ShakeRotMag;           // how far to rot view
var() vector ShakeRotRate;          // how fast to rot view
var() float  ShakeRotTime;          // how much time to rot the instigator's view
var() vector ShakeOffsetMag;        // max view offset vertically
var() vector ShakeOffsetRate;       // how fast to offset view vertically
var() float  ShakeOffsetTime;       // how much time to offset view

var class<Emitter> DyingEffectClass;
var Emitter DyingEffect;

replication
{
   reliable if (bNetInitial && Role == ROLE_Authority)
      BombTargetCenter;
   reliable if (bNetDirty && Role == ROLE_Authority)
      bShotDown;
}

function Touch(Actor Other)
{
   if (Vehicle(Other) != None)
   {
      Vehicle(Other).TakeDamage(Vehicle(Other).Health, None, Other.Location, vect(0,0,0), class'DamTypeONSVehicle');
      TakeDamage(Health, Pawn(Other), Location, vect(0,0,0), class'DamTypeONSVehicle');
   }
}

function Bump(Actor Other)
{
   Touch(Other);
}

function SetDelayedDamageInstigatorController(Controller C)
{
   DelayedDamageInstigatorController = C;
}

function TakeDamage(int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum, class<DamageType> DamageType)
{
   local Controller InstigatorController;

   if (EventInstigator != None)
      InstigatorController = EventInstigator.Controller;
   else
      InstigatorController = DelayedDamageInstigatorController;

   if (InstigatorController == None || InstigatorController.GetTeamNum() == Team)
      return;

   Health -= Damage;
   if (Health <= 0)
      GotoState('ShotDown');
}

simulated function PostBeginPlay()
{
   Super.PostBeginPlay();

   if (Role == ROLE_Authority && Instigator != None)
      Team = Instigator.GetTeamNum();

   if (Level.NetMode != NM_DedicatedServer)
   {
      spawn(class'ONSAutoBomberWarpEffect',,,, Rotation + rot(0,16384,0));
      Level.GetLocalPlayerController().PlayStatusAnnouncement('Incoming_air', 0, true);
   }
}

function Bomb(vector Target)
{
   BombTargetCenter = Target;
   SetRotation(rotator(Target - Location));
   Velocity = vector(Rotation) * ((VSize(Location - BombTargetCenter) - BombRange) / 100000 * Speed + MinSpeed);
   SetTimer(0.33, true);
}

simulated event HitWall(vector HitNormal, Actor HitWall)
{
   if (Level.NetMode != NM_DedicatedServer)
      spawn(class'ONSAutoBomberWarpEffect',,,, Rotation + rot(0,16384,0));
   Destroy();
}

*/function Timer()
{
   local Controller C;
   local Projectile myBomb;
   local Vector NewVelocity,X,Y,Z;

   GetViewAxes(X,Y,Z);
   NewVelocity = 0.5*Velocity - frand()*Y*BombOffset.Y;
   
   if (FRand() < 0.5)
   {
      //high skill enemies who don't have anything else to shoot at will try to shoot bomber down
      for (C = Level.ControllerList; C != None; C = C.NextController)
         if ( AIController(C) != None && C.Pawn != None && C.GetTeamNum() != Team && AIController(C).Skill >= 5.0
              && !C.Pawn.IsFiring() && (C.Enemy == None || !C.LineOfSightTo(C.Enemy)) && C.Pawn.CanAttack(self) )
         {
            C.Focus = self;
            C.FireWeaponAt(self);
         }
   }

   if (VSize(Location - BombTargetCenter) < BombRange)
   {
      //drop a bomb
      myBomb=spawn(BombClass,,, Location - ((CollisionHeight + BombClass.default.CollisionHeight) * vect(0,0,2)), rotator(vect(0,0,-1)));
      CBU100BaseShell(myBomb).Velocity+=NewVelocity;//0.5*Velocity;
      Velocity = Normal(Velocity) * MinSpeed;
      Acceleration = vect(0,0,0);
   }
}

/*
simulated function Tick(float deltaTime)
{
   local float TargetDist;

   //start out really fast, slow down when near target
   TargetDist = VSize(Location - BombTargetCenter);
   if (TargetDist > BombRange)
      Velocity = vector(Rotation) * ((TargetDist - BombRange) / 100000 * Speed + MinSpeed);
}

simulated function PostNetReceive()
{
   if (bShotDown)
      GotoState('ShotDown');
}

simulated function Destroyed()
{
   if (DyingEffect != None)
      DyingEffect.Kill();
}

function bool IsStationary()
{
   return false;
}

state ShotDown
{
   simulated function BeginState()
   {
      bShotDown = true;
      bNetNotify = false;
      SetPhysics(PHYS_Falling);
      if (Level.NetMode != NM_DedicatedServer)
      {
         DyingEffect = spawn(DyingEffectClass, self);
         if (DyingEffect != None)
            DyingEffect.SetBase(self);
      }
   }

   simulated function HitWall(vector HitNormal, Actor HitWall)
   {
      Landed(HitNormal);
   }

   simulated function Landed(vector HitNormal)
   {
      GotoState('BlowingUp');
   }

   simulated function Tick(float deltaTime)
   {
      SetRotation(rotator(Velocity));
   }

   function Timer() {}
   function TakeDamage(int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum, class<DamageType> DamageType) {}
}

state BlowingUp extends ShotDown
{
   simulated function Landed(vector HitNormal) {}

   simulated function BeginState()
   {
      local PlayerController PC;
      local float Dist, Scale;

      InitialState = 'BlowingUp';
      if (Level.NetMode != NM_DedicatedServer)
      {
         Spawn(class'RedeemerExplosion',,, Location - 100 * Normal(Velocity), Rot(0,16384,0));
         Spawn(class'IonCore',,, Location, Rotation);
      }
      MakeNoise(1.0);
      bHidden = true;
      SetPhysics(PHYS_None);
      SetCollision(false,false,false);

      //shakeview
      PC = Level.GetLocalPlayerController();
      if (PC != None && PC.ViewTarget != None)
      {
         Dist = VSize(Location - PC.ViewTarget.Location);
         if (Dist < DamageRadius * 2.0)
         {
            if (Dist < DamageRadius)
               Scale = 1.0;
            else
               Scale = (DamageRadius*2.0 - Dist) / (DamageRadius);
            PC.ShakeView(ShakeRotMag*Scale, ShakeRotRate, ShakeRotTime, ShakeOffsetMag*Scale, ShakeOffsetRate, ShakeOffsetTime);
         }
      }
   }

Begin:
    PlaySound(sound'WeaponSounds.redeemer_explosionsound');
    HurtRadius(Damage, DamageRadius*0.125, MyDamageType, MomentumTransfer, Location);
    Sleep(0.5);
    HurtRadius(Damage, DamageRadius*0.300, MyDamageType, MomentumTransfer, Location);
    Sleep(0.2);
    HurtRadius(Damage, DamageRadius*0.475, MyDamageType, MomentumTransfer, Location);
    Sleep(0.2);
    HurtRadius(Damage, DamageRadius*0.650, MyDamageType, MomentumTransfer, Location);
    Sleep(0.2);
    HurtRadius(Damage, DamageRadius*0.825, MyDamageType, MomentumTransfer, Location);
    Sleep(0.2);
    HurtRadius(Damage, DamageRadius*1.000, MyDamageType, MomentumTransfer, Location);
    Destroy();
}
*/

simulated function GetViewAxes( out vector xaxis, out vector yaxis, out vector zaxis )
{
    //if ( Instigator.Controller == None )
      //  GetAxes( Instigator.Rotation, xaxis, yaxis, zaxis );
    //else
        GetAxes( Rotation, xaxis, yaxis, zaxis );
}

defaultproperties
{
     BombOffset=(X=-2000.000000)
     BombRange=1500.000000
     BombClass=Class'Airstrikes.CBU100BaseShell'
}

Author:  mzoltan22 [ Fri Jan 21, 2011 12:56 pm ]
Post subject:  Re: Why no sir, I can't code! Why do you ask?

i don't know if you have solved it already, But here is a way:

first you compute the horizontal distance from the target inside of wich you can drop the bomb (actually, the square of it), (if im right Z is for height)
float Hdist

Hdist =speedh*speedh*2*(bomberpos.Z - bombtarget.Z)/g; where g is the gravitational acceleration and i assume that on bomb spawn bomb will have a horisontal speed (so rotator.Z or however it is implemented should be 0) and 0 vertical speed in the first second.

then you just always in every tick check if ((bomtarget.x-bomberpos.x)*(bomtarget.x-bomberpos.x)+(bombtarget.y-bomberpos.y)*(bombtarget.y-bomberpos.y) <=Hdist)
then if condition met, you drop the bomb. //

of course you can always rotate the bomb depending on the ratio of its horizontal and vertical speed. if im right x and y are horizontal coordinates, and Z is vertical coordinate.

Could you send me the whole packages, so i could see how could that be implemented? (just in case)

Author:  mzoltan22 [ Tue Feb 01, 2011 12:56 pm ]
Post subject:  Re: Why no sir, I can't code! Why do you ask?

sorry for bump,

check your PM's.

Author:  Herr General [ Wed Feb 02, 2011 10:36 am ]
Post subject:  Re: Why no sir, I can't code! Why do you ask?

I'm checking it out now. Thanks a lot!

Author:  mzoltan22 [ Thu Feb 03, 2011 3:06 am ]
Post subject:  Re: Why no sir, I can't code! Why do you ask?

let me know if it worked; also if you managed to include the Dt correctly into rotmult, or if there is anything else you noticed.

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/