summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMicksha <ms-shaman@gmx.de>2020-05-07 14:58:56 +0000
committerMicksha <ms-shaman@gmx.de>2020-05-07 14:58:56 +0000
commit976171f0e53a9818cfbe1ce727b0e4f6c0b8762a (patch)
tree1e5f4b0968d403bf67eb96196e06a5b84062a049
parent6e464f619de5aad2b14455dfd993f8081008e268 (diff)
parent7fa4a1e41d43f3da04ffe8fbeba1498ab96385b9 (diff)
downloadserverdata-976171f0e53a9818cfbe1ce727b0e4f6c0b8762a.tar.gz
serverdata-976171f0e53a9818cfbe1ce727b0e4f6c0b8762a.tar.bz2
serverdata-976171f0e53a9818cfbe1ce727b0e4f6c0b8762a.tar.xz
serverdata-976171f0e53a9818cfbe1ce727b0e4f6c0b8762a.zip
Merge branch 'jesusalva/treasure' into 'master'
Treasure! Closes evol-all#75 See merge request evol/serverdata!240
-rw-r--r--db/constants.conf4
-rw-r--r--db/re/item_db.conf28
-rw-r--r--db/re/mob_db.conf12
-rw-r--r--npc/001-1/enora.txt6
-rw-r--r--npc/001-1/qonan.txt5
-rw-r--r--npc/001-2-11/mona.txt6
-rw-r--r--npc/functions/RNGesus.txt20
-rw-r--r--npc/functions/treasure.txt134
-rw-r--r--npc/items/shovel.txt155
-rw-r--r--npc/scripts.conf3
10 files changed, 344 insertions, 29 deletions
diff --git a/db/constants.conf b/db/constants.conf
index 19a812e8..4c83ec8c 100644
--- a/db/constants.conf
+++ b/db/constants.conf
@@ -4128,6 +4128,7 @@ constants_db: {
NPC_FLAG_L: 464
NPC_FLAG_R: 465
NPC_TOICHI: 466
+ NPC_TREASURE: 469
NPC_TEST1: 800
NPC_PLAYER: 801
@@ -4239,5 +4240,8 @@ constants_db: {
LANG_ON_SEA: 1
LANG_IN_SHIP: 2
+ comment__: "Misc settings"
+ CHEST_WAITTIME: 900 // 15 minutes
+
@include "conf/import/constants.conf"
}
diff --git a/db/re/item_db.conf b/db/re/item_db.conf
index adf5fcec..38963955 100644
--- a/db/re/item_db.conf
+++ b/db/re/item_db.conf
@@ -1184,6 +1184,24 @@ item_db: (
sc_start SC_INCHITRATE, 80000, 300;
">
},
+{
+ Id: 615
+ AegisName: "TreasureMap"
+ Name: "Treasure Map"
+ Type: "IT_USABLE"
+ Buy: 45000
+ Sell: 300
+ Weight: 14
+ KeepAfterUse: true
+ Refine: false
+ Script: <"
+ // ShovelQuests_Assigned<MAP$,X,Y> → Coordinates for Treasure Map
+ if (!ShovelQuests_AssignedX) {
+ callfunc "shovel_genrandtreasure";
+ }
+ dispbottom l("A treasure is burried in @@, (@@, @@)", ShovelQuests_AssignedMAP$, ShovelQuests_AssignedX, ShovelQuests_AssignedY);
+ ">
+},
// Generic
{
@@ -1849,6 +1867,16 @@ item_db: (
nogstorage: true
}
},
+{
+ Id: 808
+ AegisName: "TreasureKey"
+ Name: "Treasure Key"
+ Type: "IT_ETC"
+ Buy: 500
+ Sell: 110
+ Weight: 2
+ Refine: false
+},
// Necklaces
{
Id: 1000
diff --git a/db/re/mob_db.conf b/db/re/mob_db.conf
index 220ff6c1..fc3f8b9e 100644
--- a/db/re/mob_db.conf
+++ b/db/re/mob_db.conf
@@ -1058,8 +1058,9 @@ mob_db: (
DamageMotion: 1026
Drops: {
MaggotSlime: 800
- HalfEggshell: 200
Moss: 400
+ HalfEggshell: 200
+ TreasureKey: 100
}
},
{
@@ -2647,8 +2648,9 @@ mob_db: (
AttackMotion: 672
DamageMotion: 900
Drops: {
- BottleOfWater: 250
CoinBag: 500
+ BottleOfWater: 250
+ TreasureKey: 200
Dagger: 90
BanditTrousers: 1
BanditHood: 1
@@ -2692,11 +2694,12 @@ mob_db: (
AttackMotion: 672
DamageMotion: 900
Drops: {
- EmptyBottle: 500
- CoinBag: 500
TrainingArrow: 5000
TrainingArrow: 1000
TrainingArrow: 500
+ EmptyBottle: 500
+ CoinBag: 500
+ TreasureKey: 200
BanditTrousers: 1
BanditHood: 1
BanditGloves: 1
@@ -2741,6 +2744,7 @@ mob_db: (
AttackMotion: 672
DamageMotion: 900
Drops: {
+ TreasureKey: 2000
CoinBag: 750
Dagger: 150
BanditShawl: 10
diff --git a/npc/001-1/enora.txt b/npc/001-1/enora.txt
index e2e4064b..140f51b0 100644
--- a/npc/001-1/enora.txt
+++ b/npc/001-1/enora.txt
@@ -300,6 +300,8 @@
l("Only one more Fluffy to kill and it's done!");
return;
+ } else if (getq(ArtisQuests_Enora) == 10) {
+ inventoryplace TreasureKey, 1;
}
speech S_FIRST_BLANK_LINE | S_LAST_NEXT,
@@ -314,6 +316,10 @@
{
setq ArtisQuests_Enora, 11;
enora_reward(140, 500);
+ getitem TreasureKey, 1;
+ mesn;
+ mesq l("Also, here is a %s. If you find a Treasure Chest somewhere, you can open it with this!", getitemlink(TreasureKey));
+ next;
}
return;
diff --git a/npc/001-1/qonan.txt b/npc/001-1/qonan.txt
index 48b0c3f8..6805356a 100644
--- a/npc/001-1/qonan.txt
+++ b/npc/001-1/qonan.txt
@@ -60,6 +60,9 @@
l("You should check on the highest part of the cliff, I was hiding there."),
l("I hope to see you soon.");
getitem IronShovel, 1;
+ // For questlog
+ setq2 ArtisQuests_QOnan, .move__rand_x+any(-1,1);
+ setq3 ArtisQuests_QOnan, .move__rand_y+any(-1,1);
close;
case 2:
speech S_FIRST_BLANK_LINE | S_LAST_BLANK_LINE,
@@ -101,7 +104,7 @@ OnInit:
}
function script QOnanFoundItem {
- setq ArtisQuests_QOnan, 2;
+ setq ArtisQuests_QOnan, 2, 0, 0;
// getitem SmallChest, 1;
narrator S_FIRST_BLANK_LINE,
l("You found a small chest, surprisingly heavy for it's size."),
diff --git a/npc/001-2-11/mona.txt b/npc/001-2-11/mona.txt
index 3d5b4584..2f4e3da0 100644
--- a/npc/001-2-11/mona.txt
+++ b/npc/001-2-11/mona.txt
@@ -127,14 +127,14 @@
{
if (!MONA_REPEAT)
{
- inventoryplace WoodenBow, 1;
+ inventoryplace WoodenSword, 1;
speech 0x0,
l("Daddy finally came back home! He grabbed a snack and said he would be returning to the sewers."),
lg("He did say that I should give you this @@ as a gift. He says you are very skilled and will make good use of his old weapon.",
"He did say that I should give you this @@ as a gift. He says you are very skilled and will make good use of his old weapon.",
- getitemlink(WoodenBow)),
+ getitemlink(WoodenSword)),
l("He has never been the same since mommy went away...");
- getitem WoodenBow, 1;
+ getitem WoodenSword, 1;
}
else if (MONA_REPEAT == 10)
{
diff --git a/npc/functions/RNGesus.txt b/npc/functions/RNGesus.txt
index 6883f8f1..7224977c 100644
--- a/npc/functions/RNGesus.txt
+++ b/npc/functions/RNGesus.txt
@@ -1,16 +1,30 @@
// Evol functions.
// Authors:
// gumi
+// jesusalva
// Description:
// Randomization helper functions.
+// pseudo-fix randomness
+// rand2( min, max )
+function script rand2 {
+ if (getargcount() == 2) {
+ .@min=getarg(0)*100;
+ .@max=getarg(1)*100+99;
+ } else {
+ .@min=0;
+ .@max=getarg(0)*100-1;
+ }
+ return rand(.@min, .@max)/100;
+}
+
// any(<arg>{, ...<arg>})
// returns one argument randomly
function script any {
- return getarg(rand(getargcount()));
+ return getarg(rand2(getargcount()));
}
@@ -19,7 +33,7 @@ function script any {
// returns any member of the array
function script any_of {
- return getelementofarray(getarg(0), getarrayindex(getarg(0)) + rand(getarraysize(getarg(0)) - getarrayindex(getarg(0))));
+ return getelementofarray(getarg(0), getarrayindex(getarg(0)) + rand2(getarraysize(getarg(0)) - getarrayindex(getarg(0))));
}
@@ -54,7 +68,7 @@ function script relative_array_random {
set(getelementofarray(getarg(0), 0), .@total_prob);
}
- .@target_sum = rand(0, .@total_prob);
+ .@target_sum = rand2(0, .@total_prob);
for (.@i = .@initial_index; .@sum < .@target_sum; .@i += 2) {
if (.@is_str) {
diff --git a/npc/functions/treasure.txt b/npc/functions/treasure.txt
new file mode 100644
index 00000000..785dd4a0
--- /dev/null
+++ b/npc/functions/treasure.txt
@@ -0,0 +1,134 @@
+// Moubootaur Legends functions.
+// Author:
+// Jesusalva
+// Description:
+// Random Treasure Box Utils
+
+function script TreasureBox {
+ .@id=getnpcid();
+ if (RNGTREASURE_DATE[.@id] > gettimetick(2)) {
+ mesc l("The chest is unlocked and empty.");
+ close;
+ }
+
+ mesc l("Open the chest?");
+ mesc l("Cost: 1 %s", getitemlink(TreasureKey)), 1;
+ if (!countitem(TreasureKey))
+ close;
+ next;
+ if (askyesno() == ASK_NO)
+ close;
+
+ delitem TreasureKey, 1;
+ mesc l("You open the chest!");
+ RNGTREASURE_DATE[.@id]=gettimetick(2)+CHEST_WAITTIME; // Minimum 15 minutes
+
+ .@empty=getvariableofnpc(.empty, strnpcinfo(0));
+ if (!.@empty) {
+ TREASURE_OPEN=TREASURE_OPEN+1;
+ .@t=TREASURE_OPEN;
+ .@r=rand(0,10000)-(readbattleparam(getcharid(3), UDT_LUK)*2);
+
+ // Select treasure list
+ // You're warranted a rare (5%) every 25 open chests
+ // There's also uncommons (20%) and commons (75%)
+ if (.@t == 1)
+ .@loot=WoodenBow;
+ else if (.@t % 25 == 0 || .@r < 500) // Rare: 5%
+ .@loot=any(AtroposMixture, ElixirOfLife, BigHealing, BigMana, DeathPotion, MagicFeather);
+ else if (.@r < 2500) // Uncommon: 20%
+ .@loot=any(FatesPotion, ClothoLiquor, LachesisBrew, RedPlushWine, TreasureMap, MediumHealing, MediumMana);
+ else // Common: 75%
+ .@loot=any(Bread, Fungus, Cheese, Aquada, Croconut, PiberriesInfusion, Carrot, SmallHealing, SmallMana);
+
+
+ inventoryplace .@loot, 1;
+ mesc l("You find %s inside!", getitemlink(.@loot));
+ getitem .@loot, 1;
+ } else {
+ mesc l("You find %s inside!", l("nothing"));
+ }
+ return;
+}
+
+// Animation code by Evol Team
+// 4144, gumi, Hal9000, Reid
+// (Random) Treasure Chest
+// Authored by Jesusalva
+// Regenerates every 6 hours
+001-3-0,0,0,0 script #chest_001-3-0 NPC_CHEST,{
+ /*
+ // Extract the map name - Seems unused
+ explode(.@ni$, .name$, "_");
+ .@map$=.@ni$[1];
+ //if (.@map$ == "") debugmes "Error";
+ */
+
+ // Conditionals
+ if (!.busy) {
+ TreasureBox();
+
+ specialeffect(.dir == 0 ? 24 : 25, AREA, getnpcid()); // closed ? opening : closing
+ .dir = .dir == 0 ? 2 : 6; // closed ? opening : closing
+ .busy = true; // lock until available again
+ initnpctimer;
+ } else {
+ mesc l("Someone looted this treasure box already...");
+ }
+ close;
+
+OnTimer160:
+ .dir = .dir == 6 ? 0 : 4; // closing ? closed : open
+ end;
+
+OnTimer500:
+ // It's closed: Make available and stop timer
+ if (.dir == 0) {
+ .busy = false;
+ stopnpctimer;
+ }
+ end;
+
+// Autoclose
+OnTimer60000:
+ .dir = 6; // closing
+ specialeffect(25, AREA, getnpcid()); // closing
+ setnpctimer 0;
+ end;
+
+OnInit:
+ .busy = false;
+ .distance = 2;
+
+OnClock0156:
+OnClock0756:
+OnClock1356:
+OnClock1956:
+ // Try to warp randomly to a walkable spot, up to 20 attempts
+ // Otherwise, it'll stay where it already is (but will close and refill).
+ .@e=0; .@x=0; .@y=0;
+ while (!checkcell(.map$, .@x, .@y, cell_chkpass))
+ {
+ if (.@e == 20) {
+ .@x=.x;
+ .@y=.y;
+ break;
+ }
+ // Remember the +20 -20 margin adjustment
+ .@x = rand2(20, getmapinfo(MAPINFO_SIZE_X, .map$)-20);
+ .@y = rand2(20, getmapinfo(MAPINFO_SIZE_X, .map$)-20);
+ ++.@e;
+ }
+ .busy=false;
+ movenpc .name$, .@x, .@y, 0;
+ end;
+}
+
+// Lets bring some treasure to The Mana World
+008-3-4,0,0,0 duplicate(#chest_001-3-0) #chest_008-3-4 NPC_TREASURE
+008-3-5,0,0,0 duplicate(#chest_001-3-0) #chest_008-3-5 NPC_TREASURE
+008-3-6,0,0,0 duplicate(#chest_001-3-0) #chest_008-3-6 NPC_TREASURE
+
+012-3-1,0,0,0 duplicate(#chest_001-3-0) #chest_012-3-1 NPC_TREASURE
+012-3-3,0,0,0 duplicate(#chest_001-3-0) #chest_012-3-3 NPC_TREASURE
+
diff --git a/npc/items/shovel.txt b/npc/items/shovel.txt
index fef4c24f..ac1cd50c 100644
--- a/npc/items/shovel.txt
+++ b/npc/items/shovel.txt
@@ -1,6 +1,7 @@
// Evol scripts.
// Author:
// Travolta
+// Jesusalva
// Description:
// NPC to use shovel (dig, bury etc)
@@ -9,10 +10,12 @@
function CheckDigLocation {
getmapxy(.@map$, .@x, .@y, 0);
- if (getunits(BL_NPC, .@units, 1, .@map$, .@x - 1, .@y, .@x + 1, .@y + 1))
- {
- dispbottom(l("You cannot bury under a NPC!"));
- return false;
+ if (.@map$ != "001-1") {
+ if (getunits(BL_NPC, .@units, 1, .@map$, .@x - 1, .@y, .@x + 1, .@y + 1))
+ {
+ dispbottom(l("You cannot bury under a NPC!"));
+ return false;
+ }
}
// TODO: we should have a way to check for GROUNDTOP collisions too
@@ -53,6 +56,13 @@
return 1;
}
+ function AddMapDigRect {
+ .@m$=getarg(0);
+ .@x=getmapinfo(MAPINFO_SIZE_X, .@m$)-20;
+ .@y=getmapinfo(MAPINFO_SIZE_Y, .@m$)-20;
+ return AddDigRect(.@m$, 20, 20, .@x, .@y);
+ }
+
function PlayerIsTired {
if (is_evtc())
return false; // event coordinators are never tired
@@ -96,21 +106,28 @@
}
function Bury {
- narrator(S_FIRST_BLANK_LINE | S_LAST_NEXT,
- l("What would you like to bury?"));
+ narrator S_FIRST_BLANK_LINE | S_LAST_BLANK_LINE, l("What would you like to bury?");
+ .@items$ = "";
+
+ mes "##B" + l("Drag and drop an item from your inventory.") + "##b";
- mes("##B" + l("Drag and drop an item from your inventory.") + "##b");
.@id = requestitem();
- // You cannot bury: Items you don't have, your shovel, Bound Items, and items which are not dropped by any mobs.
- // The "item not dropped by any mob" is temporary, and should be replaced by "items with trade restrictions" later. [JESUS]
- // event coordinators can always bury
- if (!is_evtc() && (.@id < 1 || countitem(.@id) < 1 ||
- compare(getitemname(.@id), "shovel") || checkbound(.@id) ||
- !getiteminfo(.@id, ITEMINFO_MAXCHANCE)))
- {
- mesc(l("You cannot bury this item!"));
- return false;
+ // If ID is invalid, there's not enough items, it is an Iron Shovel, it is bound = Cannot bury
+ // NOBODY bypass notrade check. (ITR_NONE is 0)
+ if (.@id < 1) close;
+ if (.@id < 1 || countitem(.@id) < 1 || .@id == IronShovel || checkbound(.@id) ||
+ (!getiteminfo(.@id, ITEMINFO_TRADE))
+ ) {
+ @ShovelLastUsed = 0;
+ if (.@id == IronShovel || .@id == SteelShovel || checkbound(.@id))
+ mesc l("You cannot bury this item!");
+ else if (!getiteminfo(.@id, ITEMINFO_TRADE))
+ mesc l("This item is too precious, you cannot part with it!");
+ else
+ mesc l("You give up.");
+ close;
+ return;
}
.@amount = 1;
@@ -193,7 +210,17 @@ OnHour00:
OnInit:
.PlayerTiredTime = 20;
- AddDigRect("001-1", 172, 26, 200, 48);
+
+ // Partial maps
+ AddDigRect("001-1", 172, 26, 200, 48);
+ AddDigRect("008-1-1", 32, 42, 46, 88);
+ AddDigRect("008-1-2", 40, 52, 114, 146);
+ AddDigRect("012-1", 44, 21, 139, 47);
+
+ // Whole maps
+ AddMapDigRect("008-1");
+ AddMapDigRect("008-3-5");
+ AddMapDigRect("012-3-1");
end;
}
@@ -235,3 +262,97 @@ function script shovel_adddigrect {
set getvariableofnpc(.WorldDigRect_y2[.@size], strnpcinfo(3)), .@y2;
return 1;
}
+
+// [Treasure Map] functions
+
+function script shovel_getcity {
+ .@a$=getarg(0);
+
+ // else is not required (return prevails)
+ if (.@a$ == "001-1")
+ return l("Artis Hills");
+ if (.@a$ == "008-1")
+ return l("East Woodlands");
+ if (.@a$ == "008-1-1")
+ return l("West Woodland Beach");
+ if (.@a$ == "008-1-2")
+ return l("Swamps");
+ if (.@a$ == "008-3-5")
+ return l("Hurnscald Bandit Cave");
+ if (.@a$ == "012-1")
+ return l("Candor North");
+ if (.@a$ == "012-3-1")
+ return l("Candor Main Cave");
+
+ return .@a$;
+}
+
+function script shovel_randomtreasure {
+ .@id=any(TreasureKey,CoinBag,CoinBag,CoinBag,Coal,
+ Diamond,Ruby,Emerald,Sapphire,Topaz,Amethyst,
+ MaggotSlimePotion, LargeMana, LargeHealing);
+ delitem TreasureMap, 1;
+ .@amount=any(1,1,2);
+ // Very Commons
+ if (.@id == CoinBag || .@id == MaggotSlimePotion || .@id == TreasureKey)
+ .@amount+=any(0,1,0,1,2);
+ // Super commons
+ if (.@id == LargeMana || .@id == LargeHealing)
+ .@amount+=rand2(0,8);
+ // Rares
+ if (.@id == Coal)
+ .@amount=1;
+ getitem .@id, .@amount;
+ ShovelQuests_AssignedMAP$="";
+ ShovelQuests_AssignedX=0;
+ ShovelQuests_AssignedY=0;
+
+ mesn strcharinfo(0);
+ mesc l("You found something!");
+ mesc l("It's %d %s.", .@amount, getitemlink(.@id));
+ next;
+ closeclientdialog;
+ return;
+}
+
+function script shovel_genrandtreasure {
+ .@m$=any("008-1", "008-1-1", "008-1-2", "008-3-5",
+ "012-1", "012-3-1");
+
+ // Prepare good defaults
+ .@x1=.@y1=20;
+ .@x2=getmapinfo(MAPINFO_SIZE_X, .@m$)-20;
+ .@y2=getmapinfo(MAPINFO_SIZE_Y, .@m$)-20;
+
+ // Default overrides
+ if (.@m$ == "008-1-1") {
+ // West Woodland Beach
+ .@x1=32; .@y1=42;
+ .@x2=46; .@y2=88;
+ } else if (.@m$ == "008-1-2") {
+ // Swamps
+ .@x1=40; .@y1=52;
+ .@x2=114; .@y2=146;
+ } else if (.@m$ == "012-1") {
+ // Candor North
+ .@x1=44; .@y1=139;
+ .@x2=21; .@y2=47;
+ }
+
+ // Dangerous, but I never had issues with this
+ do {
+ .@x=rand2(.@x1, .@x2);
+ .@y=rand2(.@y1, .@y2);
+ } while (!checkcell(.@m$, .@x, .@y, cell_chkpass));
+
+ // Success
+ if (checkcell(.@m$, .@x, .@y, cell_chkpass)) {
+ shovel_addquest(.@m$, .@x, .@y, "shovel_randomtreasure");
+ ShovelQuests_AssignedMAP$=shovel_getcity(.@m$);
+ ShovelQuests_AssignedX=.@x;
+ ShovelQuests_AssignedY=.@y;
+ }
+ return;
+}
+
+
diff --git a/npc/scripts.conf b/npc/scripts.conf
index 330f6c62..29f1d588 100644
--- a/npc/scripts.conf
+++ b/npc/scripts.conf
@@ -48,9 +48,10 @@
"npc/functions/riddle.txt",
"npc/functions/bank.txt",
"npc/functions/confused-tree-dict.txt",
-"npc/functions/util.txt",
+"npc/functions/treasure.txt",
// May rely on custom functions and thus must be handled by last
+"npc/functions/util.txt",
"npc/functions/scoreboards.txt",
"npc/functions/manhole.txt",
"npc/functions/skills.txt",