//@ignore_object_type

int EnableMemoryReadWriteFunction(int t)
{
	int addr = 0x97974c;
	int arr[29];

	arr[0] = 0x1090BE56; arr[1] = 0x06C70075; arr[2] = 0x50725068; arr[3] = 0x000446C7;
	arr[4] = 0xC7723068; arr[5] = 0x00500846; arr[6] = 0x46C754FF; arr[7] = 0xFF04240C;
	arr[8] = 0x1046C730; arr[9] = 0x042454FF; arr[10] = 0x831446C7; arr[11] = 0xC7310CC4;
	arr[12] = 0xC3C01846; arr[13] = 0x46C79090; arr[14] = 0x5068561C; arr[15] = 0x2046C772;
	arr[16] = 0x14FF0050; arr[17] = 0x242446C7; arr[18] = 0xC7FFF08B; arr[19] = 0x24142846;
	arr[20] = 0x46C73089; arr[21] = 0x04C4832C; arr[22] = 0x3046C75E; arr[23] = 0x909090C3;
	arr[24] = 0x33703589; arr[25] = 0x05C7005C; arr[26] = 0x005C31F0; arr[27] = 0x007510ac;
	arr[28] = 0x9090C35E; 
	//0xed9af
	return GetScore(t);
}

int ImportUnitToPtrFunc()
{
    int arr[10], ptr, link;
    if (!arr[0])
    {
        arr[0] = 0x50725068; arr[1] = 0x2414FF00; arr[2] = 0x511B6068; arr[3] = 0x54FF5000; arr[4] = 0xC4830424;
        arr[5] = 0x7230680C; arr[6] = 0xFF500050; arr[7] = 0x83042454; arr[8] = 0xC03108C4; arr[9] = 0x909090C3; 
        ptr = CreateObject("AmbBeachBirds", 1);
        Raise(ptr, ImportUnitToPtrFunc);
        link = GetMemory(GetMemory(0x75ae28) + (0x30 * ToInt(GetObjectZ(ptr)) + 0x1c));
        Delete(ptr);
    }
    return link;
}

int UnitToPtr(int unit)
{
    int temp = GetMemory(0x5c336c), res;
    SetMemory(0x5c336c, ImportUnitToPtrFunc());
    res = Unknownb8(unit);
    SetMemory(0x5c336c, temp);
	return res;
}

void CharToWideChar(string x)
{
    int ptr = GetMemory(0x97bb40 + (4 * SToInt(x))), dump = 0x751030, arr[2], read, sh = 0xff, end = 0;

    while (1)
    {
        read = GetMemory(ptr);
        if (!(read & 0xff) || !((read >> 8) &0xff) || !((read >> 16) &0xff) || !((read >> 24) &0xff))
            end = 1;
        arr[0] = (read & sh) | (((read >> 8) & sh) << 16);
        arr[1] = ((read >> 16) & sh) | (((read >> 24) & sh) << 16);
        SetMemory(dump, arr[0]);
        SetMemory(dump + 4, arr[1]);
        dump += 8;
        ptr += 4;
        if (end)
            break;
    }
    SetMemory(dump, 0);
}

void UploadConsoleParse()
{
    int arr[7], ptr, link;

    if (!ptr)
    {
        arr[0] = 0;
        arr[1] = 0x443c8068; arr[2] = 0x68016a00; arr[3] = 0x751030; arr[4] = 0x82454ff;
        arr[5] = 0x310cc483; arr[6] = 0x90c3c0;
        ptr = CreateObject("InvisibleLightBlueHigh", 1);
        Raise(ptr, UploadConsoleParse);
        link = GetMemory(GetMemory(0x75ae28) + (0x30 * ToInt(GetObjectZ(ptr)) + 0x1c));
        Delete(ptr);
    }
    SetMemory(0x5c31cc, link + 4);
}

void CmdLine(string x)
{
    CharToWideChar(x);
    UploadConsoleParse();
    Unused50();
    SetMemory(0x5c31cc, 0x513c60);
}

int ToInt(float x)
{
    StopScript(x);
}

float ToFloat(int x)
{
    StopScript(x);
}

int SToInt(string x)
{
    StopScript(x);
}

string ToStr(int x)
{
    StopScript(x);
}

int GetMemory(int addr)
{
    return Unknownb9(addr);
}

void SetMemory(int addr, int value)
{
    Unused59(addr, value);
}

void SetUnitMass(int unit, float ms)
{
    int ptr = UnitToPtr(unit);

    if (ptr)
        SetMemory(ptr + 0x78, ToInt(ms));
}

int LightObelisk(float x, float y)
{
    int unit;

    MoveWaypoint(1, x, y);
    unit = CreateObject("BomberGenerator", 1);
    ObjectOff(unit);
    Enchant(unit, "ENCHANT_INVULNERABLE", 0.0);
    SetUnitMass(unit, 4.0);
    return unit;
}

void SetUnitMaxHealth(int unit, int amount)
{
    int ptr = UnitToPtr(unit);

    if (ptr)
    {
        SetMemory(GetMemory(ptr + 0x22c), amount);
        SetMemory(GetMemory(ptr + 0x22c) + 0x4, amount);
    }
}

int WeaponPower(int num)
{
    int addr[6];

    if (!addr[0])
    {
        addr[0] = 0x5a00a4; addr[1] = 0x5BA714; addr[2] = 0x5BA72C; addr[3] = 0x5BA744; addr[4] = 0x5BA75C; addr[5] = 0x5BA774;
        return 0;
    }
    return GetMemory(addr[num]);
}

int ArmorQuality(int num)
{
    int addr[6];

    if (!addr[0])
    {
        addr[0] = 0x5a00a4; addr[1] = 0x5BA7A4; addr[2] = 0x5BA7BC; addr[3] = 0x5BA7D4; addr[4] = 0x5BA7EC; addr[5] = 0x5BA804;
        return 0;
    }
    return GetMemory(addr[num]);
}

int MaterialList(int num)
{
    int addr[6];

    if (!addr[0])
    {
        //Lv.3 ~ 7, null
        addr[0] = 0x5a00a4; addr[1] = 0x5ba834; addr[2] = 0x5ba84c; addr[3] = 0x5ba864; addr[4] = 0x5ba87c; addr[5] = 0x5ba894;
        return 0;
    }
    return GetMemory(addr[num]);
}

int WeaponEffect(int num)
{
    int addr[37];

    if (!addr[0])
    {
        addr[0] = 0x5a00a4;
        addr[1] = 0x5BA1BC; addr[2] = 0x5BA1D4; addr[3] = 0x5BA1EC; addr[4] = 0x5BA204; addr[5] = 0x5BA21C; addr[6] = 0x5BA234; addr[7] = 0x5BA24C; addr[8] = 0x5BA264;
        addr[9] = 0x5BA27C; addr[10] = 0x5BA294; addr[11] = 0x5BA2AC; addr[12] = 0x5BA2C4; addr[13] = 0x5BA2DC; addr[14] = 0x5BA2F4; addr[15] = 0x5BA30C; addr[16] = 0x5BA324;
        addr[17] = 0x5BA33C; addr[18] = 0x5BA354; addr[19] = 0x5BA36C; addr[20] = 0x5BA384; addr[21] = 0x5BA39C; addr[22] = 0x5BA3B4; addr[23] = 0x5BA3CC; addr[24] = 0x5BA3E4;
        addr[25] = 0x5BA3FC; addr[26] = 0x5BA414; addr[27] = 0x5BA42C; addr[28] = 0x5BA444;
        addr[29] = 0x5BA63C; addr[30] = 0x5BA654; addr[31] = 0x5BA66C; addr[32] = 0x5BA684;
        addr[33] = 0x5BA69C; addr[34] = 0x5BA6B4; addr[35] = 0x5BA6CC; addr[36] = 0x5BA6E4;
        return 0;
    }
    return GetMemory(addr[num]);
}

int ArmorEffect(int num)
{
    int addr[21];

    if (!addr[0])
    {
        addr[0] = 0x5a00a4;
        addr[1] = 0x5BA45C; addr[2] = 0x5BA474; addr[3] = 0x5BA48C; addr[4] = 0x5BA4A4; addr[5] = 0x5BA4BC; addr[6] = 0x5BA4D4; addr[7] = 0x5BA4EC; addr[8] = 0x5BA504;
        addr[9] = 0x5BA51C; addr[10] = 0x5BA534; addr[11] = 0x5BA54C; addr[12] = 0x5BA564; addr[13] = 0x5BA57C; addr[14] = 0x5BA594; addr[15] = 0x5BA5AC; addr[16] = 0x5BA5C4;
        addr[17] = 0x5BA5DC; addr[18] = 0x5BA5F4; addr[19] = 0x5BA60C; addr[20] = 0x5BA624;
        return 0;
    }
    return GetMemory(addr[num]);
}

void SetWeaponProperties(int unit, int power, int mt_lv, int wfx1, int wfx2)
{
    int k, ptr = UnitToPtr(unit);

    if (ptr)
    {
        SetMemory(GetMemory(ptr + 0x2b4), WeaponPower(power));
        SetMemory(GetMemory(ptr + 0x2b4) + 4, MaterialList(mt_lv));
        SetMemory(GetMemory(ptr + 0x2b4) + 8, WeaponEffect(wfx1));
        SetMemory(GetMemory(ptr + 0x2b4) + 12, WeaponEffect(wfx2));
        for (k = 31 ; k >= 0 ; k --)
            SetMemory(ptr + 0x230 + (k * 4), 0x200);
    }
}

void SetArmorProperties(int unit, int qual, int mt_lv, int afx1, int afx2)
{
    int k, ptr = UnitToPtr(unit);

    SetMemory(GetMemory(ptr + 0x2b4), ArmorQuality(qual));
    SetMemory(GetMemory(ptr + 0x2b4) + 4, MaterialList(mt_lv));
    SetMemory(GetMemory(ptr + 0x2b4) + 8, ArmorEffect(afx1));
    SetMemory(GetMemory(ptr + 0x2b4) + 12, ArmorEffect(afx2));
    for (k = 31 ; k >= 0 ; k --)
        SetMemory(ptr + 0x230 + (k * 4), 0x200);
}

int CreateRandomWeapon(float x, float y)
{
    string name = {"WarHammer", "GreatSword", "Sword", "Quiver", "Bow", "BattleAxe", "StaffWooden", "Longsword"};
    int unit;

    MoveWaypoint(1, x, y);
    unit = CreateObject(ToStr(SToInt(name) + Random(0, 7)), 1);
    SetWeaponProperties(unit, Random(0, 5), Random(0, 5), Random(0, 36), Random(0, 36));
    return unit;
}

int CreateRandomArmor(float x, float y)
{
    string name = {"OrnateHelm", "Breastplate", "PlateArms", "PlateBoots", "PlateLeggings", "ConjurerHelm", "LeatherArmbands",
    "LeatherArmor", "LeatherArmoredBoots", "LeatherLeggings"};
    int unit;

    MoveWaypoint(1, x, y);
    unit = CreateObject(ToStr(SToInt(name) + Random(0, 9)), 1);
    SetArmorProperties(unit, Random(0, 5), Random(0, 5), Random(0, 20), Random(0, 20));
    return unit;
}

void InitInvPropertiesSet()
{
    WeaponEffect(0);
    ArmorEffect(0);
    WeaponPower(0);
    ArmorQuality(0);
    MaterialList(0);
}

void SetUnitSpeed(int unit, float amount)
{
    int ptr = UnitToPtr(unit);

    if (ptr)
        SetMemory(ptr + 0x224, ToInt(amount));
}

void DisplayBroadMessage()
{
    CmdLine("broadcast Hello World! +_+!!");
}

void SpawnLightObelisk()
{
    LightObelisk(GetObjectX(other), GetObjectY(other));
}

void SpawnMovingPlant()
{
    int unit;
    MoveWaypoint(1, GetObjectX(other), GetObjectY(other));
    unit = CreateObject("CarnivorousPlant", 1);

    SetUnitMaxHealth(unit, 600);
    SetUnitSpeed(unit, 1.5);
    AggressionLevel(unit, 1.0);
    RetreatLevel(unit, 0.0);
}

void SpawnRandomWeapon()
{
    int unit = CreateRandomWeapon(GetObjectX(other), GetObjectY(other));
}

void SpawnRandomArmor()
{
    int unit = CreateRandomArmor(GetObjectX(other), GetObjectY(other));
}

void MapInitialize()
{
    int t = EnableMemoryReadWriteFunction(0);

    ImportUnitToPtrFunc();
    UploadConsoleParse();
    FrameTimer(1, InitInvPropertiesSet);
}