Pokemon-style berry plant things?
Moderators: marionline, SDHawk
- Taco Bot
- Meat, Cheese, and Silicon
- Posts: 484
- Joined: Fri Jul 18, 2014 12:15 am
- Location: Santa Cruz
- Contact:
Pokemon-style berry plant things?
So, I'd like to implement a system sort of like the berry tree system from Pokemon Gold and Silver. Basically, the player can harvest berries (or whatever) from the tree, then they can come back later and harvest again. I'm not entirely sure how to differentiate the trees, maybe just have them all grow back when (systemMinute, mod, 30 == 0) or something for simplicity's sake?
And how would I go about storing the "harvested" data for each plant? A half-billion tags seems just a wee bit inefficient.
Sorry if I'm requesting scriptzilla over here, just wondering.
And how would I go about storing the "harvested" data for each plant? A half-billion tags seems just a wee bit inefficient.
Sorry if I'm requesting scriptzilla over here, just wondering.
Sent from my iPhone
You could do a real-time timer, but it might be nicer scripting-wise and gameplay-wise if you make timers based on steps taken. Then you can make an each-step script that advances a global time variable. You could make a fake array with globals or slices that hold each tree's "cooldown" length.
It also depends on how big the game is. Some ways might start to use too much memory if you have hundreds of trees.
If you want to do real-time, it could actually be pretty easy, although it would take a lot of tags or an array probably. If you make the tree an NPC that sets a timer on use, you could just write a script that recreates the NPC when the timer runs out. Each tree can have different growth periods if you utilize the NPC arguments.
EDIT: Let me know if any of that makes sense. I'm a bit tired and distracted.
It also depends on how big the game is. Some ways might start to use too much memory if you have hundreds of trees.
If you want to do real-time, it could actually be pretty easy, although it would take a lot of tags or an array probably. If you make the tree an NPC that sets a timer on use, you could just write a script that recreates the NPC when the timer runs out. Each tree can have different growth periods if you utilize the NPC arguments.
EDIT: Let me know if any of that makes sense. I'm a bit tired and distracted.
Last edited by kylekrack on Wed May 18, 2016 7:52 am, edited 1 time in total.
My pronouns are they/them
Ps. I love my wife
Ps. I love my wife
- Bob the Hamster
- Liquid Metal King Slime
- Posts: 7460
- Joined: Tue Oct 16, 2007 2:34 pm
- Location: Hamster Republic (Ontario Enclave)
- Contact:
This seems like treasure chests that re-fill after a certain amount of time.
You can probably make this work with one tag and one global variable per refilling treasure. You can possibly make it happen with just one script, but how that script works depends a lot on the specifics. I think msw188 is correct that NPC extra data could make this easier.
1) How exactly do you want to make the refill timing work?
* A real-time timer? It would keep counting even if the player exits the game and goes to browse reddit for an hour instead
* A gameplay timer? Would only count actual play time (similar to the count of playtime on the save/load screens)
* A step-timer? As kylekrack suggests. This wouldn't count time in battles or menus or textboxes, or just sitting still doing nothing.
2) Should all the treasures re-fill at the same speed? If you want 1 tree that re-grows in half the speed, and another that regrows in 5 times the speed, then the script will need to be a lot more complicated, and you might need 2 globals per treasure.
With those questions answered, I can probably help you come up with a script that does what you want.
You can probably make this work with one tag and one global variable per refilling treasure. You can possibly make it happen with just one script, but how that script works depends a lot on the specifics. I think msw188 is correct that NPC extra data could make this easier.
1) How exactly do you want to make the refill timing work?
* A real-time timer? It would keep counting even if the player exits the game and goes to browse reddit for an hour instead
* A gameplay timer? Would only count actual play time (similar to the count of playtime on the save/load screens)
* A step-timer? As kylekrack suggests. This wouldn't count time in battles or menus or textboxes, or just sitting still doing nothing.
2) Should all the treasures re-fill at the same speed? If you want 1 tree that re-grows in half the speed, and another that regrows in 5 times the speed, then the script will need to be a lot more complicated, and you might need 2 globals per treasure.
With those questions answered, I can probably help you come up with a script that does what you want.
Last edited by Bob the Hamster on Wed May 18, 2016 3:45 pm, edited 1 time in total.
- Bob the Hamster
- Liquid Metal King Slime
- Posts: 7460
- Joined: Tue Oct 16, 2007 2:34 pm
- Location: Hamster Republic (Ontario Enclave)
- Contact:
Okay!
Now we are in business!
First, make a treasure NPC. You can't use the one-time tags for this, so you need to use a tag. If the tag is ON then the NPC vanishes. Each re-filling treasure will need its own tag
Now lets pick a block of global variables. Lets say globals 2000 through 2100 are going to be used for refilling treasure boxes. You can pick whatever sized range you think is appropriate for your game.
When you create your treasure NPC, put its global variable in the "script argument"
Here are the scripts you will need:
The "take refillable treasure" script should be run when activating any of your treasure NPCs.
The "eachstep refiller update" script should be the each-step script for every map (or you can call it indirectly for maps that already have some other eachstep script)
I suggest setting the "refiller steps" constant to something much lower than 100 while you are testing this out.
(DISCLAIMER, I haven't tested any of this in a game yet, but I think it will work, and I can help if it doesn't work)
Now we are in business!
First, make a treasure NPC. You can't use the one-time tags for this, so you need to use a tag. If the tag is ON then the NPC vanishes. Each re-filling treasure will need its own tag
It is up to you to keep track of which tags get used for this. You can name them however you want, and they don't need to be in order.Appear If Tag ##=OFF
Now lets pick a block of global variables. Lets say globals 2000 through 2100 are going to be used for refilling treasure boxes. You can pick whatever sized range you think is appropriate for your game.
When you create your treasure NPC, put its global variable in the "script argument"
It is up to you to keep track of which globals and tags have already been used for refillable treasures.Script Argument: 2000
Here are the scripts you will need:
Code: Select all
# Use globals 2000 thru 2100
define constant(2000, first refiller)
define constant(2100, last refiller)
# You don't need to name any of these globals with "global variable()"
# Just take care not to use them for anything else.
define constant(100, refiller steps)
# This is the number of steps that the player has to walk
# in order to refill any particular treasure.
define constant(123, found item textbox)
define constant(0, string for putting item name in textbox)
# This textbox should say "Found a ${S0}"
# If you are already using script string 0 for something else,
# you might need to use a different string ID number
plotscript, take refillable treasure, arg, npc, begin
# You should already have the item just by activating the NPC,
# but it would be nice to show a textbox saying so.
variable(item)
item := read NPC(npc, NPCstat:giveitem) -- 1
if(item < 0) then(exit script)
# Store the item name in a global so we can embed it in a generic textbox.
# If you are already using script string 0 for something else,
# you might need to use a different string ID number
get item name(string for putting item name in textbox, item)
show text box(found item textbox)
wait for textbox
# Now we turn on the tag that makes this NPC vanish
variable(tag)
tag := abs(read NPC(npc, 9))
# NPCstat 9 is undocumented. It is the first NPC appearance tag number. positive for ON and negative for OFF
# Although undocumented, James will not break it in future versions, so it is safe to use.
# James also totally *should* document it. Why hasn't he done that yet?
set tag(tag, ON)
# Now we update the global variable that tracks how long it will be until the treasure reappears
write global(arg, refiller steps)
end
plotscript, eachstep refiller update, begin
# Subtract 1 from each global
variable(i, g)
for(i, first refiller, last refiller) do(
g := read global(i)
if(g > 0) then(
write global(i, g -- 1)
)
)
# Search the current map for re-usable treasure NPCs
variable(ID, arg, tag)
for(ID, 0, 499) do(
arg := read NPC(ID, NPCstat:scriptargument)
if(arg >= first refiller && arg <= last refiller) then(
# This NPC ID is a refillable treasure
g := read global(arg)
if(g == 0) then(
# The global counter for this NPC has run out!
tag := abs(read NPC(ID, 9))
# Make the NPC reappear
set tag(tag, OFF)
)
)
)
end
The "eachstep refiller update" script should be the each-step script for every map (or you can call it indirectly for maps that already have some other eachstep script)
Code: Select all
plotscript, my other eachstep thingie, begin
eachstep refiller update
# then do a
# bunch of
# other stuff
# right here
end
(DISCLAIMER, I haven't tested any of this in a game yet, but I think it will work, and I can help if it doesn't work)
Last edited by Bob the Hamster on Wed May 18, 2016 5:39 pm, edited 2 times in total.
- Taco Bot
- Meat, Cheese, and Silicon
- Posts: 484
- Joined: Fri Jul 18, 2014 12:15 am
- Location: Santa Cruz
- Contact:
Alright, it appears to be kinda working? This is my modified version of the script (set up to match my game's stuff)
And the necessary constants n 'variables:
The only problem I'm having is that every step, the script throws an error for every single undefined NPC up to 499 (so like 490 errors).
Code: Select all
plotscript, berryGet, arg, npc, begin
variable(i)
variable(item)
variable(tag)
variable(bushType)
i := random (berryMin, berryMax)
doWhateverWithThis := i
bushType := readNpc(npc, npcStat:palette) -- 23
if (bushType == col:red) then (
getItem(item:¡ Red, i)
$str:doWhateverWithMe = "Red"
) else if (bushType == col:orange) then (
getItem(item:¡ Orange, i)
$str:doWhateverWithMe = "Orange"
) else if (bushType == col:yellow) then (
getItem(item:¡ Yellow, i)
$str:doWhateverWithMe = "Yellow"
) else if (bushType == col:green) then (
getItem(item:¡ Green, i)
$str:doWhateverWithMe = "Green"
) else if (bushType == col:blue) then (
getItem(item:¡ Blue, i)
$str:doWhateverWithMe = "Blue"
) else if (bushType == col:purple) then (
getItem(item:¡ Purple, i)
$str:doWhateverWithMe = "Purple"
)
showTextBox(text:berryGet)
waitForTextbox
tag := abs(readNpc(npc, 9))
setTag(tag, on)
writeGlobal(arg, refillSteps)
end
plotscript, berryRefillUpdate, begin
variable(i, g)
for (i, berryArrayStart, berryArrayEnd) do (
g := readGlobal(i)
if (g > 0) then (
writeGlobal(i, g -- 1)
)
)
variable(ID, arg, tag)
for (ID, 0, 499) do (
arg := readNpc(ID, NpcStat:scriptargument)
if (arg >= berryArrayStart && arg <= berryArrayEnd) then (
g := readGlobal(arg)
if (g == 0) then (
tag := abs(readNpc(ID, 9))
setTag(tag, off)
)
)
)
end
Code: Select all
define constant, begin
### Strings
1, str:doWhateverWithMe
### Textboxes
174, text:berryGet
### Palettes
24, pal:redBB
25, pal:orangeBB
26, pal:yellowBB
27, pal:greenBB
28, pal:blueBB
29, pal:purpleBB
### Colours
1, col:red
2, col:orange
3, col:yellow
4, col:green
5, col:blue
6, col:purple
### Other Stuff
5, berryMin
10, berryMax
500, refillSteps
5000, berryArrayStart
7000, berryArrayEnd
end
global variable, begin
1, doWhateverWithThis
end
Last edited by Taco Bot on Thu May 19, 2016 4:13 am, edited 1 time in total.
Sent from my iPhone
- Taco Bot
- Meat, Cheese, and Silicon
- Posts: 484
- Joined: Fri Jul 18, 2014 12:15 am
- Location: Santa Cruz
- Contact:
Attached is the error message. Hopefully useful.
- Attachments
-
- Error message
- grapnes20001.bmp (63.55 KiB) Viewed 591 times
Last edited by Taco Bot on Thu May 19, 2016 5:41 am, edited 1 time in total.
Sent from my iPhone
- Bob the Hamster
- Liquid Metal King Slime
- Posts: 7460
- Joined: Tue Oct 16, 2007 2:34 pm
- Location: Hamster Republic (Ontario Enclave)
- Contact:
- Bob the Hamster
- Liquid Metal King Slime
- Posts: 7460
- Joined: Tue Oct 16, 2007 2:34 pm
- Location: Hamster Republic (Ontario Enclave)
- Contact:
Oh! I looked at the plotscript dictionary, and realized that TMC implemented a really nice command for just this purpose!
the "next NPC reference" command is perfect for looping through all the NPCs on the map.
the "next NPC reference" command is perfect for looping through all the NPCs on the map.
Code: Select all
plotscript, berryRefillUpdate, begin
variable(i, g)
for (i, berryArrayStart, berryArrayEnd) do (
g := readGlobal(i)
if (g > 0) then (
writeGlobal(i, g -- 1)
)
)
variable(ref, arg, tag)
ref := next NPC reference() # The first NPC
while(ref) do(
arg := readNpc(ref, NpcStat:scriptargument)
if (arg >= berryArrayStart && arg <= berryArrayEnd) then (
g := readGlobal(arg)
if (g == 0) then (
tag := abs(readNpc(ref, 9))
setTag(tag, off)
)
)
ref := next NPC reference(ref)
)
end
- Taco Bot
- Meat, Cheese, and Silicon
- Posts: 484
- Joined: Fri Jul 18, 2014 12:15 am
- Location: Santa Cruz
- Contact:
Oh bother. Now the plants aren't refilling at all... :/
The tags and arguments are set right, and I can't see what's wrong with the scripts.
Scriptoes:
The tags and arguments are set right, and I can't see what's wrong with the scripts.
Scriptoes:
Code: Select all
plotscript, berryGet, arg, npc, begin
variable(i, item, tag, bushType)
i := random (berryMin, berryMax)
doWhateverWithThis := i
bushType := readNpc(npc, npcStat:palette) -- 23
if (bushType == col:red) then (
getItem(item:¡ Red, i)
$str:doWhateverWithMe = "Red"
) else if (bushType == col:orange) then (
getItem(item:¡ Orange, i)
$str:doWhateverWithMe = "Orange"
) else if (bushType == col:yellow) then (
getItem(item:¡ Yellow, i)
$str:doWhateverWithMe = "Yellow"
) else if (bushType == col:green) then (
getItem(item:¡ Green, i)
$str:doWhateverWithMe = "Green"
) else if (bushType == col:blue) then (
getItem(item:¡ Blue, i)
$str:doWhateverWithMe = "Blue"
) else if (bushType == col:purple) then (
getItem(item:¡ Purple, i)
$str:doWhateverWithMe = "Purple"
)
showTextBox(text:berryGet)
waitForTextbox()
tag := abs(readNpc(npc, 9))
setTag(tag, on)
writeGlobal(arg, refillSteps)
end
plotscript, berryRefillUpdate, begin
variable(i, g)
for (i, berryArrayStart, berryArrayEnd) do (
g := readGlobal(i)
if (g > 0) then (
writeGlobal(i, g -- 1)
)
)
variable(ref, arg, tag)
ref := nextNpcReference()
while (ref) do (
arg := readNpc(ref, npcStat:scriptargument)
if (arg >= berryArrayStart && arg <= berryArrayEnd) then (
g := readGlobal(arg)
if (g == 0) then (
tag := abs(readNpc(ref, 9))
setTag(tag, off)
)
)
ref := nextNpcReference(ref)
)
end
Sent from my iPhone
- Bob the Hamster
- Liquid Metal King Slime
- Posts: 7460
- Joined: Tue Oct 16, 2007 2:34 pm
- Location: Hamster Republic (Ontario Enclave)
- Contact:
Hmmm... how about adding a
right at the top of the each step script (or 2001 or 2005 or whatever global goes with the bush NPC that you are using for testing)
Then you can see if the global is actually counting down as you walk. that will help narrow down the problem.
Code: Select all
show value(read global(2000))Then you can see if the global is actually counting down as you walk. that will help narrow down the problem.