Loop on every player in a zone [areatrigger?]

Hi. I need to implement a script that teleports all the players from a zone or something. I need to make a loop with everyplayer in it. Is this possible?

And a second question - how to implement an areatrigger in TC2? I know how to add Creature/Trigger scripts - just add them to Cmake, scriptloader and scriptname in creature_template, but no idea with AreaScripts. If someone could help me, I would be grateful.

Here is one approach:

Map* map = player->GetMap(); // get map object somehow
auto players = map->GetPlayers();
for (auto it = players.begin(); it != players.end(); ++it)
{
Player* plr = it->GetSource();
if (plr->GetZoneId() != 123)
continue;
plr->TeleportTo(mapid, x, y, z, o);
}
What is an area script?
What do you want to do exactly and more importantly when should the code be executed?

Thank you for the code.

I was trying to implement something that happens per one hour (for example two bosses are spawning). Tried with Custom Scripts (added in scriptloader and cmakelist) and tried with a file AreaScripts.cpp (or something similar - there were some scripts from instances - don’t remember now). If you could tell me where they should be added (maybe in CustomScripts - but i missed something (didn’t add a line)) - I would be thankful /emoticons/default_smile.png

What map / mapID are you trying to make a script for?

Here is one suggestion

[CODE]#include “ScriptPCH.h”

class TeleportZone : public MapScript
{
public:
TeleportZone() : MapScript(mapidhere)
{
timer = HOUR*IN_MILLISECONDS;
}

void OnUpdate(Map* map, uint32 diff) override
{
    if (diff < timer)
    {
        timer -= diff;
        return;
    }
    else
    {
        timer = HOUR*IN_MILLISECONDS;
    }

    auto players = map->GetPlayers();
    for (auto it = players.begin(); it != players.end(); ++it)
    {
        Player* plr = it->GetSource();
        if (plr->GetZoneId() != 123)
            continue;
        plr->TeleportTo(mapid, x, y, z, o);
    }
}

uint32 timer;

};

void AddSC_TeleportZone()
{
new TeleportZone();
}
[/CODE]

And this should be added in Custom & Scriptloader, right?

Yes. There is no need for a database entry - those are needed only for areatrigger, creature, gameobject, item and spell scripts. … and maybe some more but cant remember any other atm.

Thank you very much Rochet /emoticons/default_smile.png

class WSG : public MapScript
{
public:
int hordeplayers, allyplayers;
WSG() : MapScript(489)
{
hordeplayers = 0;
allyplayers = 0;
timer = HOUR*IN_MILLISECONDS;
}

void OnUpdate(Map* map, uint32 diff) override
{
	

	Map::PlayerList const& playerList = map->GetPlayers();
	for (auto it = playerList.begin(); it != playerList.end(); ++it) // zliczanie graczy
	{
		Player* plr = it->GetSource();
		if (plr->getFaction() == 67) hordeplayers++;
		else allyplayers++;
	}
	cout << endl << "HORDE " << hordeplayers << "  ALLY " << allyplayers << endl;
}

uint32 timer;

};
Something is wrong. It doesn’t refresh. I joined the BG. Console is empty

Try using WorldMapScript instead of MapScript.
If it still doesnt work, when ingame in the BG check if .gps gives you an instance ID. If it does, you probably need to use an InstanceMapScript instead.

I know WorldMapScript works at least on normal maps. InstanceMapScript seems to be used for instances, the GetInstanceScript function returns a new “AI” for each new instance.

Im unsure about how BGs function and if you can even use these scripts there.
Could be BGs and arenas are a special case for the system.
Maybe look into BattlegroundWS.cpp and header file if you cant get these things to work.

Yep, it gives Instance 110. So InstanceMapScripts<110> right?

no, just InstanceMapScript.

you use the mapid either in the constructor or then in the database. See instance_template table.
You dont use the instanceID anywhere. Instance IDs are not predefined.

Okay, it seems that this must be done via Instance, BUT I can’t assign a script to a BG map - it yells InstanceMapScript for map 489 is Invalid while server launching.
i think it’s done like this, because if there are two instances of a single bg opened, it will count everyone on both, what is wrong.

Tried to look in BG_WS, as you said, but there is everything made on a single player and dunno how to count everyone.

Maybe a trigger isn’t a bad option? Just a simple, single trigger looping every player?

Edit: Edited every BG’s code, including constructors, Update functions and onRemove.

Included std:list, I’m adding every player to it while executing PlayerAdd() or something in every BG. Working as I wanted, no idea how to make this via these maps /emoticons/default_smile.png