Commit 7fa4a1e4 authored by Jesusaves's avatar Jesusaves Committed by Micksha

Random, Wild Treasure Chests were sighted in Hurnscald Caves!

Watch out for them!
parent 6e464f61
......@@ -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"
}
......@@ -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
......
......@@ -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
......
......@@ -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;
......
......@@ -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."),
......
......@@ -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)
{
......
// 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) {
......
// 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([email protected]$, .name$, "_");
[email protected][email protected]$[1];
//if ([email protected]$ == "") 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
// 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;
}
......@@ -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",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment