From 9537c3f0086c8985d84eb0fa5823e8be185beada Mon Sep 17 00:00:00 2001
From: Fate <fate-tmw@googlemail.com>
Date: Fri, 12 Dec 2008 12:23:58 -0700
Subject: Added @hugo and @linus commands for iterating over logged-in players

---
 src/map/atcommand.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/map/atcommand.h |  4 +++
 src/map/map.c       | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/map/map.h       |  5 ++++
 src/map/pc.h        |  1 +
 5 files changed, 146 insertions(+), 2 deletions(-)

diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index d10139f..37ba1e6 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -222,6 +222,8 @@ ATCOMMAND_FUNC(log); // [Fate]
 ATCOMMAND_FUNC(tee); // [Fate]
 ATCOMMAND_FUNC(invisible); // [Fate]
 ATCOMMAND_FUNC(visible); // [Fate]
+ATCOMMAND_FUNC(iterate_forward_over_players); // [Fate]
+ATCOMMAND_FUNC(iterate_backwards_over_players); // [Fate]
 
 #ifndef TXT_ONLY
 ATCOMMAND_FUNC(checkmail); // [Valaris]
@@ -473,8 +475,10 @@ static AtCommandInfo atcommand_info[] = {
         { AtCommand_Log, "@l", 60, atcommand_log }, // [Fate]
         { AtCommand_Tee, "@tee", 60, atcommand_tee }, // [Fate]
         { AtCommand_Tee, "@t", 60, atcommand_tee }, // [Fate]
-        { AtCommand_Tee, "@invisible", 60, atcommand_invisible }, // [Fate]
-        { AtCommand_Tee, "@visible", 60, atcommand_visible }, // [Fate]
+        { AtCommand_Invisible, "@invisible", 60, atcommand_invisible }, // [Fate]
+        { AtCommand_Visible, "@visible", 60, atcommand_visible }, // [Fate]
+        { AtCommand_IterateForward, "@hugo", 60, atcommand_iterate_forward_over_players }, // [Fate]
+        { AtCommand_IterateBackward, "@linus", 60, atcommand_iterate_backwards_over_players }, // [Fate]
 
 #ifndef TXT_ONLY // sql-only commands
 	{ AtCommand_CheckMail,		 "@checkmail",	      1, atcommand_listmail }, // [Valaris]
@@ -8058,3 +8062,65 @@ atcommand_visible(const int fd, struct map_session_data* sd,
         return 0;
 }
 
+
+
+int atcommand_jump_iterate(
+	const int fd, struct map_session_data* sd,
+	const char* command, const char* message,
+        struct map_session_data *(*get_start)(),
+        struct map_session_data *(*get_next)(struct map_session_data *current)
+    )
+{
+	char output[200];
+	struct map_session_data *pl_sd;
+
+	memset(output, '\0', sizeof(output));
+
+        pl_sd = map_id2bl(sd->followtarget);
+
+        if (pl_sd)
+                pl_sd = get_next(pl_sd);
+
+        if (!pl_sd)
+                pl_sd = get_start();
+
+        if (pl_sd == sd) {
+                pl_sd = get_next(pl_sd);
+                if (!pl_sd)
+                        pl_sd = get_start();
+        }
+
+        if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarpto && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
+                clif_displaymessage(fd, "You are not authorised to warp you to the map of this player.");
+                return -1;
+        }
+        if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && battle_config.any_warp_GM_min_level > pc_isGM(sd)) {
+                clif_displaymessage(fd, "You are not authorised to warp you from your actual map.");
+                return -1;
+        }
+        pc_setpos(sd, map[pl_sd->bl.m].name, pl_sd->bl.x, pl_sd->bl.y, 3);
+        sprintf(output, msg_table[4], pl_sd->status.name); // Jump to %s
+        clif_displaymessage(fd, output);
+
+        sd->followtarget = pl_sd->bl.id;
+
+	return 0;
+}
+
+int
+atcommand_iterate_forward_over_players(
+	const int fd, struct map_session_data* sd,
+	const char* command, const char* message)
+{
+        return atcommand_jump_iterate(fd, sd, command, message,
+                                      map_get_first_session, map_get_next_session);
+}
+
+int
+atcommand_iterate_backwards_over_players(
+	const int fd, struct map_session_data* sd,
+	const char* command, const char* message)
+{
+        return atcommand_jump_iterate(fd, sd, command, message,
+                                      map_get_last_session, map_get_prev_session);
+}
diff --git a/src/map/atcommand.h b/src/map/atcommand.h
index 76593cc..80101b9 100644
--- a/src/map/atcommand.h
+++ b/src/map/atcommand.h
@@ -213,6 +213,10 @@ enum AtCommandType {
         AtCommand_MagicInfo,
         AtCommand_Log,
         AtCommand_Tee,
+        AtCommand_Invisible,
+        AtCommand_Visible,
+        AtCommand_IterateForward,
+        AtCommand_IterateBackward,
 	// end
 	AtCommand_Unknown,
 	AtCommand_MAX
diff --git a/src/map/map.c b/src/map/map.c
index 3db293c..6ca1bd4 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -1145,6 +1145,74 @@ char * map_charid2nick(int id) {
 	return p->nick;
 }
 
+/*========================================*/
+/* [Fate] Operations to iterate over active map sessions */
+
+static struct map_session_data *
+map_get_session(int i)
+{
+        struct map_session_data *d;
+
+        if (i >= 0 && i < fd_max
+            && session[i] && (d = session[i]->session_data)
+            && d->state.auth)
+                return d;
+
+        return NULL;
+}
+
+static struct map_session_data *
+map_get_session_forward(int start)
+{
+        int i;
+	for (i = start; i < fd_max; i++) {
+                struct map_session_data *d = map_get_session(i);
+                if (d)
+                        return d;
+        }
+
+        return NULL;
+}
+
+static struct map_session_data *
+map_get_session_backward(int start)
+{
+        int i;
+	for (i = start; i >= 0; i--) {
+                struct map_session_data *d = map_get_session(i);
+                if (d)
+                        return d;
+        }
+
+        return NULL;
+}
+
+struct map_session_data *
+map_get_first_session()
+{
+        return map_get_session_forward(0);
+}
+
+struct map_session_data *
+map_get_next_session(struct map_session_data *d)
+{
+        return map_get_session_forward(d->fd + 1);
+}
+
+struct map_session_data *
+map_get_last_session()
+{
+        return map_get_session_backward(fd_max);
+}
+
+struct map_session_data *
+map_get_prev_session(struct map_session_data *d)
+{
+        return map_get_session_backward(d->fd - 1);
+}
+
+
+
 
 /*==========================================
  * Search session data from a nick name
diff --git a/src/map/map.h b/src/map/map.h
index d407016..0b52a38 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -748,6 +748,11 @@ void map_addnickdb(struct map_session_data *);
 int map_scriptcont(struct map_session_data *sd,int id); /* Continues a script either on a spell or on an NPC */
 struct map_session_data * map_nick2sd(char*);
 
+struct map_session_data * map_get_first_session();
+struct map_session_data * map_get_last_session();
+struct map_session_data * map_get_next_session(struct map_session_data *current);
+struct map_session_data * map_get_prev_session(struct map_session_data *current);
+
 // gat�֘A
 int map_getcell(int,int,int);
 int map_setcell(int,int,int,int);
diff --git a/src/map/pc.h b/src/map/pc.h
index 24ecd74..3d6fc64 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -30,6 +30,7 @@ int pc_isGM(struct map_session_data *sd);
 int pc_iskiller(struct map_session_data *src, struct map_session_data *target); // [MouseJstr]
 int pc_getrefinebonus(int lv,int type);
 
+void pc_invisibility(struct map_session_data *sd, int enabled); // [Fate]
 int pc_counttargeted(struct map_session_data *sd,struct block_list *src,int target_lv);
 int pc_setrestartvalue(struct map_session_data *sd,int type);
 int pc_makesavestatus(struct map_session_data *);
-- 
cgit v1.2.3-70-g09d2