Jason's skybox as well as entity changes for the new heal, trample and repair actions and fixes for the per-player templates.

This was SVN commit r3866.
This commit is contained in:
Matei
2006-05-16 04:43:11 +00:00
parent 275a73851c
commit 6bf7f2c4eb
15 changed files with 278 additions and 53 deletions
@@ -9,9 +9,9 @@
<Creation>
<Time>5</Time>
<Resource>
<Food>2</Food>
<Wood>1</Wood>
<Stone>3</Stone>
<Food>15</Food>
<Wood>10</Wood>
<Stone>5</Stone>
</Resource>
</Creation>
</Traits>
@@ -21,6 +21,7 @@ const ACTION_GATHER = 2;
const ACTION_HEAL = 3;
const ACTION_ATTACK_RANGED = 4;
const ACTION_BUILD = 5;
const ACTION_REPAIR = 6;
const PRODUCTION_TRAIN = 1;
const PRODUCTION_RESEARCH = 2;
@@ -36,7 +37,7 @@ function entityInit()
// If this is a foundation, initialize traits from the building we're converting into
if( this.building && this.building != "" )
{
var building = getEntityTemplate( this.building );
var building = getEntityTemplate( this.building, this.player );
this.traits.id.generic = building.traits.id.generic;
this.traits.id.specific = building.traits.id.specific;
this.traits.id.civ = building.traits.id.civ;
@@ -187,6 +188,10 @@ function entityInit()
{
this.setActionParams( ACTION_BUILD, 0.0, 2.0, this.actions.build.speed, "build" );
}
if( this.actions.repair )
{
this.setActionParams( ACTION_REPAIR, 0.0, 2.0, this.actions.repair.speed, "build" );
}
}
// Attach functions to ourselves
@@ -196,6 +201,7 @@ function entityInit()
this.performGather = performGather;
this.performHeal = performHeal;
this.performBuild = performBuild;
this.performRepair = performRepair;
this.damage = damage;
this.entityComplete = entityComplete;
this.GotoInRange = GotoInRange;
@@ -293,22 +299,32 @@ function attachAuras()
if( this.traits.auras.courage )
{
a = this.traits.auras.courage;
this.addAura ( "courage", a.radius, new DamageModifyAura( this, true, a.bonus ) );
this.addAura ( "courage", a.radius, 0, new DamageModifyAura( this, true, a.bonus ) );
}
if( this.traits.auras.fear )
if( this.traits.auras.fear )
{
a = this.traits.auras.fear;
this.addAura ( "fear", a.radius, new DamageModifyAura( this, false, -a.bonus ) );
this.addAura ( "fear", a.radius, 0, new DamageModifyAura( this, false, -a.bonus ) );
}
if( this.traits.auras.infidelity )
if( this.traits.auras.infidelity )
{
a = this.traits.auras.infidelity;
this.addAura ( "infidelity", a.radius, new InfidelityAura( this, a.time ) );
this.addAura ( "infidelity", a.radius, 0, new InfidelityAura( this, a.time ) );
}
if( this.traits.auras.dropsite )
if( this.traits.auras.dropsite )
{
a = this.traits.auras.dropsite;
this.addAura ( "dropsite", a.radius, new DropsiteAura( this, a.types ) );
this.addAura ( "dropsite", a.radius, 0, new DropsiteAura( this, a.types ) );
}
if( this.traits.auras.heal )
{
a = this.traits.auras.heal;
this.addAura ( "heal", a.radius, a.speed, new HealAura( this ) );
}
if( this.traits.auras.trample )
{
a = this.traits.auras.trample;
this.addAura ( "trample", a.radius, a.speed, new TrampleAura( this ) );
}
}
}
@@ -324,7 +340,7 @@ function foundationDestroyed( evt )
var bp = this.build_points;
var fractionToReturn = (bp.max - bp.curr) / bp.max;
var resources = getEntityTemplate( this.building ).traits.creation.resource;
var resources = getEntityTemplate( this.building, this.player ).traits.creation.resource;
for( r in resources )
{
amount = parseInt( fractionToReturn * parseInt(resources[r]) );
@@ -344,24 +360,31 @@ function performAttack( evt )
// Attack logic.
var dmg = new DamageType();
var flank = (evt.target.getAttackDirections()-1)*evt.target.traits.flank_penalty.value;
if ( this.getRunState() )
{
console.write("" + this + " doing a charge attack!");
dmg.crush = parseInt(this.actions.attack.charge.damage * this.actions.attack.charge.crush);
dmg.hack = parseInt(this.actions.attack.charge.damage * this.actions.attack.charge.hack);
dmg.pierce = parseInt(this.actions.attack.charge.damage * this.actions.attack.charge.pierce);
var a = this.actions.attack.charge;
dmg.crush = parseInt(a.damage * a.crush);
dmg.hack = parseInt(a.damage * a.hack);
dmg.pierce = parseInt(a.damage * a.pierce);
this.setRun( false );
}
else
{
dmg.crush = parseInt(this.actions.attack.melee.damage * this.actions.attack.melee.crush);
dmg.hack = parseInt(this.actions.attack.melee.damage * this.actions.attack.melee.hack);
dmg.pierce = parseInt(this.actions.attack.melee.damage * this.actions.attack.melee.pierce);
var a = this.actions.attack.melee;
dmg.crush = parseInt(a.damage * a.crush);
dmg.hack = parseInt(a.damage * a.hack);
dmg.pierce = parseInt(a.damage * a.pierce);
}
// Add flank bonus
if(evt.target.traits.flank_penalty)
{
var flank = (evt.target.getAttackDirections()-1)*evt.target.traits.flank_penalty.value;
dmg.crush += dmg.crush * flank;
dmg.hack += dmg.hack * flank;
dmg.pierce += dmg.pierce * flank;
}
dmg.crush += dmg.crush * flank;
dmg.hack += dmg.hack * flank;
dmg.pierce += dmg.pierce * flank;
evt.target.damage( dmg, this );
@@ -375,14 +398,19 @@ function performAttackRanged( evt )
// Create a projectile from us, to the target, that will do some damage when it hits them.
dmg = new DamageType();
dmg.crush = parseInt(this.actions.attack.ranged.damage * this.actions.attack.ranged.crush);
dmg.hack = parseInt(this.actions.attack.ranged.damage * this.actions.attack.ranged.hack);
dmg.pierce = parseInt(this.actions.attack.ranged.damage * this.actions.attack.ranged.pierce);
var a = this.actions.attack.ranged;
dmg.crush = parseInt(a.damage * a.crush);
dmg.hack = parseInt(a.damage * a.hack);
dmg.pierce = parseInt(a.damage * a.pierce);
var flank = (evt.target.getAttackDirections()-1)*evt.target.traits.flank_penalty.value;
dmg.crush += dmg.crush * flank;
dmg.hack += dmg.hack * flank;
dmg.pierce += dmg.pierce * flank;
// Add flank bonus
if(evt.target.traits.flank_penalty)
{
var flank = (evt.target.getAttackDirections()-1)*evt.target.traits.flank_penalty.value;
dmg.crush += dmg.crush * flank;
dmg.hack += dmg.hack * flank;
dmg.pierce += dmg.pierce * flank;
}
// The parameters for Projectile are:
// 1 - The actor to use as the projectile. There are two ways of specifying this:
@@ -544,6 +572,12 @@ function performHeal( evt )
function performBuild( evt )
{
if( !canBuild( this, evt.target ) )
{
evt.preventDefault();
return;
}
var t = evt.target;
var b = this.actions.build;
var bp = t.build_points;
@@ -558,7 +592,7 @@ function performBuild( evt )
// We've finished building this object; convert the foundation to a building
if( t.building != "" ) // Might be false if another unit finished building the thing during our last anim cycle
{
t.template = getEntityTemplate( t.building );
t.template = getEntityTemplate( t.building, t.player );
t.building = "";
t.attachAuras();
@@ -572,6 +606,48 @@ function performBuild( evt )
// ====================================================================
function performRepair( evt )
{
if( !canRepair( this, evt.target ) )
{
evt.preventDefault();
return;
}
var t = evt.target;
var b = this.actions.build;
var hp = t.traits.health;
// Find the fraction of max health to repair by; this should be one build tick (i.e. longer for buildings with
// longer creation time) but also not so much that it causes the unit to have more than max HP
var fraction = Math.min(
parseFloat( b.rate ) / t.traits.creation.time,
( hp.max - hp.curr ) / hp.max
);
console.write("Repair fraction is " + fraction);
// Check if we can afford to repair
var resources = t.traits.creation.resource;
for( r in resources )
{
amount = parseInt( fraction * parseInt(resources[r]) );
getGUIGlobal().deductResources( r.toString(), amount );
}
// Heal the building
hp.curr = Math.min( hp.max, hp.curr + fraction * hp.max );
// Deduct the resources
var resources = t.traits.creation.resource;
for( r in resources )
{
amount = parseInt( fraction * parseInt(resources[r]) );
getGUIGlobal().deductResources( r.toString(), amount );
}
}
// ====================================================================
function damage( dmg, inflictor )
{
if(!this.traits.armour) return; // corpses have no armour, everything else should
@@ -636,7 +712,7 @@ function damage( dmg, inflictor )
inflictor.traits.id.icon_cell++;
// Transmogrify him into his next rank.
inflictor.template = getEntityTemplate(inflictor.traits.promotion.newentity, inflictor.player);
inflictor.template = getEntityTemplate( inflictor.traits.promotion.newentity, inflictor.player );
}
}
break;
@@ -706,6 +782,8 @@ function entityEventGeneric( evt )
this.performAttackRanged( evt ); break;
case ACTION_BUILD:
this.performBuild( evt ); break;
case ACTION_REPAIR:
this.performRepair( evt ); break;
default:
console.write( "Unknown generic action: " + evt.action );
@@ -880,6 +958,17 @@ function entityEventTargetChanged( evt )
evt.secondaryAction = ACTION_BUILD;
evt.secondaryCursor = "action-build";
}
if ( canRepair( this, evt.target ) )
{
evt.defaultOrder = NMT_Generic;
evt.defaultAction = ACTION_REPAIR;
evt.defaultCursor = "action-build";
evt.secondaryOrder = NMT_Generic;
evt.secondaryAction = ACTION_REPAIR;
evt.secondaryCursor = "action-build";
}
}
@@ -988,6 +1077,16 @@ function entityEventPrepareOrder( evt )
evt.notifyType = NOTIFY_NONE;
this.forceCheckListeners( NOTIFY_ORDER_CHANGE, this );
break;
case ACTION_REPAIR:
if ( !this.actions.repair )
{
evt.preventDefault();
return;
}
evt.notifyType = NOTIFY_NONE;
this.forceCheckListeners( NOTIFY_ORDER_CHANGE, this );
break;
}
break;
@@ -1018,7 +1117,7 @@ function entityStartProduction( evt )
if(evt.productionType == PRODUCTION_TRAIN)
{
var template = getEntityTemplate( evt.name );
var template = getEntityTemplate( evt.name, this.player );
var result = entityCheckQueueReq( this, template );
if (result == true) // If the entry meets requirements to be added to the queue (eg sufficient resources)
@@ -1043,7 +1142,7 @@ function entityStartProduction( evt )
}
// Set the amount of time it will take to complete production of the production object.
evt.time = getEntityTemplate(evt.name).traits.creation.time;
evt.time = getEntityTemplate( evt.name, this.player ).traits.creation.time;
}
else
{
@@ -1065,7 +1164,7 @@ function entityCancelProduction( evt )
if(evt.productionType == PRODUCTION_TRAIN)
{
// Give back all the resources spent on this entry.
var template = getEntityTemplate( evt.name );
var template = getEntityTemplate( evt.name, this.player );
var pool = template.traits.creation.resource;
for ( resource in pool )
{
@@ -1092,7 +1191,7 @@ function entityFinishProduction( evt )
if(evt.productionType == PRODUCTION_TRAIN)
{
var template = getEntityTemplate(evt.name);
var template = getEntityTemplate( evt.name, this.player );
// Code to find a free space around an object is tedious and slow, so
// I wrote it in C. Takes the template object so it can determine how
@@ -1220,7 +1319,7 @@ function entityCreateComplete()
function attemptAddToBuildQueue( entity, create_tag, tab, list )
{
template = getEntityTemplate( create_tag );
template = getEntityTemplate( create_tag, entity.player );
result = entityCheckQueueReq( entity, template );
if (result == true) // If the entry meets requirements to be added to the queue (eg sufficient resources)
@@ -1342,6 +1441,19 @@ function canBuild( source, target )
// ====================================================================
function canRepair( source, target )
{
// Checks whether we're allowed to gather from a target entity (this involves looking at both the type and subtype).
if( !source.actions )
return false;
r = source.actions.repair;
return( r && target.traits.health.repairable && target.player.id == source.player.id
&& target.traits.health.curr < target.traits.health.max
&& target.building == "" );
}
// ====================================================================
function DamageType()
{
this.typeless = 0.0;
@@ -1524,6 +1636,75 @@ function InfidelityAura( source, time )
}
// ====================================================================
function HealAura( source )
{
// Defines the effects of the Heal aura. Slowly heals nearby allies over time.
this.source = source;
this.affects = function( e )
{
return ( e.player.id == this.source.player.id && e.traits.health
&& e.traits.health.healable
&& e.traits.health.curr < e.traits.health.max );
}
this.onTick = function( e )
{
if( this.affects( e ) )
{
var hp = e.traits.health;
var rate = this.source.traits.auras.heal.rate;
hp.curr = Math.min( hp.max, hp.curr + rate );
}
};
}
// ====================================================================
function TrampleAura( source )
{
// Defines the effects of the Trample aura. Damages nearby enemies over time if the unit is charging or has recently charged.
this.source = source;
this.affects = function( e )
{
// Check if the target is an enemy foot unit with health and if we were running in the last 3 seconds
var a = this.source.traits.auras.trample;
return ( e.player.id != this.source.player.id && e.traits.health && e.hasClass("Foot")
&& (getGameTime() - this.source.last_run_time < a.duration) );
}
this.onTick = function( e )
{
if( this.affects( e ) )
{
// Set up the damage object
var dmg = new DamageType();
var a = this.source.traits.auras.trample;
dmg.crush = parseInt(a.damage * a.crush);
dmg.hack = parseInt(a.damage * a.hack);
dmg.pierce = parseInt(a.damage * a.pierce);
// Add flank bonus
if(e.traits.flank_penalty)
{
var flank = (e.getAttackDirections()-1)*e.traits.flank_penalty.value;
dmg.crush += dmg.crush * flank;
dmg.hack += dmg.hack * flank;
dmg.pierce += dmg.pierce * flank;
}
// Perform the damage
e.damage( dmg, this.source );
}
};
}
// ====================================================================
function GotoInRange( x, y, run )
{
if ( !this.actions || !this.actions.move )
@@ -1534,7 +1715,9 @@ function GotoInRange( x, y, run )
else
this.order( ORDER_GOTO, x, y - this.actions.escort.distance, true);
}
//=====================================================================
function entityEventFormation( evt )
{
if ( evt.formationEvent == FORMATION_ENTER )
@@ -17,14 +17,23 @@
</Id>
<Creation>
<Time>10</Time>
<Resource>
<Food>0</Food>
<Wood>100</Wood>
<Stone>50</Stone>
</Resource>
</Creation>
<Health>
<Bar_Height>12.0</Bar_Height>
<Repairable />
</Health>
<Vision>
<LOS>9</LOS>
</Vision>
</Traits>
<Script File="entities/template_entity_script.js" />
@@ -27,6 +27,14 @@
<Height>8.0</Height>
</Footprint>
<Auras>
<Heal>
<Radius>30</Radius>
<Rate>5</Rate>
<Speed>2000</Speed>
</Heal>
</Auras>
<Health>
<Max>600</Max>
</Health>
@@ -50,7 +50,7 @@
<Max>100</Max>
<Bar_Height>5.0</Bar_Height>
<Bar_Size>20</Bar_Size>
<Healable />
</Health>
<Stamina>
@@ -83,7 +83,7 @@
<Run>
<Speed>15.0</Speed>
<Range>50.0</Range>
<RangeMin>10.0</RangeMin>
<RangeMin>0.0</RangeMin>
<Regen_Rate>10.0</Regen_Rate>
<Decay_Rate>5.0</Decay_Rate>
@@ -42,17 +42,6 @@
<Promotion>
<Req>900</Req>
</Promotion>
<Auras>
<Trample>
<Radius>1</Radius>
<Damage>50</Damage>
<Crush>0</Crush>
<Hack>0.9</Hack>
<Pierce>0.1</Pierce>
</Trample>
</Auras>
</Traits>
<Actions>
@@ -78,7 +67,7 @@
<Run>
<Speed>30.0</Speed>
<Range>100.0</Range>
<Range>150.0</Range>
<RangeMin>10.0</RangeMin>
</Run>
@@ -12,6 +12,18 @@
</Id>
<Auras>
<Trample>
<Radius>10</Radius>
<Speed>1000</Speed>
<Duration>3</Duration>
<Damage>20.0</Damage>
<Crush>0.0</Crush>
<Hack>0.5</Hack>
<Pierce>0.5</Pierce>
</Trample>
</Auras>
</Traits>
<Actions>
@@ -87,7 +87,10 @@
<XP />
</Loot>
<Repair />
<Repair>
<Rate>1.0</Rate>
<Speed>1000</Speed>
</Repair>
<Build>
<Rate>1.0</Rate>
@@ -53,7 +53,10 @@
<Speed>3000</Speed>
</Gather>
<Repair />
<Repair>
<Rate>0.5</Rate>
<Speed>1000</Speed>
</Repair>
</Actions>