mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-26 06:50:06 +00:00
Grouped Mobs are gruntworkable
* Using /summonGroupW
This commit is contained in:
parent
883a1c17e6
commit
5e8b6eec6e
@ -523,6 +523,119 @@ void playersCommand(std::string full, std::vector<std::string>& args, CNSocket*
|
|||||||
ChatManager::sendServerMessage(sock, PlayerManager::getPlayerName(pair.second));
|
ChatManager::sendServerMessage(sock, PlayerManager::getPlayerName(pair.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void summonGroupWCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
||||||
|
if (args.size() < 4) {
|
||||||
|
ChatManager::sendServerMessage(sock, "/summonGroupW <leadermob> <mob> <number> [distance]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
|
||||||
|
char *rest;
|
||||||
|
int type = std::strtol(args[1].c_str(), &rest, 10);
|
||||||
|
int type2 = std::strtol(args[2].c_str(), &rest, 10);
|
||||||
|
int count = std::strtol(args[3].c_str(), &rest, 10);
|
||||||
|
int distance = 150;
|
||||||
|
if (args.size() > 4)
|
||||||
|
distance = std::strtol(args[4].c_str(), &rest, 10);
|
||||||
|
|
||||||
|
if (*rest) {
|
||||||
|
ChatManager::sendServerMessage(sock, "Invalid NPC number: " + args[1]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// permission & sanity check
|
||||||
|
if (plr == nullptr || type >= 3314 || type2 >= 3314 || count > 5)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Mob* leadNpc = nullptr;
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
int team = NPCManager::NPCData[type]["m_iTeam"];
|
||||||
|
assert(NPCManager::nextId < INT32_MAX);
|
||||||
|
|
||||||
|
|
||||||
|
#define EXTRA_HEIGHT 200
|
||||||
|
BaseNPC *npc = nullptr;
|
||||||
|
int id = NPCManager::nextId++;
|
||||||
|
|
||||||
|
int x = plr->x;
|
||||||
|
int y = plr->y;
|
||||||
|
int z = plr->z;
|
||||||
|
if (i > 0) {
|
||||||
|
int angle = 360.0f / (count-1) * (i-1);
|
||||||
|
if (count == 3)
|
||||||
|
angle = 90 + 60 * i;
|
||||||
|
|
||||||
|
angle += (plr->angle + 180) % 360;
|
||||||
|
|
||||||
|
x += -1.0f * sin(angle / 180.0f * M_PI) * distance;
|
||||||
|
y += -1.0f * cos(angle / 180.0f * M_PI) * distance;
|
||||||
|
z = plr->z;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (team == 2) {
|
||||||
|
npc = new Mob(x, y, z + EXTRA_HEIGHT, plr->instanceID, type, NPCManager::NPCData[type], id);
|
||||||
|
MobManager::Mobs[npc->appearanceData.iNPC_ID] = (Mob*)npc;
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
leadNpc->groupMember[i-1] = npc->appearanceData.iNPC_ID;
|
||||||
|
Mob* mob = MobManager::Mobs[npc->appearanceData.iNPC_ID];
|
||||||
|
mob->groupLeader = leadNpc->appearanceData.iNPC_ID;
|
||||||
|
mob->offsetX = x - plr->x;
|
||||||
|
mob->offsetY = y - plr->y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// re-enable respawning
|
||||||
|
((Mob*)npc)->summoned = false;
|
||||||
|
} else {
|
||||||
|
npc = new BaseNPC(x, y, z + EXTRA_HEIGHT, 0, plr->instanceID, type, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
npc->appearanceData.iAngle = (plr->angle + 180) % 360;
|
||||||
|
NPCManager::NPCs[npc->appearanceData.iNPC_ID] = npc;
|
||||||
|
|
||||||
|
NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, x, y, z);
|
||||||
|
|
||||||
|
// if we're in a lair, we need to spawn the NPC in both the private instance and the template
|
||||||
|
if (PLAYERID(plr->instanceID) != 0) {
|
||||||
|
id = NPCManager::nextId++;
|
||||||
|
|
||||||
|
if (team == 2) {
|
||||||
|
npc = new Mob(x, y, z + EXTRA_HEIGHT, MAPNUM(plr->instanceID), type, NPCManager::NPCData[type], id);
|
||||||
|
|
||||||
|
MobManager::Mobs[npc->appearanceData.iNPC_ID] = (Mob*)npc;
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
leadNpc->groupMember[i-1] = npc->appearanceData.iNPC_ID;
|
||||||
|
Mob* mob = MobManager::Mobs[npc->appearanceData.iNPC_ID];
|
||||||
|
mob->groupLeader = leadNpc->appearanceData.iNPC_ID;
|
||||||
|
mob->offsetX = x - plr->x;
|
||||||
|
mob->offsetY = y - plr->y;
|
||||||
|
}
|
||||||
|
|
||||||
|
((Mob*)npc)->summoned = false;
|
||||||
|
} else {
|
||||||
|
npc = new BaseNPC(x, y, z + EXTRA_HEIGHT, 0, MAPNUM(plr->instanceID), type, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
npc->appearanceData.iAngle = (plr->angle + 180) % 360;
|
||||||
|
NPCManager::NPCs[npc->appearanceData.iNPC_ID] = npc;
|
||||||
|
|
||||||
|
NPCManager::updateNPCPosition(npc->appearanceData.iNPC_ID, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatManager::sendServerMessage(sock, "/summonGroupW: placed mob with type: " + std::to_string(type) +
|
||||||
|
", id: " + std::to_string(npc->appearanceData.iNPC_ID));
|
||||||
|
TableData::RunningMobs[npc->appearanceData.iNPC_ID] = npc; // only record the one in the template
|
||||||
|
|
||||||
|
if (i == 0 && team == 2) {
|
||||||
|
type = type2;
|
||||||
|
leadNpc = MobManager::Mobs[npc->appearanceData.iNPC_ID];
|
||||||
|
leadNpc->groupLeader = leadNpc->appearanceData.iNPC_ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void flushCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
void flushCommand(std::string full, std::vector<std::string>& args, CNSocket* sock) {
|
||||||
TableData::flush();
|
TableData::flush();
|
||||||
ChatManager::sendServerMessage(sock, "Wrote gruntwork to " + settings::GRUNTWORKJSON);
|
ChatManager::sendServerMessage(sock, "Wrote gruntwork to " + settings::GRUNTWORKJSON);
|
||||||
@ -553,6 +666,7 @@ void ChatManager::init() {
|
|||||||
registerCommand("tasks", 30, tasksCommand, "list all active missions and their respective task ids.");
|
registerCommand("tasks", 30, tasksCommand, "list all active missions and their respective task ids.");
|
||||||
registerCommand("notify", 30, notifyCommand, "receive a message whenever a player joins the server");
|
registerCommand("notify", 30, notifyCommand, "receive a message whenever a player joins the server");
|
||||||
registerCommand("players", 30, playersCommand, "print all players on the server");
|
registerCommand("players", 30, playersCommand, "print all players on the server");
|
||||||
|
registerCommand("summonGroupW", 30, summonGroupWCommand, "permanently summon group NPCs");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatManager::registerCommand(std::string cmd, int requiredLevel, CommandHandler handlr, std::string help) {
|
void ChatManager::registerCommand(std::string cmd, int requiredLevel, CommandHandler handlr, std::string help) {
|
||||||
|
@ -641,6 +641,8 @@ void TableData::loadGruntwork(int32_t *nextId) {
|
|||||||
|
|
||||||
// mobs
|
// mobs
|
||||||
auto mobs = gruntwork["mobs"];
|
auto mobs = gruntwork["mobs"];
|
||||||
|
int leaderMob = -1;
|
||||||
|
int leaderMobFollowers = 0;
|
||||||
for (auto _mob = mobs.begin(); _mob != mobs.end(); _mob++) {
|
for (auto _mob = mobs.begin(); _mob != mobs.end(); _mob++) {
|
||||||
auto mob = _mob.value();
|
auto mob = _mob.value();
|
||||||
BaseNPC *npc;
|
BaseNPC *npc;
|
||||||
@ -655,6 +657,37 @@ void TableData::loadGruntwork(int32_t *nextId) {
|
|||||||
((Mob*)npc)->summoned = false;
|
((Mob*)npc)->summoned = false;
|
||||||
|
|
||||||
MobManager::Mobs[npc->appearanceData.iNPC_ID] = (Mob*)npc;
|
MobManager::Mobs[npc->appearanceData.iNPC_ID] = (Mob*)npc;
|
||||||
|
|
||||||
|
// handling groups
|
||||||
|
if (mob.find("iOffsetX") != mob.end() && MobManager::Mobs.find(id) != MobManager::Mobs.end()) {
|
||||||
|
Mob* currNpc = MobManager::Mobs[id];
|
||||||
|
|
||||||
|
if (leaderMob == -1) {
|
||||||
|
if (MobManager::Mobs.find(id-1) != MobManager::Mobs.end()) {
|
||||||
|
Mob* leadNpc = MobManager::Mobs[id-1];
|
||||||
|
leaderMob = id-1;
|
||||||
|
leadNpc->groupMember[leaderMobFollowers] = id;
|
||||||
|
leaderMobFollowers++;
|
||||||
|
currNpc->groupLeader = id-1;
|
||||||
|
leadNpc->groupLeader = id-1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (MobManager::Mobs.find(leaderMob) != MobManager::Mobs.end()) {
|
||||||
|
Mob* leadNpc = MobManager::Mobs[leaderMob];
|
||||||
|
leaderMob = leaderMob;
|
||||||
|
leadNpc->groupMember[leaderMobFollowers] = id;
|
||||||
|
leaderMobFollowers++;
|
||||||
|
currNpc->groupLeader = leaderMob;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currNpc->offsetX = (int)mob["iOffsetX"];
|
||||||
|
currNpc->offsetY = mob.find("iOffsetY") == mob.end() ? 0 : (int)mob["iOffsetY"];
|
||||||
|
} else {
|
||||||
|
leaderMob = -1;
|
||||||
|
leaderMobFollowers = 0;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
npc = new BaseNPC(mob["iX"], mob["iY"], mob["iZ"], mob["iAngle"], instanceID, mob["iNPCType"], id);
|
npc = new BaseNPC(mob["iX"], mob["iY"], mob["iZ"], mob["iAngle"], instanceID, mob["iNPCType"], id);
|
||||||
}
|
}
|
||||||
@ -737,12 +770,19 @@ void TableData::flush() {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
int x, y, z, hp;
|
int x, y, z, hp;
|
||||||
|
int offsetX = 0;
|
||||||
|
int offsetY = 0;
|
||||||
if (npc->npcClass == NPC_MOB) {
|
if (npc->npcClass == NPC_MOB) {
|
||||||
Mob *m = (Mob*)npc;
|
Mob *m = (Mob*)npc;
|
||||||
x = m->spawnX;
|
x = m->spawnX;
|
||||||
y = m->spawnY;
|
y = m->spawnY;
|
||||||
z = m->spawnZ;
|
z = m->spawnZ;
|
||||||
hp = m->maxHealth;
|
hp = m->maxHealth;
|
||||||
|
// handling groups
|
||||||
|
if (m->groupLeader != 0 && m->groupLeader != m->appearanceData.iNPC_ID) {
|
||||||
|
offsetX = m->offsetX;
|
||||||
|
offsetY = m->offsetY;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
x = npc->appearanceData.iX;
|
x = npc->appearanceData.iX;
|
||||||
y = npc->appearanceData.iY;
|
y = npc->appearanceData.iY;
|
||||||
@ -760,6 +800,12 @@ void TableData::flush() {
|
|||||||
// this is a bit imperfect, since this is a live angle, not a spawn angle so it'll change often, but eh
|
// this is a bit imperfect, since this is a live angle, not a spawn angle so it'll change often, but eh
|
||||||
mob["iAngle"] = npc->appearanceData.iAngle;
|
mob["iAngle"] = npc->appearanceData.iAngle;
|
||||||
|
|
||||||
|
// there is an assumption that group mobs will never have an offset of (0,0)
|
||||||
|
if (offsetX != 0 || offsetY != 0) {
|
||||||
|
mob["iOffsetX"] = offsetX;
|
||||||
|
mob["iOffsetY"] = offsetY;
|
||||||
|
}
|
||||||
|
|
||||||
// it's called mobs, but really it's everything
|
// it's called mobs, but really it's everything
|
||||||
gruntwork["mobs"].push_back(mob);
|
gruntwork["mobs"].push_back(mob);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user