map 2021 spawns

01/21/2014 15:19 LordGragen.#1
anyone have the spawns of 2021? if yes please share will help me allot.
01/22/2014 23:34 LordGragen.#2
#bump

if anyone have the map 2021 monster spawns please share

if no one have it then the thread can be closed tomorrow.
01/22/2014 23:36 Y u k i#3
What map is that? If its a noname map, post a screenshot maybe?

Wait, thats Dis City isnt it? Thats in the TQ DB!

Here you go:

Implementation example: (DB is in the attachment

PHP Code:
        static public void Load()
        {
            
Ini rdr = new Ini("");
            foreach (
string filename in Directory.GetFiles(@"C:\Dropbox\CSDB\cq_generator\"))
            {
                rdr.FileName = filename;

                MonsterSpawn Spawn = new MonsterSpawn();
                Spawn.SpawnID = rdr.ReadUInt32("
cq_generator", "id", 0);
                Spawn.MapID = rdr.ReadUInt16("
cq_generator", "mapid", 0);
                Spawn.X = rdr.ReadUInt16("
cq_generator", "bound_x", 0);
                Spawn.Y = rdr.ReadUInt16("
cq_generator", "bound_y", 0);
                Spawn.Xc = rdr.ReadUInt16("
cq_generator", "bound_cx", 0);
                Spawn.Yc = rdr.ReadUInt16("
cq_generator", "bound_cy", 0);
                Spawn.MaxMobs = rdr.ReadUInt32("
cq_generator", "maxnpc", 0);
                Spawn.SpawnAmount = rdr.ReadUInt32("
cq_generator", "maxnpc", 0);
                Spawn.MobID = rdr.ReadUInt32("
cq_generator", "npctype", 0);
                Spawn.InstanceID = rdr.ReadUInt16("
cq_generator", "Instance", 0);

                Mobspawns.TryAdd(Spawn.SpawnID, Spawn);
            }
        }
        static public void SpawnMobs()
        {
            foreach (MonsterSpawn spawn in Mobspawns.Values)
            {
                Monster ThisMob = new Monster();
                foreach (Monster mob in Monster.xMobs.Values)
                {
                    if (mob.ID == spawn.MobID)
                    {
                        ThisMob = mob;
                        break;
                    }
                }
                if (ThisMob.ID > 0)
                {
                        for (uint i = 0; i < spawn.SpawnAmount; i++)
                        {

                            Mob M = new Mob((int)ThisMob.ID,
                                (ushort)Program.Rand.Next(spawn.X, spawn.Xc + spawn.X),
                                (ushort)Program.Rand.Next(spawn.Y, spawn.Yc + spawn.Y),
                                (ushort)spawn.MapID, (UInt32)ThisMob.Life, (UInt32)ThisMob.Life,
                                (uint)ThisMob.AttackMin, (uint)ThisMob.AttackMax, (uint)Program.Rand.Next(800000, 999999),
                                ThisMob.Name, ThisMob.Lookface, (short)ThisMob.Level, 0, 0, 0, true, (short)spawn.X, (short)spawn.Y, (short)(spawn.Xc + spawn.X), (short)(spawn.Yc + spawn.Y), 0, Element.None, spawn.InstanceID);
                            World.AllMobs.TryAdd(M.UID, M);
                            World.MapMobs[M.LocMap].TryAdd(M.UID, M);
                            World.MapEntities[M.LocMap].TryAdd(M.UID, M);
                        }
                }
            }
            Console.WriteLine("
Monsters Spawned!");
        } 
01/23/2014 00:10 LordGragen.#4
thx, wonder which one holds the 2021 XD ty
01/23/2014 01:26 Aceking#5
None of those contain the dis city spawns....

Quite helpful though, it has the 2nd rb spawns, adv zone spawns etc

What does the bound cx and bound cy values mean? They aren't co ordinates.
Does it mean the entity can't move beyond that value away from the spawn center?

Implementation is slightly off too, there is no instance field, and spawn amount should be max_per_gen.

Just for anyone who wishes to copy and paste.

Great stuff tho yuki

Actually I stand corrected, they do contain the dis city spawns.
Except they are listed as mapid 4021
01/23/2014 02:16 CptSky#6
Quote:
Originally Posted by Aceking View Post
[...] What does the bound cx and bound cy values mean? They aren't co ordinates.
Does it mean the entity can't move beyond that value away from the spawn center?

Implementation is slightly off too, there is no instance field, and spawn amount should be max_per_gen. [...]
Code:
/*
 * ****** COPS v7 Emulator - Open Source ******
 * Copyright (C) 2012 - 2014 Jean-Philippe Boivin
 *
 * Please read the WARNING, DISCLAIMER and PATENTS
 * sections in the LICENSE file.
 */

#include "log.h"
#include "generator.h"
#include "basefunc.h"
#include "mapmanager.h"
#include "gamemap.h"
#include "world.h"
#include "monster.h"
#include <QSqlQuery>
#include <QVariant>

/* static */
err_t
Generator :: makeGenerator(Generator** aOutGenerator, const QSqlQuery& aQuery)
{
    ASSERT_ERR(aOutGenerator != nullptr && *aOutGenerator == nullptr, ERROR_INVALID_POINTER);
    ASSERT_ERR(&aQuery != nullptr, ERROR_INVALID_REFERENCE);

    static MapManager& mgr = MapManager::getInstance(); // singleton...

    err_t err = ERROR_SUCCESS;

    uint32_t id = (uint32_t)aQuery.value(SQLDATA_ID).toInt();
    uint32_t mapId = (uint32_t)aQuery.value(SQLDATA_MAPID).toInt();
    GameMap* map = mgr.getMap(mapId);

    if (map != nullptr)
    {
        Generator* generator = new Generator(id, *map,
                                             (uint16_t)aQuery.value(SQLDATA_BOUND_X).toUInt(),
                                             (uint16_t)aQuery.value(SQLDATA_BOUND_Y).toUInt(),
                                             (uint16_t)aQuery.value(SQLDATA_BOUND_CX).toUInt(),
                                             (uint16_t)aQuery.value(SQLDATA_BOUND_CY).toUInt(),
                                             (uint16_t)aQuery.value(SQLDATA_MAXNPC).toUInt(),
                                             (uint16_t)aQuery.value(SQLDATA_REST_SECS).toUInt(),
                                             (uint16_t)aQuery.value(SQLDATA_MAX_PER_GEN).toUInt(),
                                             (uint32_t)aQuery.value(SQLDATA_MONSTER_TYPE).toUInt());
        *aOutGenerator = generator;
        generator = nullptr;

        SAFE_DELETE(generator);
    }
    else
    {
        LOG(WARN, "Could not find the map %u for the generator %u.",
            mapId, id);
        err = ERROR_NOT_FOUND;
    }

    return err;
}

Generator :: Generator(uint32_t aId,
                       GameMap& aMap,
                       uint16_t aBoundX, uint16_t aBoundY, uint16_t aBoundCX, uint16_t aBoundCY,
                       uint16_t aMaxNPC, uint16_t aRestSecs, uint16_t aMaxPerGen,
                       uint32_t aMonsterType)
    : mId(aId), mMonsterType(aMonsterType),
      mMap(aMap),
      mBoundX(aBoundX), mBoundY(aBoundY), mBoundCX(aBoundCX), mBoundCY(aBoundCY),
      mGrid(aMaxNPC), mRestSecs(aRestSecs), mMaxPerGen(aMaxPerGen),
      mAmount(0), mGenAmount(0), mCurGen(0),
      mMaxNPC(0), mIdxLastGen(0)
{
    mTimer.setInterval(mRestSecs + random(0, mRestSecs));

    if (mGrid < 1)
        mMaxNPC = 1;
    else
        mMaxNPC = (mBoundCX / mGrid) * (mBoundCY / mGrid);

    if (mMaxNPC < 1)
        mMaxNPC = 1;

    mIdxLastGen = random(0, mMaxNPC);
}

void
Generator :: findGenPos(uint16_t& aOutPosX, uint16_t& aOutPosY)
{
    ASSERT(&aOutPosX != nullptr && &aOutPosY != nullptr);

    aOutPosX = mBoundX;
    aOutPosY = mBoundY;
    if (mMaxNPC <= 1)
    {
        aOutPosX += random(0, mBoundCX);
        aOutPosY += random(0, mBoundCY);
    }
    else
    {
        ++mIdxLastGen;
        if (mIdxLastGen >= mMaxNPC)
            mIdxLastGen = 0;

        int32_t gridX = mBoundCX / mGrid;
        if (gridX < 0)
            gridX = 1;

        aOutPosX += mGrid * (mIdxLastGen % gridX) + random(0, mGrid);
        aOutPosY += mGrid * (mIdxLastGen / gridX) + random(0, mGrid);
    }
}

uint32_t
Generator :: generate(uint32_t aAmount)
{
    static World& world = World::getInstance(); // singleton...
    const uint32_t RANDOM_GENERATOR_SECS = 600;

    if (mGenAmount >= mMaxNPC)
        return 0;

    if (mTimer.toNextTime())
    {
        if (mRestSecs >= RANDOM_GENERATOR_SECS)
            mTimer.start(mRestSecs + random(0, mRestSecs));

        mCurGen = mMaxPerGen;
    }

    if (mCurGen <= 0)
        return 0;

    // must access map data... will do a lot of I/O if no player is on the map
    // but acceptable as it will only happens at startup
    mMap.mData.unpack(this);

    uint32_t generated = 0;
    for (uint32_t i = 0; i < aAmount; ++i)
    {
        uint16_t posX = 0, posY = 0;
        findGenPos(posX, posY);

        if (!mMap.isStandEnable(posX, posY))
        {
            posX = mBoundX + random(0, mBoundCX);
            posY = mBoundY + random(0, mBoundCY);

            if (!mMap.isStandEnable(posX, posY))
                continue;
        }

        Monster* monster = world.generateMonster(mMonsterType, this);
        if (monster != nullptr)
        {
            monster->setMapId(mMap.getUID());
            monster->setPosition(posX, posY);

            // add the monster to the map
            mMap.enterRoom(*monster);

            // TODO broadcast spawn ?
        }

        --mCurGen;
        ++mGenAmount;
        ++generated;
        if (mCurGen <= 0)
            break;
    }

    // release the resources
    mMap.mData.pack(this);

    return generated;
}
01/23/2014 03:51 Aceking#7
Quote:
Originally Posted by CptSky View Post
Code:
mMaxNPC = (mBoundCX / mGrid) * (mBoundCY / mGrid);
Just what I was looking for :)
From what I understand the values in those ini files are SERIOUSLY backwards.
But that formula is exactly what I needed.
01/23/2014 07:29 Y u k i#8
Quote:
Originally Posted by Aceking View Post
None of those contain the dis city spawns....

Quite helpful though, it has the 2nd rb spawns, adv zone spawns etc

What does the bound cx and bound cy values mean? They aren't co ordinates.
Does it mean the entity can't move beyond that value away from the spawn center?

Implementation is slightly off too, there is no instance field, and spawn amount should be max_per_gen.

Just for anyone who wishes to copy and paste.

Great stuff tho yuki

Actually I stand corrected, they do contain the dis city spawns.
Except they are listed as mapid 4021
Oh well, the instance thingy if needed for our server, but you are right, thats not in the DB I provided. Simply comment that out :3

About the "max_per_gen", well.. its just a variable name afterall. I used hybrids SQL to INI dumper so yeah.