Custom CO: Difference between revisions
Line 62: | Line 62: | ||
var Constructor = function () { | var Constructor = function () { | ||
this.init = function (co) { | this.init = function (co, map) { | ||
co.setPowerStars(3); | co.setPowerStars(3); | ||
co.setSuperpowerStars(3); | co.setSuperpowerStars(3); |
Revision as of 18:32, 20 August 2022
Notice: Modding tutorials assume you know at least the basics of coding or scripting. Commander Wars uses Javascript as the Scripting Language. In case you want to learn more about Javascript, you can check the tutorial here: Derek Banas' Javascript tutorial , purchase O'Reilly's excellent book on the subject JavaScript: The Definitive Guide, or check out W3 Schools Interactive Tutorials
Setup
In this tutorial a basic CO will be created, with an Advance Wars 2 like set of powers. The mod must be created in the mods folder for the Javascript to be detected properly.
To simplify things, we will create a CO that simply boosts the defense and offense of all units. However notes to modify specific units, adding custom weapon values to units will be linked at the end of the tutorial.
- Create a folder with the name of the CO for simplicity we will name it testco
- Create a mod.txt file with the following contents inside the testco folder. This is required for the engine to detect compatibilities between mods, and to display what your mod does
name=Test CO
description=This is a test CO.
version=N/A
compatible_mods=
incompatible_mods=
required_mods=
cosmetic=false
- Inside testco, create a folder named music and inside of the music folder, create a cos folder. Inside the cos folder is where the music of the CO will be. You can place an mp3 or several mp3s of your choice, One for the theme song of your CO, another one for the Power, third one for the Superpower. They will be used later in the music section of the tutorial.
- Inside testco create a folder named images and inside of the folder images, create yet another folder called co this is where the image files of the CO will be placed. Create an empty xml file inside the co folder. Name it res.xml this file is important and without it, the Engine will not detect the images properly. Leave res.xml empty for now, it will be updated in the images section of this tutorial.
- Next, inside the testco folder, create a folder called scripts; inside of the scripts folder, create yet another folder named cos, please notice these are case sensitive.
- inside the cos folder, create a javascript file named co_test.js
CO Constructor
Inside co_test.js put the following code:
var Constructor = function()
{
this.init = function(co,map)
{
co.setPowerStars(3);
co.setSuperpowerStars(3);
};
this.getCOArmy = function()
{
return "OS";
};
}
Constructor.prototype = CO;
var CO_TEST = new Constructor();
This code simply inits the constructor to create our CO, this.init sets the stars that are required for the Power and Super Power respectively. this.getCOArmy sets to which country the CO belongs to. In this case OS sets it for the Orange Star Army. The list of values are: OS for Orange Star, BM for Blue Moon, YC for Yellow Comet, GE for Green Earth and BH for Black Hole. Custom factions will have their own, specific strings.
CO Intel
Up next, we will add the Intel information of our CO.
var Constructor = function () {
this.init = function (co, map) {
co.setPowerStars(3);
co.setSuperpowerStars(3);
};
this.getCOArmy = function () {
return "OS";
};
this.getBio = function (co) {
return qsTr("A test CO.");
};
this.getHits = function (co) {
return qsTr("Hitting");
};
this.getMiss = function (co) {
return qsTr("Missing");
};
this.getCODescription = function (co) {
return qsTr("A Simple CO created for this tutorial. All units have 10% extra Firepower and Defense");
};
this.getPowerDescription = function (co) {
return qsTr("Increases the Firepower and Defense of all units by 20%");
};
this.getPowerName = function (co) {
return qsTr("Power Boost");
};
this.getSuperPowerDescription = function (co) {
return qsTr("Increases the Firepower and Defense of all units by 40%");
};
this.getSuperPowerName = function (co) {
return qsTr("Super Power Boost");
};
this.getPowerSentences = function (co) {
return [qsTr("Attack!"), qsTr("Destroy the Enemy!")];
};
this.getVictorySentences = function (co) {
return [qsTr("Victory!")];
};
this.getDefeatSentences = function (co) {
return [qsTr("Defeat...")];
};
this.getName = function () {
return qsTr("Test CO");
};
}
Constructor.prototype = CO;
var CO_TEST = new Constructor();
The anonymous functions set the values for each of the respective values in the Engine. The qsTr() function is a Qt function which is used to generate translatable strings in the Engine. You can know more about the qsTr() function here: qsTr()
this.getVictorySentences, this.getDefeatSentences, this.getPowerSentences all take arrays which are randomized when a Victory, Defeat or Power activation occur.
this.getPowerSentences lists the strings for both the CO Power and Super Power.
Adding Offensive and Defensive stats
To add Firepower and Defense in CoW-Engine Style we can use the following functions
//Constructor code ommited for brevity
Constructor.prototype = CO;
var CO_TEST = new Constructor();
CO_TEST.getOffensiveBonus = function (co, attacker, atkPosX, atkPosY,
defender, defPosX, defPosY, isDefender, action, luckMode, map) {
switch (co.getPowerMode())
{
case GameEnums.PowerMode_Tagpower:
case GameEnums.PowerMode_Superpower:
return 50;
case GameEnums.PowerMode_Power:
return 30;
default:
if (co.inCORange(Qt.point(atkPosX, atkPosY), attacker))
{
return 10;
}
break;
}
return 0;
}
CO_TEST.getDeffensiveBonus = function (co, attacker, atkPosX, atkPosY,
defender, defPosX, defPosY, isAttacker, action, luckMode,map) {
switch (co.getPowerMode())
{
case GameEnums.PowerMode_Tagpower:
case GameEnums.PowerMode_Superpower:
return 50;
case GameEnums.PowerMode_Power:
return 30;
default:
if (co.inCORange(Qt.point(atkPosX, atkPosY), attacker))
{
return 10;
}
break;
}
return 0;
}
This will set the Defense and Offense of all units to 10% inside the co-zone as the day to day ability. And increase both to 30% during the Power activation, and to 50% during the Super Powers for all units. All bonuses are applied independend of the fact if it's the first or second co.
The following example does the same but as an AW-DS-Style CO.
//Constructor code ommited for brevity
Constructor.prototype = CO;
var CO_TEST = new Constructor();
CO_TEST.getOffensiveBonus = function (co, attacker, atkPosX, atkPosY,
defender, defPosX, defPosY, isDefender, action, luckMode, map) {
if (co.getIsCO0() === true) {
switch (co.getPowerMode()) {
case GameEnums.PowerMode_Superpower:
return 50;
case GameEnums.PowerMode_Power:
return 30;
default:
return 10;
break;
}
}
return 0;
}
CO_TEST.getDeffensiveBonus = function (co, attacker, atkPosX, atkPosY,
defender, defPosX, defPosY, isAttacker, action, luckMode,map) {
if (co.getIsCO0() === true) {
switch (co.getPowerMode()) {
case GameEnums.PowerMode_Superpower:
return 50;
case GameEnums.PowerMode_Power:
return 30;
default:
return 10;
break;
}
}
return 0;
}
This will set the Defense and Offense of all units to 10% as the day to day ability, increase both to 30% during the Power activation, and to 50% during the Super Power.
If the CO is the currently the first one.
Power and Super Power Animations
To create the Power animation we will use the following code:
//Rest of the code ommited for brevity
var Constructor = function () {
this.activatePower = function (co) {
var dialogAnimation = co.createPowerSentence();
var powerNameAnimation = co.createPowerScreen(GameEnums.PowerMode_Power);
dialogAnimation.queueAnimation(powerNameAnimation);
var units = co.getOwner().getUnits();
var animations = [];
var counter = 0;
units.randomize();
for (var i = 0; i < units.size(); i++) {
var unit = units.at(i);
var animation = GameAnimationFactory.createAnimation(unit.getX(), unit.getY());
if (animations.length < 5) {
animation.addSprite("power2", -map.getImageSize() * 1.27, -map.getImageSize() * 1.27, 0, 1.5, globals.randInt(0, 400));
powerNameAnimation.queueAnimation(animation);
animations.push(animation);
}
else {
animation.addSprite("power2", -map.getImageSize() * 1.27, -map.getImageSize() * 1.27, 0, 1.5);
animations[counter].queueAnimation(animation);
animations[counter] = animation;
counter++;
if (counter >= animations.length) {
counter = 0;
}
}
}
units.remove();
};
}
And for the Super Power:
//Rest of the code omitted for brevity
var Constructor = function () {
this.activateSuperpower = function (co, powerMode) {
var dialogAnimation = co.createPowerSentence();
var powerNameAnimation = co.createPowerScreen(powerMode);
powerNameAnimation.queueAnimationBefore(dialogAnimation);
var units = co.getOwner().getUnits();
var animations = [];
var counter = 0;
units.randomize();
for (var i = 0; i < units.size(); i++) {
var unit = units.at(i);
var animation = GameAnimationFactory.createAnimation(unit.getX(), unit.getY());
if (animations.length < 5) {
animation.addSprite("power12", -map.getImageSize() * 2, -map.getImageSize() * 2, 0, 1.5, globals.randInt(0, 400));
powerNameAnimation.queueAnimation(animation);
animations.push(animation);
}
else {
animation.addSprite("power12", -map.getImageSize() * 2, -map.getImageSize() * 2, 0, 1.5);
animations[counter].queueAnimation(animation);
animations[counter] = animation;
counter++;
if (counter >= animations.length) {
counter = 0;
}
}
}
units.remove();
};
}
CO Images
In the Setup step, we created a set of folders, "mods/testco/images/co/" is where all the images for this tutorial will go. Make sure you also created the res.xml file inside the "mods/testco/images/co/" folder.
Inside res.xml place the following:
<?xml version="1.0"?>
<resources>
<set path = "mods/testco/images/co/" />
<atlas linearFilter="false">
<set scale_factor = "1.0" />
<image file="co_test+nrm.png" />
<set scale_factor = "1.0" />
<image file="co_test+info.png" />
<image file="co_test+face.png" cols = "3" />
</atlas>
</resources>
co_test+nrm.png is the image that will be displayed when the power and superpowers are activated. It will also show on the Intel options of the CO. This image has no set standard and can be of any size you choose, such that it fits on the screen.
co_test+info.png is the image that shows next to the Star Meter of the CO as well as in some menus of the game. The standard size for this image is 32x12.
co_test+face.png is the portrait picture of the CO, with three different facial expressions, the order of these facial expressions is normal, happy and sad, these can be given a rows argument to have Advance Wars style animations. You can use the scale_factor parameter to resize the images in-game. The standard for this image is 144x48 (48x48 for each facial expression).
CO Music
Inside the constructor of the CO, place the following code:
var Constructor = function()
{
//Rest of the code ommited for brevity
this.loadCOMusic = function (co,map) {
switch (co.getPowerMode()) {
case GameEnums.PowerMode_Power:
audio.addMusic("mods/testco/music/cos/Power.mp3", 0, 0);
break;
case GameEnums.PowerMode_Superpower:
audio.addMusic("mods/testco/music/cos/Super.mp3", 0, 0);
break;
case GameEnums.PowerMode_Tagpower:
audio.addMusic("mods/testco/music/cos/Super.mp3", 0, 0);
break;
default:
audio.addMusic("mods/testco/music/cos/Theme.mp3", 0, 0);
break;
}
};
}
Constructor.prototype = CO;
var CO_TEST = new Constructor();
Make sure the files are properly placed inside the path passed to the audio.addMusic() function.
Activating the CO
- Start the Game.
- Click 'Options'.
- On the right hand side of the Options menu, click 'Mods'.
- Activate the checkbox 'Test CO' and click 'Exit'.
After you do, the game will restart on its own. Once the game restarts, click on 'Style CO'. The test CO should show up under Orange Star.