summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesusaves <cpntb1@ymail.com>2020-09-01 19:12:56 -0300
committerJesusaves <cpntb1@ymail.com>2020-09-01 19:12:56 -0300
commitbf25badae686b6e5defde50eb424b45a855dbf6b (patch)
tree4e96552b874ae741a0d9054057d097fd515efd7f
parent5b7b91097c8e3e2bfd962a66ef3633a420f0a358 (diff)
downloadserverdata-bf25badae686b6e5defde50eb424b45a855dbf6b.tar.gz
serverdata-bf25badae686b6e5defde50eb424b45a855dbf6b.tar.bz2
serverdata-bf25badae686b6e5defde50eb424b45a855dbf6b.tar.xz
serverdata-bf25badae686b6e5defde50eb424b45a855dbf6b.zip
Begin working on item port script.
Its performance is an utter crap. I guess the best option, actually.......... ....is to extend getitem() and getitembound() to return index.
-rw-r--r--npc/012-2-2/sorfina.txt167
-rw-r--r--npc/functions/legacy.txt31
2 files changed, 194 insertions, 4 deletions
diff --git a/npc/012-2-2/sorfina.txt b/npc/012-2-2/sorfina.txt
index be92fa32..120db16f 100644
--- a/npc/012-2-2/sorfina.txt
+++ b/npc/012-2-2/sorfina.txt
@@ -6,6 +6,9 @@
// THIS IS A PLACEHOLDER!
012-2-2,26,30,0 script Sorfina NPC_SORFINA,{
+ function sorfinaCheckUpdates;
+ function sorfinaUpdater;
+ function sorfinaRecreateItem;
speech
lg("Welcome, adventurer."),
l("I will never know why people barge in others' houses and get away with it."),
@@ -13,7 +16,133 @@
if (islegacyaccount() && countitem(ClothesPack)) goto L_Legacy;
close;
-L_Legacy:
+function sorfinaCheckUpdates {
+ return (getlegacyport(true) < $GLOBAL_MERGELVL);
+}
+
+// sorfinaRecreateItemList(MERGELVL_ID, Duplicate, item1, item2, item3...)
+function sorfinaRecreateItemList {
+ if (getlegacyport(true) < getarg(0))
+ return;
+
+ .@dupe=getarg(0, false);
+
+ // Warn player it'll take a while
+ mesn;
+ mesq l("Gimme a second, this may take a while.");
+ consolemes(CONSOLEMES_DEBUG, "Applying sorfina.merge-%03d to char %d (Account %d)", getarg(0), getcharid(0), getcharid(3));
+ next;
+
+ // Retrieve item list
+ // FIXME: Optimize: if @lega_** exists, skip resetting it
+ deletearray(@lega_item);
+ deletearray(@lega_ammo);
+ deletearray(.@itemlist);
+ deletearray(.@ammolist);
+ getlegacyinventory(@lega_item, @lega_ammo);
+
+ // array_push obviously cannot push zeros,
+ // So we do not use wrappers here
+ freeloop(true);
+ for (.@i=2;.@i < getargcount(); .@i++) {
+ .@item=getarg(.@i);
+
+ // FIXME: Translation from rEvolt to Legacy
+ // Should probably be done either using an httable
+ // Or using black magic: $@ITEMTABLE[revoltid] = legacyid
+ .@idx=array_find(@lega_item, .@item);
+
+ // Record on .@itemlist NEW ITEM ID
+ .@itemlist[.@i-2]=.@item;
+
+ // Amount is tricky depending on dupe enabled or not
+ if (.@dupe)
+ .@ammolist[.@i-2]=@lega_ammo[.@idx];
+ else
+ .@ammolist[.@i-2]=(@lega_ammo[.@idx] ? 1 : 0);
+ }
+ freeloop(false);
+
+ // Check weight
+ if (!checkweight2(.@itemlist, .@ammolist)) {
+ // Ban player for a while
+ @sorfina_cooldown=gettimetick(2)+90;
+ // Induced cooldown to prevent logout abuse
+ sleep2(1000);
+ mesn;
+ mesq l("Sorry, but you do not have enough space for this.");
+ next;
+ mesn;
+ mesq l("Please come back later.");
+ close; // Terminate
+ }
+
+ // Update merger level
+ setlegacyport(getarg(0), true);
+
+ // Use the function helper to give items
+ freeloop(true);
+ for (.@i=0; .@i < getarraysize(.@itemlist); .@i++) {
+ sorfinaRecreateItem(.@itemlist[.@i], .@ammolist[.@i]);
+ }
+ freeloop(false);
+
+ // Report player we're done
+ mesn;
+ mesq lg("Here you go, darling.");
+ next;
+ return;
+}
+
+// sorfinaRecreateItem(ItemID, amount)
+// THIS IS A SUB FUNCTION, DO NOT CALL IT DIRECTLY
+function sorfinaRecreateItem {
+ // Obtain item type
+ .@type=getiteminfo(getarg(0), ITEMINFO_TYPE);
+
+ // Because we'll manually set the options, we must do it one. at. a. time.
+ // And bugs may be present D:
+ // FIXME: Bugs (ML ticket)
+ switch (.@type) {
+ case IT_WEAPON:
+ // We need to assign vintage (50% nerf) option
+ for (.@j=0; .@j < getarg(1); .@j++) {
+ getitembound(getarg(0), 1, 1);
+ // FIXME: We actually DO need to recreate the inventory list
+ // It is super expensive but getitembound() do not
+ // return the item index it created.
+ // And it also comes with a bug.
+ delinventorylist();
+ getinventorylist();
+ .@index=array_rfind(@inventorylist_id, .@it);
+ setitemoptionbyindex(.@index, 0, VINTAGE_WPN, 1);
+ // Loopback
+ }
+ break;
+ case IT_ARMOR:
+ // We need to assign vintage (20% nerf) option
+ for (.@j=0; .@j < getarg(1); .@j++) {
+ getitembound(getarg(0), 1, 1);
+ // FIXME: We actually DO need to recreate the inventory list
+ // It is super expensive but getitembound() do not
+ // return the item index it created.
+ // And it also comes with a bug.
+ delinventorylist();
+ getinventorylist();
+ .@index=array_rfind(@inventorylist_id, .@it);
+ setitemoptionbyindex(.@index, 0, VINTAGE_ARM, 1);
+ // Loopback
+ }
+ break;
+ default:
+ // No special treatment required
+ getitembound(getarg(0), getarg(1), 1);
+ break;
+ }
+ return;
+}
+
+function sorfinaUpdater {
next;
mesn;
mesq l("Actually, I see you have some really torn %s.", getitemlink(ClothesPack));
@@ -24,9 +153,39 @@ L_Legacy:
mesn;
mesq l("I wonder what sort of sea disaster could have destroyed them so badly. But, I believe they can be repaired with magic.");
next;
- mesn;
- mesq l("If only the developers - my next door neighbor - weren't so lazy, maybe I would be able to repair them or know someone able to do that. Sorry.");
- close;
+ if (@sorfina_cooldown > gettimetick(2)) {
+ mesn;
+ mesq l("I can do it but I'm busy right now, please come back later.");
+ } else if (!sorfinaCheckUpdates()) {
+ mesn;
+ mesq l("If only the developers - my next door neighbor - weren't so lazy, maybe I would be able to repair them or know someone able to do that. Sorry.");
+ } else {
+ mesn;
+ mesq l("Actually, I could try to repair some of your items. These cannot be traded and have weaker status than normal items =/");
+ next;
+ mesn;
+ mesq l("Maybe someone can fix but I would have no idea. But given they cannot be traded, dropped, mailed, or whatever...");
+ next;
+ mesn;
+ mesq l("Do you want me to do it? And do you want to keep duplicates?");
+ next;
+ // Because we lack getstorageitem() and we have H.U.S.S. on PR List
+ // So let's wait for the Hercules Ultimate Storage System.
+ mesc l("WARNING: Items which were at storage cannot be repaired by Sorfina!!"), 1;
+ select
+ l("Please do, and delete duplicates."),
+ l("Please do, and keep duplicates."),
+ l("Please don't.");
+ mes "";
+ if (@menu == 3)
+ return;
+ .@dup=(@menu == 2);
+ // Updater list
+ sorfinaRecreateItemList(1, .@dup, Acorn, Dagger, Knife);
+ sorfinaRecreateItemList(2, .@dup, CottonShirt);
+ }
+ return;
+}
OnInit:
.bodytype = BODYTYPE_2;
diff --git a/npc/functions/legacy.txt b/npc/functions/legacy.txt
index 5f5ad026..010d5111 100644
--- a/npc/functions/legacy.txt
+++ b/npc/functions/legacy.txt
@@ -115,6 +115,37 @@ function script getlegacybosspoints {
return bitwise_get(getvariableofpc(LEGACY[1], nameid2id(getarg(0, "")), 0), 0x7FFFFF00, 8);
}
+/**
+ * gets the current item porting level for player
+ *
+ * Example:
+ * getlegacyport("player name", true)
+ *
+ * @param 0? - Char versus Account item porting level. Default to char.
+ * @param 1? - char name / account id (defaults to attached player)
+ * @return base level
+ */
+function script getlegacyport {
+ .@var=getvariableofpc(getarg(0, true) ? LEGACY[3] : ##LEGACY[2], nameid2id(getarg(1, "")), 0);
+ return bitwise_get(.@var, 0x000000FF, 0);
+}
+
+/**
+ * sets the current item porting level for player
+ *
+ * Example:
+ * setlegacyport("player name", 255, true)
+ *
+ * @param 0 - New value
+ * @param 1? - Char versus Account item porting level. Default to char.
+ * @param 2? - char name / account id (defaults to attached player)
+ * @return base level
+ */
+function script setlegacyport {
+ .@var=getvariableofpc(getarg(1, true) ? LEGACY[3] : ##LEGACY[2], nameid2id(getarg(2, "")), 0);
+ return bitwise_set(.@var, 0x000000FF, 0, getarg(0));
+}
+
// the functions below can be used to mimic a Legacy account for local testing