Skip to content

03. Placing pieces

phu54321 edited this page Feb 10, 2018 · 5 revisions

Table of Contents generated with DocToc

You can download this chapter's material here.

This chapter is about placing pieces like above. Really, does this even deserve a separate chapter? Who doesn't know how to use SCMDraft2?

We're not going this way. We're going to place these pieces by a script. In this way, we can learn more about euddraft, and this will make the script much, much easier to manage in long term. For a sneak peek, we're going to generate the pieces by this code.

function onPluginStart() {
    placePiece(0, 0, $U("Rook"),   $P7);
    placePiece(1, 0, $U("Knight"), $P7);
    placePiece(2, 0, $U("Bishop"), $P7);
    placePiece(3, 0, $U("King"),   $P7);
    placePiece(4, 0, $U("Queen"),  $P7);
    placePiece(5, 0, $U("Bishop"), $P7);
    placePiece(6, 0, $U("Knight"), $P7);
    placePiece(7, 0, $U("Rook"),   $P7);
    placePiece(0, 1, $U("Pawn"),   $P7);
    placePiece(1, 1, $U("Pawn"),   $P7);
    placePiece(2, 1, $U("Pawn"),   $P7);
    placePiece(3, 1, $U("Pawn"),   $P7);
    placePiece(4, 1, $U("Pawn"),   $P7);
    placePiece(5, 1, $U("Pawn"),   $P7);
    placePiece(6, 1, $U("Pawn"),   $P7);
    placePiece(7, 1, $U("Pawn"),   $P7);
    placePiece(0, 7, $U("Rook"),   $P8);
    placePiece(1, 7, $U("Knight"), $P8);
    placePiece(2, 7, $U("Bishop"), $P8);
    placePiece(3, 7, $U("King"),   $P8);
    placePiece(4, 7, $U("Queen"),  $P8);
    placePiece(5, 7, $U("Bishop"), $P8);
    placePiece(6, 7, $U("Knight"), $P8);
    placePiece(7, 7, $U("Rook"),   $P8);
    placePiece(0, 6, $U("Pawn"),   $P8);
    placePiece(1, 6, $U("Pawn"),   $P8);
    placePiece(2, 6, $U("Pawn"),   $P8);
    placePiece(3, 6, $U("Pawn"),   $P8);
    placePiece(4, 6, $U("Pawn"),   $P8);
    placePiece(5, 6, $U("Pawn"),   $P8);
    placePiece(6, 6, $U("Pawn"),   $P8);
    placePiece(7, 6, $U("Pawn"),   $P8);
}

In short, we'll create a function placePiece(x, y, type, player) that generates type piece owned by player at position (x, y).

Q) Wait, that gets compiled into triggers...?

A) Yes.

Moving location by EUD

How should placePiece look like? I think it should look like this.

function placePiece(x, y, unitType, player) {
    move1x1Loc(x, y); // Move location 1x1 to cell (x, y) of the chess board.
    CreateUnit(1, unitType, '1x1', player);
}

Lines starting with // is comments. It explains what the code does.

In this course, every text in a box like this or Lines starting with // is comments. It explains what the code does. thing is an side-explanation. These texts are outside of our course, and you won't have any trouble reading this course even if you skip all those boxes.

Here we define a function called placePiece. Functions are script snippets that do something. You can reuse the function over and over again.

Functions can accept multiple values and behave according to it. placePiece function here receives x, y, unitType, and player, as shown in the line function placePiece(x, y, unitType, player). Values passed to function are called parameters. So we say 'placePiece accepts four parameters x, y, unitType, and player'.

Function uses the given parameters. For example, if we write this code

placePiece(4, 6, $U("Pawn"),   $P8);

It means that we will call placePiece with parameters

  • x as 4
  • y as 6
  • unitType as $U("Pawn")
  • player as $P8

Then these passed parameters are used inside the function like this.

move1x1Loc(4, 6); // Move location 1x1 to cell (x, y) of the chess board.
CreateUnit(1, $U("Pawn"), '1x1', $P8);

On our onPluginStart code, we called placePiece function 32 times. This doesn't mean that the content of placePiece is copied 32 times to the map trigger. There is only one placePiece in the map code. Remember. Functions are reused. It is not copied. This is not a MacroTrigger. This is a real, function.

Okay. So we discussed what functions are and how we create the placePiece function. placePiece function also calls another function named move1x1Loc, which we'll make now.

For easier writing, I will often give you the completed code and explain it, rather than writing the code one by one. Also, we will often craft functions (placePiece) requiring other incomplete functions (move1x1Loc), and later complete those functions. This is how you would create a code in a real map.

This function should move the location named 1x1, as shown in move1x1Loc(x, y); // Move location 1x1 to cell (x, y) of the chess board.. How can we move location 1x1 to cell (x, y)? You might have heard about moving locations via EUD. We're going to use that technique here. Specifically, 0x58DC60 is the address of location table. We have 255 locations here. Each location takes 20 byte space, and address of left/top/right/bottom coordinates are:

  • 0x58DC60 + (locid*20) + 0x0 : Left
  • 0x58DC60 + (locid*20) + 0x4 : Top
  • 0x58DC60 + (locid*20) + 0x8 : Right
  • 0x58DC60 + (locid*20) + 0xC : Bottom

Since the entire map's dimension is 64x64, the width and height of the map are 2048 pixels each. (64 tiles * 32 pixel/tile). So chess board is centered at pixel (1024, 1024). Each cell takes two tile, which accounts for 64 pixels. So (0, 0) cell takes places from (768, 768) to (832, 832). Modifying location coordinates to these values will move the location to the desired position. Function moving location 1x1 to (x, y) cell can be created like this.

const loc1x1 = $L("1x1");  // Get location index of "1x1" location.

/// Move 1x1 location to specific chess cell.
/// 0 <= x,y <= 7
function move1x1Loc(x, y) {
    const x0 = 768 + x * 64;
    const y0 = 768 + y * 64;
    SetMemory(0x58DC60 + 20 * loc1x1 + 0x00, SetTo, x0);
    SetMemory(0x58DC60 + 20 * loc1x1 + 0x04, SetTo, y0);
    SetMemory(0x58DC60 + 20 * loc1x1 + 0x08, SetTo, x0 + 64);
    SetMemory(0x58DC60 + 20 * loc1x1 + 0x0C, SetTo, y0 + 64);
}
  • $L(x) converts location name x to location index.
  • $T(x) converts string x to string index. (T means text)
  • $S(x) converts switch name x to switch index.
  • $U(x) converts unit name x to unit index.

What does this all mean? Let's analyze this line by line.

const loc1x1 = $L("1x1");

This means 'Set loc1x1 to be a location index of location "1x1"'. So from this point, loc1x1 holds the index of "1x1" location. Note that we need location index to move location with EUD, so we'll use this value later.

For the next line.

const x0 = 768 + x * 64;

This means that x0 now equals to 768 + x * 64. Consts are constant, so we cannot change their value. Same goes for y0.

Next, we have this line. ::

SetMemory(0x58DC60 + 20 * loc1x1 + 0x00, SetTo, x0);

This means

  • Compute 0x58DC60 + 20 * loc1x1 + 0x00. This is address of the 'left' coordinate of the '1x1' location.
  • Execute action SetMemory(0x58DC60 + 20 * loc1x1 + 0x00, SetTo, x0)

Which changes the 'left' coordinate of '1x1' location to (x, y) cell of the board. SetMemory is a shorthand of SetDeaths actions. The difference is that SetMemory takes memory address as input while SetDeaths takes (player, unit) pair to specify the memory address. Think SetMemory as an EPD SetDeaths action. The 4 SetMemory actions change the left, top, right, and bottom coordinate of 1x1 location to the appropriate value, effectively moving the location to (x, y) cell of the board.

Summing up

So here we have move1x1Loc function. We've built everything we needed. Now check out the final main.eps file.

const loc1x1 = $L("1x1");  // Get location index of "1x1" location.

/// Move 1x1 location to specific chess cell.
/// 0 <= x,y <= 7

function move1x1Loc(x, y) {
    const x0 = 768 + x * 64;
    const y0 = 768 + y * 64;
    SetMemory(0x58DC60 + 20 * loc1x1 + 0x00, SetTo, x0);
    SetMemory(0x58DC60 + 20 * loc1x1 + 0x04, SetTo, y0);
    SetMemory(0x58DC60 + 20 * loc1x1 + 0x08, SetTo, x0 + 64);
    SetMemory(0x58DC60 + 20 * loc1x1 + 0x0C, SetTo, y0 + 64);
}


function placePiece(x, y, unitType, player) {
    move1x1Loc(x, y);
    CreateUnit(1, unitType, '1x1', player);
}


function onPluginStart() {
    placePiece(0, 0, $U("Rook"),   $P7);
    placePiece(1, 0, $U("Knight"), $P7);
    placePiece(2, 0, $U("Bishop"), $P7);
    placePiece(3, 0, $U("King"),   $P7);
    placePiece(4, 0, $U("Queen"),  $P7);
    placePiece(5, 0, $U("Bishop"), $P7);
    placePiece(6, 0, $U("Knight"), $P7);
    placePiece(7, 0, $U("Rook"),   $P7);
    placePiece(0, 1, $U("Pawn"),   $P7);
    placePiece(1, 1, $U("Pawn"),   $P7);
    placePiece(2, 1, $U("Pawn"),   $P7);
    placePiece(3, 1, $U("Pawn"),   $P7);
    placePiece(4, 1, $U("Pawn"),   $P7);
    placePiece(5, 1, $U("Pawn"),   $P7);
    placePiece(6, 1, $U("Pawn"),   $P7);
    placePiece(7, 1, $U("Pawn"),   $P7);
    placePiece(0, 7, $U("Rook"),   $P8);
    placePiece(1, 7, $U("Knight"), $P8);
    placePiece(2, 7, $U("Bishop"), $P8);
    placePiece(3, 7, $U("King"),   $P8);
    placePiece(4, 7, $U("Queen"),  $P8);
    placePiece(5, 7, $U("Bishop"), $P8);
    placePiece(6, 7, $U("Knight"), $P8);
    placePiece(7, 7, $U("Rook"),   $P8);
    placePiece(0, 6, $U("Pawn"),   $P8);
    placePiece(1, 6, $U("Pawn"),   $P8);
    placePiece(2, 6, $U("Pawn"),   $P8);
    placePiece(3, 6, $U("Pawn"),   $P8);
    placePiece(4, 6, $U("Pawn"),   $P8);
    placePiece(5, 6, $U("Pawn"),   $P8);
    placePiece(6, 6, $U("Pawn"),   $P8);
    placePiece(7, 6, $U("Pawn"),   $P8);
}


function afterTriggerExec() {
    DisplayText("Hello World!");
}

Piece placed in-game

This is the end of the chapter. We have programmatically populated the chess pieces. See you again soon!