Download Public Code Snippets

PureWhoopAss

Legions Developer
shotty isn't op if you balance things out... say give the bullets less lifetime so they die at maybe 30 meters... and give each round less damage... problem solved.
 
Not a bug, just hasn't been coded. Open up the deathMessages.cs file and append it to be whatever you want.

"x was pulped by y"
"x needs to get off y's lawn"
"y defended their property against x"

whatever you like.
how about this, I think it should work
Code:
$DamageType::ShotgunProjectile= 24;
addDamageType($DamageType::ShotgunProjectile, "Shotgun");
addDeathMessage(Kill, $DamageType::ShotgunProjectile, '~g%1 was pulped by %2');
and you need to change in the code above, this
Code:
damageType = $DamageType::ChaingunProjectile;
to this
Code:
damageType = $DamageType::ShotgunProjectile;
 

Royalty

The Aussie
We had six people in the Aussie server last night. Was pretty awesome. We all agree though, that some American players are truly very bad for their ping...
Expecting Americans to pop in occasionally.
Even Kiwi's ping under 70 in my server!

The one thing we all agreed on though is that public test really needs tweaked as it is frigging impossible to combo... :(
 

Volt Cruelerz

Legions Developer
here's a little something I just came up with. It's an incredibly flexible energy modification function that you just paste in your server/game/player.cs file and call from Player::damage. It allows you to...

  • Determine energy modified
  • Regen/Degredate energy
  • Allow excess energy regen to heal health
  • control the conversion rate of energy to health
  • overcharge the energy (untested, will likely crash, but hey :p )
  • cause an energy DoT
  • rate at which energy is reduced
  • number of times the energy is reduced

Code:
function modEnergy(%this, %amount, %carryToHealth,%conversion,%overCharge,%canRecur,%frequency,%count)
{
    //int %this.getEnergyLevel();
    //void %this.setEenergyLevel(%amount);
    //int %this.getDataBlock().maxEnergy;
   
    //echo("MODDING ENERGY NOW");
   
    if(%carryToHealth != true){%carryToHealth=false;}
    if(%overCharge != true){%overCharge=false;}   
    if(%conversion $= ""){%conversion=0;}
    if(%canRecur != true){
        %canRecur=false;
        %frequency=0;
        %count=0;
    }
   
    %e=%this.getEnergyLevel();
    %em=%this.getDataBlock().maxEnergy;
   
    //echo("Energy: " @ %e);
    //echo("Max Energy: " @ %em);
   
    if(%amount>0){//regen energy
        //echo("REGEN ENERGY");
        if(%overcharge){//if can overcharge
            %this.setEnergyLevel(%e+%amount);
        }else{//if can't overcharge
            %total=%amount+%e;
            %emp=%em+1;
            if(%total<%emp){//if less than max energy
                %this.setEnergyLevel(%e+%amount);
            }else{
                if(%carryToHealth){
                    %this.setEnergyLevel(%em);//max energy
                    %regenVal=%em-%e;//find the regen difference
                    %healValue=-1*(%amount-%regenVal);//find the rough dif for health regen
                    %this.applyDamage(%conversion*%healValue);//convert
                }
            }
        }
    }else{//drain energy
        //echo("DRAIN ENERGY");
        if(%amount+%e<=0){
            %this.setEnergyLevel(0);
        }else{
            %this.setEnergyLevel(%amount+%e);
            echo("Remaining Energy: " @ %this.getEnergyLevel());
        }
    }
   
    if(%canRecur){
        schedule(%frequency,98,"modEnergy",%this,%amount,%carryToHealth,%conversion,%overCharge,%canRecur,%frequency,%count);
    }
}
 

Volt Cruelerz

Legions Developer
Here's a shocklance. It will one-shot lights and mediums at very short range, but won't beyond that.

Download

Code:
//-----------------------------------------------------------------------------
// Fallen Empire: Legions
// Copyright (C) GarageGames.com, Inc.
// Written by Volt Cruelerz
// Based upon Tribes Shocklance
//-----------------------------------------------------------------------------
 
datablock BeamProjectileData(ShocklanceProjectile)
{
  passThroughPlayers = true;
  processImmediate = true;
  // damage
  beamCount = 2;
  beamRadius[0] = 0.4;
  beamMaterial[0] = "Shockblade0";
  beamRepeatLength[0] = 16;
  beamStartFadeTime[0] = 0.1;
  beamEndFadeTime[0] = 1.0;
  beamEndFadeFactor[0] = 1.0;
 
  beamRadius[1] = 0.4;
  beamMaterial[1] = "Shockblade1";
  beamRepeatLength[1] = 64;
  beamStartFadeTime[1] = 0.1;
  beamEndFadeTime[1] = 1.0;
  beamEndFadeFactor[1] = 0.0;
 
  initialFadeDistance = 15.0;
     
  initialDamage = 0;
  directDamage = 0;
  radiusDamage = 0;
  damageRadius = 0;
  areaImpulse = 0;
  damageType = $DamageType::SniperBeam;
  explosionDamageType = $DamageType::SniperExplosion;
 
  lifetime = 1300;
  isBallistic = false;
  gravityMod = 0.0;
 
  deleteOnExplode = false;
  isAttached = false;
};
 
datablock BeamProjectileData(ShocklanceDamageProjectile)
{
  passThroughPlayers = true;
 
  // damage
  beamCount = 1;
  beamRadius[0] = 0.0;
  beamMaterial[0] = "Shockblade0";
  beamRepeatLength[0] = 16;
  beamStartFadeTime[0] = 0.0;
  beamEndFadeTime[0] = 1.0;
  beamEndFadeFactor[0] = 0.0;
 
  explosionMidair = "SniperBeamExplosion";
 
  minDamage = 40;
  maxDamage = 105;
  directDamage = 0;
  radiusDamage = 5;
  damageRadius = 4;
  areaImpulse = 3500;
  damageType = $DamageType::ShocklanceHit;
  explosionDamageType = $DamageType::SniperExplosion;
 
  lifetime = 15;
 
  deleteOnExplode = false;
  isAttached = false;
};
 
new ScriptObject(ShocklanceIcon)
{
  class = IconInfo;
  name = Shocklance;
 
  containerIcon = "client/gui/images/hud/weaponIcons/sniperRifle";
  ammoIcon = "client/gui/images/hud/weaponIcons/sniperRifleAmmo";
};
 
new ScriptObject(ShocklanceReticle)
{
  class = ReticleInfo;
  name = Shocklance;
 
  image = "client/gui/images/hud/reticles/SniperReticle_NoZoom";
  frames = "4 1";
 
  normalFrame = 0;
};
 
datablock ItemData(Shocklance)
{
  class = Weapon;
  image = ShocklanceImage;
 
  iconInfo = ShocklanceIcon;
  reticleInfo = ShocklanceReticle;
 
  longName = "Shocklance";
  shortName = "SL";
};
 
datablock ItemData(ShocklanceAmmo)
{
  class = Ammo;
  item = Shocklance;
};
 
// Shocklance gun image
datablock ShapeBaseImageData(ShocklanceImage)
{
  class = WeaponImage;
  item = Shocklance;
  ammo = ShocklanceAmmo;
  aimProjectile = ShocklanceDamageProjectile;
  projectile = ShocklanceProjectile;
  projectileType = BeamProjectile;
  optimalRange = 15;
  maxRange = 120; // maximum range in meters
 
  shapeFile = "legions/data/shapes/Weapons/sniperrifle/sniperrifle.dts";
  emap = true;
 
  reticleImageFile[0] = "client/gui/images/hud/reticles/SniperReticle_NoZoom";
  reticleImageFile[1] = "client/gui/images/hud/reticles/SniperReticle_FullZoom";
  reticleImageFile[2] = "client/gui/images/hud/reticles/SniperReticle_FullZoom";
 
  reticleStartScale[0] = "1 1";
  reticleStartScale[1] = "0.3 0.3";
  reticleStartScale[2] = "0.5 0.5";
 
  reticleEndScale[0] = "1 1";
  reticleEndScale[1] = "0.5 0.5";
  reticleEndScale[2] = "1 1";
 
  reticleScaleTime[0] = 0;
  reticleScaleTime[1] = 0.25;
  reticleScaleTime[2] = 0.25;
 
  reticleStartAlpha[0] = 255;
  reticleStartAlpha[1] = 50;
  reticleStartAlpha[2] = 255;
 
  reticleEndAlpha[0] = 255;
  reticleEndAlpha[1] = 255;
  reticleEndAlpha[2] = 255;
 
  reticleFadeTime[0] = 0;
  reticleFadeTime[1] = 0.3;
  reticleFadeTime[2] = 0.3;
 
  reticleFrameCount = "4 1";
  cursorTexture = "client/gui/images/hud/targetingCursor";
 
  mountPoint = $WeaponSlot;
  firstPerson = false;
  eyeOffset = "0.7 0.3 -0.4";
  correctMuzzleVector = true;
  aimBeam = 0;
  shotBeam = 1;
   
  // Check ammo, do appropriate activate animation
  stateName[0] = "PreActivate";
  stateTransitionOnAmmo[0] = "Activate";
  stateSequence[0] = "activate";
  stateTransitionOnNoAmmo[0] = "ActivateNoAmmo";
 
  stateName[1] = "Activate";
  stateSequence[1] = "activate";
  stateTransitionOnTimeout[1] = "Ready";
  stateTimeoutValue[1] = 0.2;
 
  stateName[2] = "ActivateNoAmmo";
  stateSequence[2] = "activatenoammo";
  stateTransitionOnTimeout[2] = "NoAmmo";
  stateTimeoutValue[2] = 0.5;
 
  stateName[3] = "Ready";
  stateScript[3] = "onReady";
  stateWaitForTimeout[3] = false;
  stateSequence[3] = "ready";
  stateTransitionOnTriggerDown[3] = "Fire";
  stateTransitionOnNoAmmo[3] = "NoAmmo";
     
  stateName[4] = "Fire";
  stateTimeoutValue[4] = 0.1; //was 0.4;
  stateTransitionOnTimeout[4] = "CheckAmmo";
  stateSequence[4] = "fire";
  stateFire[4] = true;
  stateAllowImageChange[4] = false;
  stateFullSound[4] = LaserRifleFireSound;
  stateScript[4] = "onFire";
 
  stateName[5] = "CheckAmmo";
  stateTransitionOnAmmo[5] = "Reload";
  stateTransitionOnNoAmmo[5] = "NoAmmoStart";
  stateAllowImageChange[5] = false;
 
  stateName[6] = "Reload";
  stateScript[6] = "onReload";
  stateSequence[6] = "cooldown";
  stateSequenceStartPosition[6] = 0.0;
  stateSequenceEndPosition[6] = 1.7;
  stateTransitionOnTimeout[6] = "Reloaded";
  stateAllowImageChange[6] = false;
  stateTimeoutValue[6] = 1.8; // 1.75
 
  stateName[7] = "Reloaded";
  stateScript[7] = "onReloaded";
  stateSequence[7] = "cooldown";
  stateSequenceStartPosition[7] = 0.7;
  stateSequenceEndPosition[7] = 1.0;
  stateTransitionOnTimeout[7] = "Ready";
  stateTimeoutValue[7] = 0.5;
     
  stateName[8] = "NoAmmoStart";
  stateSequence[8] = "cooldown";
  stateTransitionOnTimeout[8] = "NoAmmo";
  stateTimeoutValue[8] = 2.0;
  stateWaitForTimeout[8] = false;
  stateTransitionOnTriggerDown[8] = "DryFire";
  stateTransitionOnAmmo[8] = "Reload";
 
  stateName[9] = "NoAmmo";
  // stateSequence[9] = "cooldown";
  stateTransitionOnTriggerDown[9] = "DryFire";
  stateTransitionOnAmmo[9] = "Reload";
 
  stateName[10] = "DryFire";
  stateTimeoutValue[10] = 0.5;
  stateWaitForTimeout[10] = true;
  stateTransitionOnTimeout[10] = "CheckAmmo";
  stateSequence[10] = "fire";
  stateFullSound[10] = LaserRifleChargedSound;
};
 
function ShocklanceImage::onReady(%this, %obj, %slot)
{
}
 
function ShocklanceImage::onReload(%this, %obj, %slot)
{
}
 
function ShocklanceImage::onReady(%this, %obj, %slot)
{
}
 
function ShocklanceImage::onFire(%this, %obj, %slot)
{
  %obj.decInventory(%this.ammo, 1);
  %pct = %obj.getEnergyLevel() / %obj.getDataBlock().maxEnergy;
  %obj.setEnergyLevel(0);
 
  return %this.createBeam(%obj, %slot, %pct);
}
 
function ShocklanceImage::onReloaded(%this, %obj, %slot)
{
}
 
function ShocklanceImage::createBeam(%this, %obj, %slot, %pct)
{
  // Create the projectile object
  %p = new (%this.projectileType)() {
      dataBlock        = %this.aimProjectile;
      initialVelocity  = "0 0 0";
      initialPosition  = %obj.getMuzzlePoint(%slot);
      damageFactor    = %pct;
      energyPercentage = %pct;
      sourceObject    = %obj;
      sourcePlayer    = %obj.client;
      sourceSlot      = %slot;
      client          = %obj.client;
      optimalRange    = %this.optimalRange;
      range            = %this.maxRange;
      stats            = %obj.stats.getWeaponStats(%this.aimProjectile.damageType);
  };
     
  %obj.laserShot[%this.aimBeam] = %p;
           
  MissionCleanup.add(%p);
 
  // Create the projectile object
  %p = new (%this.projectileType)() {
      dataBlock        = %this.projectile;
      initialVelocity  = "0 0 0";
      initialPosition  = %obj.getMuzzlePoint(%slot);
      sourceObject    = %obj;
      sourcePlayer    = %obj.client;
      sourceSlot      = %slot;
      client          = %obj.client;
      range            = %this.maxRange;
  };
 
  %obj.laserShot[%this.shotBeam] = %p;
 
  MissionCleanup.add(%p);
  return %p;
}
 
function ShocklanceDamageProjectile::onCollision(%this, %obj, %col, %pos, %normal, %velocity)
{
  %damageAmount = ((%this.maxDamage - %this.minDamage) * %obj.damageFactor) + %this.minDamage;
 
  if ((%damageAmount > 0.0) && (%col.getType() & $TypeMasks::PlayerObjectType))
  {
      if(!isObject(%obj.hitSet))
      {
        %obj.hitSet = new SimSet(){};
        %obj.hitSet.schedule(%this.lifetime * 2, delete);
      }
 
    %distance = VectorDist(%obj.initialPosition, %pos);
    if(%distance > 0)
        %distanceScale = mClamp(1.0 - ((%distance - %obj.optimalRange) / (%obj.range - (%distance - %obj.optimalRange))), 0, 1);
    else
        %distanceScale = 1.0;
 
    if(!%obj.hitSet.isMember(%col))
    {
        %col.damage(%obj.sourcePlayer, %obj.position, %damageAmount * %distanceScale, %this.damageType, %obj.stats);
        %col.setDamageSource(%obj.getDirection());
        %col.setDamageVector(%obj.getDirection(), 10);
     
        if (%col != %obj.sourceObject)
          %obj.sourceObject.setDidDamage(%damageAmount * %distanceScale);
           
        %obj.hitSet.add(%col);
    }
  }
}
 

Volt Cruelerz

Legions Developer
Eh.. I never played tribes, so I don't know the relative distances involved in the usage of the SL from those. I simply based it upon what seemed to be roughly the same in legions. Number tweaking is a very easy thing to do, so not an issue. The other thing was that the range is what I was interpreting to be small when playing by myself. It may also require tweaking based upon feedback. If someone tries it and would like some radical changes to numbers, I'd be open to it.
 

Volt Cruelerz

Legions Developer
Well, on the one hand, it would have been nice, but I also would have been.. What, eight at the time lol? Wasn't quite interested in FPS games then :p

Nah, I've seen videos of people using it before so I tried to make it the legions equivalent of that. Hopefully it's in the right ballpark.
 

Volt Cruelerz

Legions Developer
thanks and is there a way to change the spread to llike a circle or square where all the buckshot will go?

Not without manually setting the angles yourself instead of using an RNG and a for loop. ;) If you want something that will make perfect circles, you can use the same mechanic the cluster bomb has. The problem with that is that the clusters only spread in the x/y plane, not the z so from the side if you fire it straight ahead, it'll just look like a line. So the best mechanism for specialty shapes is to manually set the vectors.
 
Top