Page 2 of 2

Re: Upgrades

Posted: 27 Mar 2013, 21:38
by Duha
aubergine wrote:@Duha: Having JS functions in .ini would be grim IMHO.
I don`t say about javascript in ini!!!!

Simple update is something like:
function = Termal30

Ini contains only function name
function = upgradeTermal
function = userDefindeUpgrade

Search name in mod_research.js, after that in base_research.js and execute function.

Re: Upgrades

Posted: 27 Mar 2013, 23:52
by aubergine
Ah, that makes more sense.

Re: Upgrades

Posted: 06 Apr 2013, 12:27
by Per
The functions idea is neat. I am coding the easy solution now, just to see that it works and how that would look. So here is the simplest way to implement it:

Code: Select all

function eventResearched(research, structure, player)
{
	var cyborgBodies = ['Cyborg Flamer', 'Cyborg Assault Gun', 'Cyborg Rocket', 'Cyborg Cannon',
	                    'Super Tank-Killer Cyborg', 'Super Rail-Gunner', 'Super Pulse Laser Cyborg',
	                    'Super Heavy-Gunner', 'Super HPV Cyborg', 'Super Auto-Cannon Cyborg',
	                    'Super Scourge Cyborg', 'Cyborg Thermite', 'Cyborg Railgun', 'Cyborg Mechanic',
	                    'Cyborg Laser', 'Cyborg Grenadier', 'Combat Engineer', 'Cyborg Anti-Tank'];
	var droidBodies = ['Tiger', 'Scorpion', 'Retribution', 'Panther', 'Cobra', 'Bug', 'Retaliation',
	                   'Leopard', 'Viper', 'Dragon', 'Wyvern', 'Mantis', 'Python', 'Vengeance'];
	var cyborgHeat = ['Cyborg Thermal Armor', 'Cyborg Thermal Armor Mk2', 'Cyborg Thermal Armor Mk3',
	                  'Cyborg High Intensity Thermal Armor', 'Cyborg High Intensity Thermal Armor Mk2',
	                  'Cyborg High Intensity Thermal Armor Mk3', 'Cyborg Superdense Thermal Armor', 
	                  'Cyborg Superdense Thermal Armor Mk2', 'Cyborg Superdense Thermal Armor Mk3'];
	var droidHeat = ['Thermal Armor', 'Thermal Armor Mk2', 'Thermal Armor Mk3', 'High Intensity Thermal Armor',
	                 'High Intensity Thermal Armor Mk2', 'High Intensity Thermal Armor Mk3',
	                 'Vehicle Superdense Thermal Armor', 'Vehicle Superdense Thermal Armor Mk2',
	                 'Vehicle Superdense Thermal Armor Mk3'];
	var droidPower = ['Fuel Injection Engine', 'Fuel Injection Engine Mk2', 'Fuel Injection Engine Mk3',
	                  'Turbo-Charged Engine', 'Turbo-Charged Engine Mk2', 'Turbo-Charged Engine Mk3',
	                  'Gas Turbine Engine', 'Gas Turbine Engine Mk2', 'Gas Turbine Engine Mk3'];
	var droidArmour = ['Composite Alloys', 'Composite Alloys Mk2', 'Composite Alloys Mk3', 'Composite Alloys Mk4',
	                   'Dense Composite Alloys', 'Dense Composite Alloys Mk2', 'Dense Composite Alloys Mk3',
	                   'Superdense Composite Alloys', 'Superdense Composite Alloys Mk2', 'Superdense Composite Alloys Mk3'];
	var cyborgArmour = ['Cyborg Composite Alloys', 'Cyborg Composite Alloys Mk2', 'Cyborg Composite Alloys Mk3',
	                    'Cyborg Dense Composite Alloys', 'Cyborg Dense Composite Alloys Mk2',
	                    'Cyborg Dense Composite Alloys Mk3', 'Cyborg Superdense Composite Alloys',
	                    'Cyborg Superdense Composite Alloys Mk2', 'Cyborg Superdense Composite Alloys Mk3'];

	if (droidHeat.indexOf(research.fullname) >= 0)
	{
		for (var i = 0; i < droidBodies.length; i++)
		{
			Upgrades[player].Body[droidBodies[i]].Thermal += 40;
		}
	}
	if (cyborgHeat.indexOf(research.fullname) >= 0)
	{
		for (var i = 0; i < droidBodies.length; i++)
		{
			Upgrades[player].Body[droidBodies[i]].Thermal += 45;
		}
	}
	if (droidPower.indexOf(research.fullname) >= 0)
	{
		for (var i = 0; i < droidBodies.length; i++)
		{
			Upgrades[player].Body[droidBodies[i]].Power += 5;
		}
	}
	if (droidArmour.indexOf(research.fullname) >= 0)
	{
		for (var i = 0; i < droidBodies.length; i++)
		{
			Upgrades[player].Body[droidBodies[i]].Armour += 30;
			Upgrades[player].Body[droidBodies[i]].HitPoints += 30;
		}
	}
	if (cyborgArmour.indexOf(research.fullname) >= 0)
	{
		for (var i = 0; i < droidBodies.length; i++)
		{
			Upgrades[player].Body[droidBodies[i]].Armour += 35;
			Upgrades[player].Body[droidBodies[i]].HitPoints += 35;
		}
	}
}
The droidBodies and cyborgBodies arrays should be seen as temporary hacks for now, since I can't get this list with the droid/cyborg distinction intact from anywhere yet. So ignore those.

A very work-in-progress patch is attached in case anyone want to experiment with the design. Note that 'work harder' cheat won't work yet. Probably a lot of other stuff is still broken too. But the basics work now.

Re: Upgrades

Posted: 06 Apr 2013, 13:40
by Per
Just thinking aloud a bit... how about instead of adding actual functions, we just add an array of hints in the ini file that can be parsed by the eventResearched() event?

Eg you can have a line

Code: Select all

rulesHints = "Armour:35", "HitPoints:35"
in the 'Cyborg Composite Alloys' entry in the ini file.

Re: Upgrades

Posted: 06 Apr 2013, 15:02
by Per
I quickly coded up the above idea. One of the result hints is "Droids" or "Cyborgs" to indicate which body list to use. Here is how the resulting rules.js function looks like:

Code: Select all

function eventResearched(research, structure, player)
{
	// TBD temporary hacks until we have this information from somewhere else...
	var cyborgBodies = ['Cyborg Flamer', 'Cyborg Assault Gun', 'Cyborg Rocket', 'Cyborg Cannon',
	                    'Super Tank-Killer Cyborg', 'Super Rail-Gunner', 'Super Pulse Laser Cyborg',
	                    'Super Heavy-Gunner', 'Super HPV Cyborg', 'Super Auto-Cannon Cyborg',
	                    'Super Scourge Cyborg', 'Cyborg Thermite', 'Cyborg Railgun', 'Cyborg Mechanic',
	                    'Cyborg Laser', 'Cyborg Grenadier', 'Combat Engineer', 'Cyborg Anti-Tank'];
	var droidBodies = ['Tiger', 'Scorpion', 'Retribution', 'Panther', 'Cobra', 'Bug', 'Retaliation',
	                   'Leopard', 'Viper', 'Dragon', 'Wyvern', 'Mantis', 'Python', 'Vengeance'];

	for (var v = 0; v < research.results.length; v++)
	{
		var s = research.results[v].split(":");
		if (['Power', 'Armour', 'HitPoints', 'Thermal'].indexOf(s[0]) >= 0) // droid stuff
		{
			if (research.results.indexOf('Droids') >= 0) // applies to droids
			{
				for (var i = 0; i < droidBodies.length; i++)
				{
					Upgrades[player].Body[droidBodies[i]][s[0]] += s[1];
				}
			}
			if (research.results.indexOf('Cyborgs') >= 0) // applies to cyborgs
			{
				for (var i = 0; i < cyborgBodies.length; i++)
				{
					Upgrades[player].Body[cyborgBodies[i]][s[0]] += s[1];
				}
			}
		}
	}
}
IMHO it looks much cleaner, and you can specify what you can to do in the .ini file as requested. Example hint string from research.ini:

Code: Select all

results = "Armour:35", "HitPoints:35", "Cyborgs"

Re: Upgrades

Posted: 06 Apr 2013, 18:49
by Duha
Per wrote:IMHO it looks much cleaner, and you can specify what you can to do in the .ini file as requested. Example hint string from research.ini:

Code: Select all

results = "Armour:35", "HitPoints:35", "Cyborgs"

Code: Select all

var bodies = {'cyborg' : cyborgBodies, droid: 'droidBodies'}
result = 'cyborg_armour_35, cyborg_hitPoints_35'  // research result

var functions = result.replace(' ', '').split(',').map(function(x) {return x.split('_')}) // [["cyborg", "armour", "35"], ["cyborg", "hitPoints", "35"]] 

functions.forEach(function(params) {
         var array = bodies[params[0]] // array of bodies
         var upgradeType = params[1];
         var upgradeValue =params[2];
         array.forEach(function(body){Upgrades[player].Body[body][upgradeValue] += value})
})

Re: Upgrades

Posted: 08 Apr 2013, 00:28
by Per
I don't want a solution that is so clever that nobody except seasoned javascript veterans will understand it.

I added a 'class' field to body.ini, which is accessible through a .bodyClass field in the Upgrades object, to remove the body definitions:

Code: Select all

function eventResearched(research, structure, player)
{
	var droids = (research.results.indexOf('Droids') >= 0); // applies to droids
	var cyborgs = (research.results.indexOf('Cyborgs') >= 0); // applies to cyborgs
	for (var v = 0; v < research.results.length; v++)
	{
		var s = research.results[v].split(":");
		if (['Power', 'Armour', 'HitPoints', 'Thermal'].indexOf(s[0]) >= 0) // droid stuff
		{
			for (var i in Upgrades[player].Body)
			{
				if ((droids && Upgrades[player].Body[i].bodyClass === 'Droids')
				    || (cyborgs && Upgrades[player].Body[i].bodyClass === 'Cyborgs'))
				{
					Upgrades[player].Body[i][s[0]] += s[1];
				}
			}
		}
	}
}
I should probably un-hardcode the class names in the above, eg use "Class:Droids" in research.ini instead of just "Droids". But I think it is starting to shape up, and this can easily be fixed later.

Re: Upgrades

Posted: 08 Apr 2013, 12:10
by Duha
Per wrote:I don't want a solution that is so clever that nobody except seasoned javascript veterans will understand it.
Thanks.
The Zen of (some other object-oriented, dynamic language) wrote:Flat is better than nested.
map, forEach and other high class functions is more readable than cycles. Yes functional approch is more complex then imperative, but it has more benefits.

I still suggest to join bodyClass to string "cyborg:armour:35"
You will never miss class: (In you variant if class not specified nothing will be upgraded)
You can make different upgrades to classes: 'cyborg:armour:35', 'cyborg:armour:25'

Re: Upgrades

Posted: 08 Apr 2013, 23:45
by aubergine
Duha wrote:I still suggest to join bodyClass to string "cyborg:armour:35"
You will never miss class: (In you variant if class not specified nothing will be upgraded)
You can make different upgrades to classes: 'cyborg:armour:35', 'cyborg:armour:25'
+1 :) I like that approach

Re: Upgrades

Posted: 13 Apr 2013, 23:41
by Per
Duha wrote:I still suggest to join bodyClass to string "cyborg:armour:35"
You will never miss class: (In you variant if class not specified nothing will be upgraded)
You can make different upgrades to classes: 'cyborg:armour:35', 'cyborg:armour:25'
Good idea. Done.

Anyone who wants to test or review this code can read/pull from https://github.com/perim/warzone2100/commits/upgrades.

Re: Upgrades

Posted: 14 Apr 2013, 00:33
by aubergine
What happens if an armour upgrade applies to both borgs and tanks? Or both defences and structures?

Re: Upgrades

Posted: 14 Apr 2013, 01:01
by Per
aubergine wrote:What happens if an armour upgrade applies to both borgs and tanks? Or both defences and structures?
You can add both "Cyborgs:Armour:30" and "Droids:Armour:30" on the same results line. When support for structures are added (work in progress), you could add that as well. It should be quite flexible.

Re: Upgrades

Posted: 19 Apr 2013, 18:43
by Per
Added to my upgrades branch:
  • New global 'Stats' that holds non-upgraded, read-only game data. It now holds Stats.Body.BodyClass, for example, and a lot of other information on droid bodies. I will add all other relevant data here going forward.
  • getWeaponInfo() is deprecated. Use the above global instead. (Weapon data not added to it yet.)
  • New sub-object to 'Upgrades' holding production/repair/research/power speeds. Eg Upgrades[player].Building.ResearchPoints
  • The above are real values, not percentages, unlike the previous body upgrades.This is obviously inconsistent, and I think I will resolve it by making all values in Upgrades real values rather than percentages.
  • Base research/repair/power/production speeds can be set in structure.ini