From f5f220fdf3ca07d631462d97c837e86848e46563 Mon Sep 17 00:00:00 2001
From: acsvln <acsvln@disroot.org>
Date: Sun, 1 Jul 2018 13:59:55 +0300
Subject: Implemented commands "hugo" and "linus"

---
 src/emap/atcommand.c         | 100 +++++++++++++++++++++++++++++++++++++++++++
 src/emap/atcommand.h         |   8 ++++
 src/emap/data/session.c      |   1 +
 src/emap/init.c              |   2 +
 src/emap/struct/sessionext.h |   1 +
 5 files changed, 112 insertions(+)

(limited to 'src')

diff --git a/src/emap/atcommand.c b/src/emap/atcommand.c
index f10a012..e37a320 100644
--- a/src/emap/atcommand.c
+++ b/src/emap/atcommand.c
@@ -24,6 +24,8 @@
 #include "emap/atcommand.h"
 #include "emap/lang.h"
 #include "emap/inter.h"
+#include "emap/struct/sessionext.h"
+#include "emap/data/session.h"
 
 const char* eatcommand_msgsd_pre(struct map_session_data **sdPtr,
                                  int *msgPtr)
@@ -66,6 +68,94 @@ const char* eatcommand_msgfd_pre(int *fdPtr,
     return lang_pctrans(atcommand->msg_table[0][msg_number], sd);
 }
 
+bool jump_iterate(struct map_session_data *sd, bool forward)
+{
+    struct SessionExt *session_ext = session_get_bysd(sd);
+
+    if (!session_ext)
+        return false;
+
+    struct map_session_data *pl_sd = map->id2sd(session_ext->jump_iterate_id);
+    struct map_session_data *buff_sd = NULL;
+
+    bool has_next = false;
+    int fd = NULL != pl_sd ? pl_sd->fd : sd->fd;
+    int user_count = map->getusers();
+
+    if (user_count == 1)
+    {
+        session_ext->jump_iterate_id = 0;
+        clif->message(sd->fd, "You are alone at map server!");
+        return true;
+    }
+
+    int max_counter = sockt->fd_max;
+
+    do
+    {
+        if (forward)
+        {
+            fd++;
+            has_next = fd < sockt->fd_max;
+        }
+        else
+        {
+            fd--;
+            has_next = fd > 0;
+        }
+
+        if (!has_next)
+        {
+            fd = (forward ? -1 : sockt->fd_max + 1);
+        }
+        else
+        {
+            if (sockt->session_is_active(fd))
+            {
+                buff_sd = sockt->session[fd]->session_data;
+
+                if (NULL != buff_sd)
+                {
+                    if (
+                        (sd == buff_sd) ||
+                        (map->list[buff_sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE))
+                       )
+                    {
+                        buff_sd = NULL;
+                    } 
+                    else if (sd->bl.m == buff_sd->bl.m && sd->bl.x == buff_sd->bl.x && sd->bl.y == buff_sd->bl.y)
+                    {
+                        if (user_count == 2) {
+                            return true;
+                        }
+
+                        buff_sd = NULL;
+                    }
+                }
+            }
+        }
+
+        --max_counter;
+    } while (NULL == buff_sd && (max_counter >= 0));
+
+    if (NULL != buff_sd)
+    {
+        char message[80];
+
+        pc->setpos(sd, buff_sd->mapindex, buff_sd->bl.x, buff_sd->bl.y, CLR_TELEPORT);
+
+        sprintf (message, "Jump to %s", buff_sd->status.name);
+
+        clif->message(sd->fd, message);
+
+        session_ext->jump_iterate_id = buff_sd->bl.id;
+
+        return true;
+    }
+
+    return false;
+}
+
 ACMD2(setSkill)
 {
     int skill_id = 0;
@@ -131,6 +221,16 @@ ACMD2(slide)
     return true;
 }
 
+ACMD3(hugo)
+{
+    return jump_iterate(sd, true);
+}
+
+ACMD3(linus)
+{
+    return jump_iterate(sd, false);
+}
+
 ACMD1(mapExit)
 {
     int code = 1;
diff --git a/src/emap/atcommand.h b/src/emap/atcommand.h
index 95e7e75..24e4a4c 100644
--- a/src/emap/atcommand.h
+++ b/src/emap/atcommand.h
@@ -18,10 +18,18 @@ const char* eatcommand_msgfd_pre(int *fdPtr,
     const char* command __attribute__ ((unused)), \
     const char* message, \
     struct AtCommandInfo *info)
+#define ACMD3(x) bool atcommand_ ## x (const int fd __attribute__ ((unused)), \
+    struct map_session_data* sd, \
+    const char* command __attribute__ ((unused)), \
+    const char* message __attribute__ ((unused)), \
+    struct AtCommandInfo *info __attribute__ ((unused)))
 
 ACMD2(setSkill);
 ACMD2(slide);
+ACMD3(hugo);
+ACMD3(linus);
 ACMD1(mapExit);
 ACMD1(serverExit);
 
+
 #endif  // EVOL_MAP_ATCOMMAND
diff --git a/src/emap/data/session.c b/src/emap/data/session.c
index 33ddb41..40ad696 100644
--- a/src/emap/data/session.c
+++ b/src/emap/data/session.c
@@ -50,5 +50,6 @@ struct SessionExt *session_create(void)
     data->onlinelistlasttime = 0;
     data->teamId = 0;
     data->mount = 0;
+    data->jump_iterate_id = 0;
     return data;
 }
diff --git a/src/emap/init.c b/src/emap/init.c
index 2ef06ca..ed1739c 100644
--- a/src/emap/init.c
+++ b/src/emap/init.c
@@ -101,6 +101,8 @@ HPExport void plugin_init (void)
     addAtcommand("slide", slide);
     addAtcommand("mapexit", mapExit);
     addAtcommand("serverexit", serverExit);
+    addAtcommand("hugo", hugo);
+    addAtcommand("linus", linus);
 
     addCPCommand("serverexit", serverExit);
 
diff --git a/src/emap/struct/sessionext.h b/src/emap/struct/sessionext.h
index 89cf163..b7ab4c8 100644
--- a/src/emap/struct/sessionext.h
+++ b/src/emap/struct/sessionext.h
@@ -12,6 +12,7 @@ struct SessionExt
     int teamId;
     uint16 mount;
     uint8 state;
+    int jump_iterate_id;
 };
 
 #endif  // EVOL_MAP_SESSIONEXT
-- 
cgit v1.2.3-70-g09d2