Pull to refresh

Расширяем функционал Monopoly City Streets

Reading time13 min
Views506
Разработчиками в MCS, к сожалению, не предусмотрена возможность застройки улицы большим количеством зданий за пару кликов мышкой. Но ведь игра написана на JS, так что ничего нам не мешает написать небольшой букмарклет, который и позволит нам добавить требуемый функционал.

Весь код MCS находится в файле monopoly.1255614067.js. Если посмотреть firebug'ом, что происходит в процессе покупки здания — мы увидим, что используются 2 функции — MCS.BUILD.showLocations() [для отображения маркеров доступных мест] и MCS.BUILD.buyBuilding() [для, собственно, покупки здания]. После размышлений у меня получился следующий код:
if (typeof MCS == "undefined") {
    alert('Букмарклет нужно вызывать только на странице монополии');
    throw '';
}   
var buildingType = null;
var player = MCS.getPlayerData();
if (player == null) {
    alert('Перед вызовом необходимо авторизоваться');
    throw '';
}
var streetId = MCS.STREET.getStreetData().id;
var streetData = MCS.STREET.getStreetData().data;
if (streetId == null) {
    alert('Перед вызовом необходимо выбрать улицу');
    throw '';
} else if (streetData.o != player.nickname) {
    alert('Перед вызовом необходимо выбрать свою улицу');
    throw '';
}
var locations = new Array();
var builtCnt = 0;
var buildLimit = 0;
function buy() {
    if (builtCnt < buildLimit) {
        buyBuilding(locations[0]);
        MCS.STATUSBAR.redraw();
        getLocations();
        setTimeout(buy, 250);
    } else {
        done();
    }
}
function done()
{
    MCS.STREET.show(streetId, null, false, false);
    MCS.LOADING.hide();
    alert('Построено зданий: ' + builtCnt + 'шт.');
}
function getLocations()
{
    locations = new Array();
    $.ajax({
        url: "/build/getlocations",
        cache: false,
        data: {
            id: streetId,
            type: buildingType
        },
        dataType: "json",
        async: false,
        success: function (data, status) {
            $.each(data, function (foo, point) {
                if (point) {
                    locations.push(foo);
                }
            });
        }
    });
}
function buyBuilding(location)
{
    $.ajax({
        url: "/negotiate/buybuilding",
        type: "post",
        data: {
            nickname: player.nickname,
            hash: player.hash,
            id: streetId,
            type: buildingType,
            loc: location
        },
        dataType: "json",
        async: false,
        success: function (data, status) {
            player.balance -= MCS.buildings[buildingType].price;
            builtCnt++;
        }
    });
    MCS.TRACK.view({
        page: "build",
        section: "build",
        street: streetData.n,
        country: streetData.cy,
        region: streetData.re,
        building_type: buildingType,
        activity: "build property",
        value: MCS.buildings[buildingType].price
    });
}
buildingType = prompt('Введите идентификатор здания. Список доступных типов можно узнать введя "?"', '?');
if (buildingType != null) {
    if (buildingType == '?') {
        var string = '';
        for (in MCS.buildings) {
            if (!isNaN(MCS.buildings[i].effect)) {
                string = string + "Идентификатор: " + i + ", наименование: " + MCS.LANG.building["building"+i] + ", стоимость: " + MCS.buildings[i].price*1000 + "\n";
            }
        }
        alert(string);
    } else if (typeof MCS.buildings[buildingType] == "undefined" || isNaN(MCS.buildings[buildingType].effect)) {
        alert("Указан некорректный идентификатор");
    } else {
        var count = Math.floor(player.balance / MCS.buildings[buildingType].price);
        if (count > 0) {
            getLocations();
            var minCnt = Math.min(count, locations.length);
            if (minCnt == 0) {
                alert('На улице нет места под здания такого типа');
            } else {
                buildLimit = minCnt;
                if (!confirm('Сейчас попытаемся понастроить домов в количестве ' + minCnt + 'шт. Если хотите изменить предел (только в меньшую сторону) - нажмите "отмена"')) {
                    buildLimit = prompt('Сколько зданий пытаться строить?', minCnt);
                    if (buildLimit == null) {
                        throw '';
                    }
                    if (isNaN(buildLimit) || buildLimit > minCnt || buildLimit < 0) {
                        alert('Некорректное значение');
                        throw '';
                    }
                }
                MCS.LOADING.show();
                setTimeout(buy, 250);
            }
        } else {
            alert('У вас недостаточно средств для строительства этого здания');
        }
    }
}
подсветка кода: highlight.hohli.com

Перед началом работы скрипт проводит несколько проверок: наличие класса MCS (в противном случае мы точно не на сайте игры), наличие авторизации у пользователя, а так же проверяется текущая выделенная улица. Далее выдаётся запрос для выяснения типа здания — список последних берётся из кода игры. Проверяется наличие денег у игрока и наличие свободных мест на улице. Затем выясняем количество домов для постройки и приступаем к этому увлекательному занятию. Чтобы пользователь не скучал — не забываем отобразить «песочные часы» в верхней панели. И, наконец, выводится количество построенных домов.

Чтобы преобразовать этот скрипт в 1 строку — используем javascriptcompressor.com, в результате у нас почти есть букмарклет — остаётся только добавить 'javascript:' в начало полученной строки.

Готовый текст букмарклета на пастебине: pastebin.mozilla.org/678433

P.S. В качестве бонуса — букмарклет для отображения стоимости текущей улицы без зданий: javascript:if(typeof MCS != "undefined"&&MCS.STREET.getStreetData().data)alert(MCS.STREET.getStreetData().data.p*1000);

UPD Букмарклет для пакетного удаления зданий:
if (typeof MCS == "undefined") {
    alert('Букмарклет нужно вызывать только на странице монополии');
    throw '';
}   
var buildingType = null;
var player = MCS.getPlayerData();
if (player == null) {
    alert('Перед вызовом необходимо авторизоваться');
    throw '';
}
var streetId = MCS.STREET.getStreetData().id;
var streetData = MCS.STREET.getStreetData().data;
if (streetId == null) {
    alert('Перед вызовом необходимо выбрать улицу');
    throw '';
} else if (streetData.o != player.nickname) {
    alert('Перед вызовом необходимо выбрать свою улицу');
    throw '';
}
function demolish() {
    if (removedCnt < removeCnt && buildingList.length) {
        $.ajax({
            url: "/negotiate/demolishbuilding",
            type: "post",
            data: {
                nickname: player.nickname,
                hash: player.hash,
                id: streetId,
                bid: buildingList.shift()
            },
            dataType: "json",
            async: false,
            success: function () {
                MCS.getPlayerData().balance += parseInt(MCS.buildings[removeMe].price / 2);
            }
        });
        removedCnt++;
        setTimeout(demolish, 500);
    } else {
        done();
    }
}
function done()
{
    MCS.STREET.show(streetId, null, false, false);
    MCS.LOADING.hide();
}
var buildingTypes = new Array();
var str = '';
var i;
for (in streetData.b) {
    if (!isNaN(MCS.buildings[streetData.b[i].t].effect)) {
        if (typeof buildingTypes[streetData.b[i].t] == "undefined") {
            buildingTypes[streetData.b[i].t] = new Array();
            buildingTypes[streetData.b[i].t]['name'] = MCS.LANG.building["building"+streetData.b[i].t];
            buildingTypes[streetData.b[i].t]['count'] = 1;
        } else {
            buildingTypes[streetData.b[i].t]['count']++;
        }
    }
}
if (buildingTypes.length == 0) {
    alert('На выбранной улице нет доступных для сноса зданий');
    throw '';
}
for (in buildingTypes) {
    str = str + "Идентификатор: " + i + ", наименование: " + buildingTypes[i]['name'] + ", количество: " + buildingTypes[i]['count'] + "шт." + "\n";
}
var removeMe = prompt("Введите идентификатор здания для сноса. Список зданий на улице:\n" + str);
var buildingList = new Array();
if (removeMe != null) {
    if (typeof buildingTypes[removeMe] == 'undefined') {
        alert('Указан некорректный тип зданий');
        throw '';
    }
    var removeCnt = buildingTypes[removeMe]['count'];
    var removedCnt = 0;
    if (!confirm('Будет предпринята попытка сноса зданий в количестве ' + removeCnt + 'шт. Если хотите изменить количество (только в меньшую сторону) - нажмите "отмена"')) {
        removeCnt = prompt('Введите количество домов для сноса');
        if (removeCnt == null) {
            throw '';
        }
        if (isNaN(removeCnt) || removeCnt > buildingTypes[removeMe]['count'] || removeCnt < 0) {
            alert('Некорректное значение');
            throw '';
        }
    }
    MCS.LOADING.show();
    for (in streetData.b) {
        if (streetData.b[i].t == removeMe && removedCnt < removeCnt) {
            buildingList.push(i);
        }
    }
    setTimeout(demolish, 250);
}

pastebin.mozilla.org/678730
Tags:
Hubs:
+4
Comments23

Articles

Change theme settings