Ticket #1912: ProofOfConcept.patch
File ProofOfConcept.patch, 10.3 KB (added by , 8 years ago) |
---|
-
data/mods/public/gui/credits/texts/programming.json
108 108 {"nick": "kingadami", "name": "Adam Winsor"}, 109 109 {"nick": "kingbasil", "name": "Giannis Fafalios"}, 110 110 {"nick": "lafferjm", "name": "Justin Lafferty"}, 111 {"nick": "LeanderH", "name": "Leander Hemelhof"}, 111 112 {"nick": "leper", "name": "Georg Kilzer"}, 112 113 {"nick": "LittleDev"}, 113 114 {"nick": "livingaftermidnight", "name": "Will Dull"}, -
data/mods/public/simulation/components/Attack.js
88 88 "<Crush>0.0</Crush>" + 89 89 "</Splash>" + 90 90 "</Ranged>" + 91 "<Continuous>" + 92 "<Hack>0.0</Hack>" + 93 "<Pierce>0.0</Pierce>" + 94 "<Crush>10.0</Crush>" + 95 "<Cycles>12</Cycles>" + 96 "<CycleDuration>250</CycleDuration>" + 97 "</Continuous>" + 91 98 "<Charge>" + 92 99 "<Hack>10.0</Hack>" + 93 100 "<Pierce>0.0</Pierce>" + … … 159 166 "</element>" + 160 167 "</optional>" + 161 168 "<optional>" + 169 "<element name='Continuous'>" + 170 "<interleave>" + 171 "<element name='Hack' a:help='Hack damage strength'><ref name='nonNegativeDecimal'/></element>" + 172 "<element name='Pierce' a:help='Pierce damage strength'><ref name='nonNegativeDecimal'/></element>" + 173 "<element name='Crush' a:help='Crush damage strength'><ref name='nonNegativeDecimal'/></element>" + 174 "<element name='Cycles' a:help='Amount of damage cycles'><data type='positiveInteger'/></element>" + 175 "<element name='CycleDuration' a:help='Time between cycles (in milliseconds)'><data type='nonNegativeInteger'/></element>" + 176 Attack.prototype.bonusesSchema + 177 "</interleave>" + 178 "</element>" + 179 "</optional>" + 180 "<optional>" + 162 181 "<element name='Capture'>" + 163 182 "<interleave>" + 164 183 "<element name='Value' a:help='Capture points value'><ref name='nonNegativeDecimal'/></element>" + … … 588 607 "target": target, 589 608 "attacker": this.entity, 590 609 "multiplier": this.GetAttackBonus(type, target), 591 "type": type610 "type": type 592 611 }); 612 if (this.template.Continuous) 613 { 614 let strengths = { 615 "hack": this.template.Continuous.Hack, 616 "pierce": this.template.Continuous.Pierce, 617 "crush": this.template.Continuous.Crush 618 }; 619 this.CauseContinuousDamage({ 620 "strengths": strengths, 621 "target": ents[i], 622 "attacker": this.entity, 623 "multiplier": multiplier, 624 "type": data.type, 625 "cycles": this.template.Continuous.Cycles, 626 "cycleDuration": this.template.Continuous.CycleDuration, 627 }); 628 } 593 629 } 594 630 // TODO: charge attacks (need to design how they work) 595 631 }; … … 677 713 data.strengths = this.GetAttackStrengths(data.type); 678 714 // Hit the primary target 679 715 Damage.CauseDamage(data); 716 if (this.template.Continuous){ 717 let strengths = { 718 "hack": this.template.Continuous.Hack, 719 "pierce": this.template.Continuous.Pierce, 720 "crush": this.template.Continuous.Crush 721 }; 722 this.CauseContinuousDamage({ 723 "strengths": strengths, 724 "target": data.target, 725 "attacker": data.attacker, 726 "multiplier": data.multiplier, 727 "type": data.type, 728 "cycles": this.template.Continuous.Cycles, 729 "cycleDuration": this.template.Continuous.CycleDuration, 730 }); 731 } 680 732 681 733 // Remove the projectile 682 734 let cmpProjectileManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ProjectileManager); … … 692 744 { 693 745 if (this.testCollision(ents[i], data.position, lateness)) 694 746 { 747 let multiplier = this.GetAttackBonus(data.type, ents[i]); 695 748 Damage.CauseDamage({ 696 749 "strengths": this.GetAttackStrengths(data.type), 697 750 "target": ents[i], 698 751 "attacker": this.entity, 699 "multiplier": this.GetAttackBonus(data.type, ents[i]),752 "multiplier": multiplier, 700 753 "type": data.type 701 754 }); 755 if (this.template.Continuous) 756 { 757 let strengths = { 758 "hack": this.template.Continuous.Hack, 759 "pierce": this.template.Continuous.Pierce, 760 "crush": this.template.Continuous.Crush 761 }; 762 this.CauseContinuousDamage({ 763 "strengths": strengths, 764 "target": ents[i], 765 "attacker": this.entity, 766 "multiplier": multiplier, 767 "type": data.type, 768 "cycles": this.template.Continuous.Cycles, 769 "cycleDuration": this.template.Continuous.CycleDuration, 770 }); 771 } 702 772 // Remove the projectile 703 773 let cmpProjectileManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_ProjectileManager); 704 774 cmpProjectileManager.RemoveProjectile(data.projectileId); … … 721 791 cmpUnitAI.UpdateRangeQueries(); 722 792 }; 723 793 794 /** 795 * Causes damage on a given unit every cycle, for a specific number of cycles. 796 * data.strengths = {'hack':<float>, 'pierce':<float>, 'crush':<float>} 797 * data.target = <entity id> 798 * data.attacker = <entity id> 799 * data.multiplier = <float between 1 and 0> 800 * data.type = <string> 801 * data.cycles = <int> 802 * data.cycleDuration = <int> 803 */ 804 Attack.prototype.CauseContinuousDamage = function(data) 805 { 806 var cyclesLeft = data.cycles; 807 var cmpHealth = Engine.QueryInterface(data.target, IID_Health); 808 if (cyclesLeft <= 0 || (cmpHealth && cmpHealth.GetHitpoints() == 0)) //Check if mistakes have been made or if the target is already dead 809 return; 810 Damage.CauseDamage(data); 811 // Check if all damage cycles have happened, or if the damage already killed the target 812 if (--cyclesLeft > 0 && cmpHealth && cmpHealth.GetHitpoints() != 0) 813 { 814 data.cycles = cyclesLeft; 815 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 816 var tmp = cmpTimer.SetTimeout(this.entity, IID_Attack, "CauseContinuousDamage", +data.cycleDuration, data); 817 } 818 } 819 724 820 Engine.RegisterComponentType(IID_Attack, "Attack", Attack); -
data/mods/public/simulation/components/AttackDetection.js
63 63 if (cmpTargetOwnership.GetOwner() != cmpPlayer.GetPlayerID()) 64 64 return; 65 65 var cmpAttackerOwnership = Engine.QueryInterface(attacker, IID_Ownership); 66 // Don't register attacks dealt by myself 67 if ( cmpAttackerOwnership.GetOwner() == cmpPlayer.GetPlayerID())66 // Don't register attacks dealt by myself and ignore if attacker is already dead 67 if (!cmpAttackerOwnership || cmpAttackerOwnership.GetOwner() == cmpPlayer.GetPlayerID()) 68 68 return; 69 69 70 70 // Since livestock can be attacked/gathered by other players -
data/mods/public/simulation/helpers/Damage.js
52 52 } 53 53 // Call CauseDamage which reduces the hitpoints, posts network command, plays sounds.... 54 54 Damage.CauseDamage({"strengths":data.strengths, "target":entity, "attacker":data.attacker, "multiplier":damageMultiplier, "type":data.type + ".Splash"}); 55 var cmpAttack = Engine.QueryInterface(data.attacker, IID_Attack); 56 if (cmpAttack && cmpAttack.template.Continuous) 57 { 58 var strengths = { 59 "hack": cmpAttack.template.Continuous.Hack, 60 "pierce": cmpAttack.template.Continuous.Pierce, 61 "crush": cmpAttack.template.Continuous.Crush 62 }; 63 cmpAttack.CauseContinuousDamage({ 64 "strengths": strengths, 65 "target": entity, 66 "attacker": data.attacker, 67 "multiplier": damageMultiplier, 68 "type": data.type, 69 "cycles": cmpAttack.template.Continuous.Cycles, 70 "cycleDuration": cmpAttack.template.Continuous.CycleDuration, 71 }); 72 } 55 73 } 56 74 }; 57 75 … … 74 92 // Damage the target 75 93 var targetState = cmpDamageReceiver.TakeDamage(data.strengths.hack * data.multiplier, data.strengths.pierce * data.multiplier, data.strengths.crush * data.multiplier); 76 94 77 var cmpPromotion = Engine.QueryInterface(data.attacker, IID_Promotion); 78 var cmpLoot = Engine.QueryInterface(data.target, IID_Loot); 79 if (cmpPromotion && cmpLoot && cmpLoot.GetXp() > 0) 80 cmpPromotion.IncreaseXp(cmpLoot.GetXp() * -targetState.change / cmpHealth.GetMaxHitpoints()); 95 if (cmpHealth.GetHitpoints() != 0) // No loot needed if attacker is already dead 96 { 97 var cmpPromotion = Engine.QueryInterface(data.attacker, IID_Promotion); 98 var cmpLoot = Engine.QueryInterface(data.target, IID_Loot); 99 if (cmpPromotion && cmpLoot && cmpLoot.GetXp() > 0) 100 cmpPromotion.IncreaseXp(cmpLoot.GetXp() * -targetState.change / cmpHealth.GetMaxHitpoints()); 101 } 81 102 82 103 // If the target was killed run some cleanup 83 104 if (targetState.killed) … … 135 156 cmpTargetPlayerStatisticsTracker.LostEntity(targetEntity); 136 157 137 158 // If killer can collect loot, let's try to collect it. 138 var cmpLooter = Engine.QueryInterface(killerEntity, IID_Looter); 139 if (cmpLooter) 140 cmpLooter.Collect(targetEntity); 159 var cmpHealth = Engine.QueryInterface(killerEntity, IID_Health) 160 if (cmpHealth && cmpHealth.GetHitpoints() != 0) // Check if killer is still alive, else no loot is needed. 161 { 162 var cmpLooter = Engine.QueryInterface(killerEntity, IID_Looter); 163 if (cmpLooter) 164 cmpLooter.Collect(targetEntity); 165 } 141 166 }; 142 167 143 168 Engine.RegisterGlobal("Damage", Damage); -
data/mods/public/simulation/templates/template_structure_civic_civil_centre.xml
20 20 <PrepareTime>1200</PrepareTime> 21 21 <RepeatTime>2000</RepeatTime> 22 22 <Spread>1.5</Spread> 23 <Splash> 24 <Shape>Circular</Shape> 25 <Range>20</Range> 26 <FriendlyFire>false</FriendlyFire> 27 <Hack>0.0</Hack> 28 <Pierce>0.1</Pierce> 29 <Crush>0.0</Crush> 30 </Splash> 23 31 </Ranged> 32 <Continuous> 33 <Hack>0.0</Hack> 34 <Pierce>0.0</Pierce> 35 <Crush>10.0</Crush> 36 <Cycles>12</Cycles> 37 <CycleDuration>250</CycleDuration> 38 </Continuous> 24 39 </Attack> 25 40 <BuildingAI> 26 41 <DefaultArrowCount>3</DefaultArrowCount>