08. Moving pawn, Splitting script
Table of Contents generated with DocToc
The material used in this chapter can be downloaded at here.
In this chapter, we will really move a pawn. Really. Also, we will split main.eps into multiple files to make our script easier to manage.
First we create a removePiece
function, a counterpart of placePiece
function.
function removePiece(x, y) {
move1x1Loc(x, y);
RemoveUnitAt(All, '(men)', '1x1', AllPlayers);
setTile(x, y, 0);
}
Next we change the afterTriggerExec
function. If the piece is selected and the selected piece is Scourge, then we move the previously selected pawn to the selected position.
var beforeUnitPlayer, beforeUnitType;
var beforeUnitX, beforeUnitY = -1, -1;
function afterTriggerExec() {
const unitType, selX, selY = sel.getSelectedUnit();
if (unitType != -1) {
if(unitType == $U('Zerg Scourge')) {
piece.removePiece(selX, selY);
piece.placePiece(selX, selY, beforeUnitType, beforeUnitPlayer);
piece.removePiece(beforeUnitX, beforeUnitY);
RemoveUnit("Zerg Scourge", Force3);
beforeUnitX = -1;
beforeUnitY = -1;
}
else if(beforeUnitX != selX || beforeUnitY != selY) {
const tileVal = tile.tile(selX, selY);
beforeUnitPlayer = tileVal / 1000;
beforeUnitType = tileVal % 1000;
beforeUnitX = selX;
beforeUnitY = selY;
RemoveUnit("Zerg Scourge", Force3);
pawn.getPossiblePawnDestination(beforeUnitPlayer, selX, selY);
}
}
else {
RemoveUnit("Zerg Scourge", Force3);
}
SetInvincibility(Enable, "(any unit)", AllPlayers, 'Anywhere');
}
When a Scourge is selected, selX and selY holds the position of the Scourge, so we need some way to know what piece was selected before the Scourge was selected. To do that we update beforeUnitX
, beforeUnitY
, beforeUnitPlayer
, beforeUnitType
for each piece selection, and use that info when the Scourge is selected.
Also, since it takes some time for unit selection pointer to update after we really select the unit, we shouldn't remove and re-create Scourge again and again while we're selecting a Scourge. To prevent Scourge from re-created every frame, we check beforeUnitX != selX && beforeUnitY != selY
to make sure that the scourge gets updated only when a different piece gets selected.
Okay. Until this code, the gameplay looks like this.
main.eps now became 171 lines. This is quite big, so we will split main.eps into multiple eps file.
If you're a map creator, you would probably have created a map with thousands of conditions and actions. Your small map's trigger may have spanned ten thousand of lines in text trigger. From a programmer's perspective, anything over 200 lines is big, and we always try to split our code to a manageable size. We always try to separate unrelated scripts from different functions and different files. In that way, we can make our projects more manageable.
We will split 'main.eps' into the following files.
- loc.eps : Moving 1x1 location.
- tile.eps : In-memory board goes to here.
- selection.eps : Selection detection.
- piece.eps : Placing/removing piece from the board.
- folder 'pieceRule' : Each piece type's moving rule.
- pawn.eps : Pawn's moving rule.
- main.eps : This file only contains
onPluginInit
andafterTriggerExec
.
Split files should reference functions from each other. To do that we use import
. For example, piece.eps uses setTile
in tile.eps like this.
import loc;
import tile;
function placePiece(x, y, unitType, player) {
loc.move1x1Loc(x, y);
CreateUnit(1, unitType, '1x1', player);
tile.setTile(x, y, unitType + player * 1000);
}
function removePiece(x, y) {
loc.move1x1Loc(x, y);
RemoveUnitAt(All, '(men)', '1x1', AllPlayers);
tile.setTile(x, y, 0);
}
-
import tile;
means that 'piece.eps' will use function, variables, and constants from tile.eps. -
piecePlace
function can use function from tile.eps withtile.[function to use]
, liketile.setTile(x, y, unitType + player * 1000);
.
Also, the eps file can be structured into folders. To use functions inside a folder, one should include folder name in the import statement. Like import pieceRule.pawn;
in main.eps. pieceRule.pawn
means 'pawn.eps inside pieceRule folder'. Likewise, import tile;
in 'pieceRule/pawn.eps' means that 'pieceRule/pawn.eps' will use functions inside 'tile.eps'.
If you are coming from C, then you probably have found this similar to
#include
of C.#include
uses a relative path to reference other files, but in epScript, we use an absolute path from the root 'main.eps' file to each eps file. So even 'pieceRule/pawn.eps' imports 'tile.eps' likeimport tile;
, notimport "../tile.eps";
. Beware of that difference.
'main.eps' is our root script because that's what we've included in 'main.edd'.
See the completed material for more info. You can download the material here.
Let's take a break and see what we have done so far. We have implemented a selection detection. We have a pawn's moving rule. This is chapter 8. We've learned a lot of things about euddraft function systems. Now we have to do this thing again for more piece types. Our course had been quite slow because we had to cover the very basics of euddraft.
We have enough basics covered until here, we still have many things to learn throughout this course, but I think we can speed things up a bit. In the next chapter, we will implement a knight and bishop's move.
Thanks for watching this course. See you soon.
- 2018-01-08:
else if(beforeUnitX != selX && beforeUnitY != selY) {
→else if(beforeUnitX != selX || beforeUnitY != selY) {
.
-
Creating chess
-
Appendixes