changeset 155:1af259ac4ed2

arogue7, xrogue: fix save/restore of alchemy jugs. state.c now saves the fuse that refills alchemy jugs, using the method of numbering objects previously applied to Advanced Rogue 5. Alchemy jugs that are empty when the game is saved will continue to function after it is restored. Savefile compatibility should not be affected.
author John "Elwin" Edwards
date Fri, 29 May 2015 17:34:04 -0400
parents 4ef27dfe0492
children 3e1146666ae5
files arogue7/state.c xrogue/state.c
diffstat 2 files changed, 156 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/arogue7/state.c	Thu May 28 15:39:28 2015 -0400
+++ b/arogue7/state.c	Fri May 29 17:34:04 2015 -0400
@@ -1383,6 +1383,69 @@
     return(READSTAT);
 }
 
+/* Assigns a number to an alchemy jug associated with a fuse, so it can be 
+ * found and reassociated when restoring.
+ * 1 - 31: slot in pack
+ * 32+   : on floor
+ * Hopefully monsters do not pick them up.
+ */
+int number_alchemy_jug(struct object *obj) {
+    struct object *tobj = NULL;
+    struct linked_list *item;
+    int i = 1;
+    for (item = pack; item != NULL; item = next(item), i++) {
+	tobj = OBJPTR(item);
+	if (tobj	 == obj		&& 
+	    tobj->o_type == MM		&& 
+	    tobj->o_which== MM_JUG)
+		break;
+    }
+    if (item == NULL) {
+	for (item = lvl_obj, i = 32; item != NULL; item = next(item), i++) {
+	    tobj = OBJPTR(item);
+	    if (tobj	     == obj		&& 
+		tobj->o_type == MM		&& 
+		tobj->o_which== MM_JUG)
+		    break;
+	}
+    }
+    if (item == NULL)
+      return 0;
+    return i;
+}
+
+/* Takes an alchemy jug number and tracks down the object. */
+struct object *find_alchemy_jug(int n) {
+    struct object *tobj;
+    struct linked_list *item;
+
+    if (n <= 0) {
+        return NULL;
+    }
+    else if (n < 32) {
+        item = pack;
+        n -= 1;
+    }
+    else if (n < 1024) {
+        item = lvl_obj;
+        n -= 32;
+    }
+    else {
+        /* This is likely a bug, not 1024 actual items on the floor. */
+        return NULL;
+    }
+    while (item != NULL && n > 0) {
+        item = next(item);
+        n--;
+    }
+    if (item == NULL)
+        return NULL;
+    tobj = OBJPTR(item);
+    if (tobj->o_type != MM || tobj->o_which != MM_JUG)
+        return NULL;
+    return tobj;
+}
+
 int
 rs_write_daemons(FILE *savef, struct delayed_action *d_list, int count)
 {
@@ -1471,6 +1534,8 @@
             func = 36;
         else if (d_list[i].d_func == nobolt)
             func = 37;
+        else if (d_list[i].d_func == alchemy)
+            func = 38;
         else if (d_list[i].d_func == NULL)
             func = 0;
         else
@@ -1497,6 +1562,10 @@
             index = find_list_ptr(player.t_pack, d_list[i].d_.varg);
             rs_write_int(savef,index);
         }
+        else if (d_list[i].d_func == alchemy)
+        {
+            rs_write_int(savef, number_alchemy_jug(d_list[i].d_.varg));
+        }
         else
             rs_write_int(savef, d_list[i].d_.arg);
 
@@ -1605,6 +1674,8 @@
                      break;
             case 37: d_list[i].d_func = nobolt;
                      break;
+            case 38: d_list[i].d_func = alchemy;
+                     break;
 	    case  0:
             case -1:
             default: d_list[i].d_func = NULL;
@@ -1635,6 +1706,13 @@
 	    if (d_list[i].d_.varg == NULL)
 		d_list[i].d_type = 0;
         }
+        else if (d_list[i].d_func == alchemy)
+        {
+	    rs_read_int(inf, &dummy);
+            d_list[i].d_.varg = find_alchemy_jug(dummy);
+	    if (d_list[i].d_.varg == NULL)
+		d_list[i].d_type = 0;
+        }
         else
 	    rs_read_int(inf, &d_list[i].d_.arg);
 
--- a/xrogue/state.c	Thu May 28 15:39:28 2015 -0400
+++ b/xrogue/state.c	Fri May 29 17:34:04 2015 -0400
@@ -960,6 +960,69 @@
     return(READSTAT);
 }
 
+/* Assigns a number to an alchemy jug associated with a fuse, so it can be 
+ * found and reassociated when restoring.
+ * 1 - 31: slot in pack
+ * 32+   : on floor
+ * Hopefully monsters do not pick them up.
+ */
+int number_alchemy_jug(struct object *obj) {
+    struct object *tobj = NULL;
+    struct linked_list *item;
+    int i = 1;
+    for (item = pack; item != NULL; item = next(item), i++) {
+	tobj = OBJPTR(item);
+	if (tobj	 == obj		&& 
+	    tobj->o_type == MM		&& 
+	    tobj->o_which== MM_JUG)
+		break;
+    }
+    if (item == NULL) {
+	for (item = lvl_obj, i = 32; item != NULL; item = next(item), i++) {
+	    tobj = OBJPTR(item);
+	    if (tobj	     == obj		&& 
+		tobj->o_type == MM		&& 
+		tobj->o_which== MM_JUG)
+		    break;
+	}
+    }
+    if (item == NULL)
+      return 0;
+    return i;
+}
+
+/* Takes an alchemy jug number and tracks down the object. */
+struct object *find_alchemy_jug(int n) {
+    struct object *tobj;
+    struct linked_list *item;
+
+    if (n <= 0) {
+        return NULL;
+    }
+    else if (n < 32) {
+        item = pack;
+        n -= 1;
+    }
+    else if (n < 1024) {
+        item = lvl_obj;
+        n -= 32;
+    }
+    else {
+        /* This is likely a bug, not 1024 actual items on the floor. */
+        return NULL;
+    }
+    while (item != NULL && n > 0) {
+        item = next(item);
+        n--;
+    }
+    if (item == NULL)
+        return NULL;
+    tobj = OBJPTR(item);
+    if (tobj->o_type != MM || tobj->o_which != MM_JUG)
+        return NULL;
+    return tobj;
+}
+
 rs_write_daemons(FILE *savef, struct delayed_action *d_list,int count)
 {
     int i = 0;
@@ -1045,6 +1108,8 @@
             func = 36;
         else if (d_list[i].d_func == nobolt)
             func = 37;
+        else if (d_list[i].d_func == alchemy)
+            func = 38;
         else if (d_list[i].d_func == NULL)
             func = 0;
         else
@@ -1071,6 +1136,10 @@
             index = find_list_ptr(player.t_pack,d_list[i].d_arg.vp);
             rs_write_int(savef,index);
         }
+        else if (d_list[i].d_func == alchemy)
+        {
+            rs_write_int(savef, number_alchemy_jug((void *) d_list[i].d_arg.vp));
+        }
         else
             rs_write_int(savef, d_list[i].d_arg.i);
 
@@ -1193,6 +1262,8 @@
                                  break;
                         case 37: d_list[i].d_func = nobolt;
                                  break;
+                        case 38: d_list[i].d_func = alchemy;
+                                 break;
 						case 0:
 						case -1:
                         default: d_list[i].d_func = NULL;
@@ -1222,6 +1293,13 @@
                         if (d_list[i].d_arg.vp == NULL)
                             d_list[i].d_type = 0;
                     }
+                    else if (d_list[i].d_func == alchemy)
+                    {
+	                rs_read_int(inf, &dummy);
+                        d_list[i].d_arg.vp = (void *) find_alchemy_jug(dummy);
+	                if (d_list[i].d_arg.vp == NULL)
+		            d_list[i].d_type = 0;
+                    }
                     else
                         rs_read_int(inf, &d_list[i].d_arg.i);