Pokemon-style berry plant things?

Ask and answer questions about making games and related topics. Unrelated topics go in that other forum.

Moderators: marionline, SDHawk

User avatar
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?

Post by Taco Bot »

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.
Sent from my iPhone
User avatar
kylekrack
Liquid Metal Slime
Posts: 1188
Joined: Mon Jun 16, 2014 8:58 am
Location: USA
Contact:

Post by kylekrack »

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.
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
User avatar
msw188
Metal Slime
Posts: 783
Joined: Tue Oct 16, 2007 1:43 am
Location: Los Angeles, CA

Post by msw188 »

NPCs have extra data assigned just to them. Seems like this could be helpful here.
I am Srime
User avatar
Bob the Hamster
Liquid Metal King Slime
Posts: 7460
Joined: Tue Oct 16, 2007 2:34 pm
Location: Hamster Republic (Ontario Enclave)
Contact:

Post by Bob the Hamster »

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.
Last edited by Bob the Hamster on Wed May 18, 2016 3:45 pm, edited 1 time in total.
User avatar
Taco Bot
Meat, Cheese, and Silicon
Posts: 484
Joined: Fri Jul 18, 2014 12:15 am
Location: Santa Cruz
Contact:

Post by Taco Bot »

To keep it simple, I'd probably go with a step timer, and they probably would refill at the same speed.
Sent from my iPhone
User avatar
kylekrack
Liquid Metal Slime
Posts: 1188
Joined: Mon Jun 16, 2014 8:58 am
Location: USA
Contact:

Post by kylekrack »

Does HamsterSpeak have any equivalent to java type classes? It'd be easier to store information if you could throw multiple parameters to a reference.
My pronouns are they/them
Ps. I love my wife
User avatar
Bob the Hamster
Liquid Metal King Slime
Posts: 7460
Joined: Tue Oct 16, 2007 2:34 pm
Location: Hamster Republic (Ontario Enclave)
Contact:

Post by Bob the Hamster »

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
Appear If Tag ##=OFF
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.

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"
Script Argument: 2000
It is up to you to keep track of which globals and tags have already been used for refillable treasures.

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&#40;item < 0&#41; then&#40;exit script&#41;
  # 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&#40;string for putting item name in textbox, item&#41;
  show text box&#40;found item textbox&#41;
  wait for textbox 

  # Now we turn on the tag that makes this NPC vanish
  variable&#40;tag&#41;
  tag &#58;= abs&#40;read NPC&#40;npc, 9&#41;&#41;
  # 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&#40;tag, ON&#41;

  # Now we update the global variable that tracks how long it will be until the treasure reappears
  write global&#40;arg, refiller steps&#41;

end

plotscript, eachstep refiller update, begin
  # Subtract 1 from each global
  variable&#40;i, g&#41;
  for&#40;i, first refiller, last refiller&#41; do&#40;
    g &#58;= read global&#40;i&#41;
    if&#40;g > 0&#41; then&#40;
      write global&#40;i, g -- 1&#41;
    &#41;
  &#41;
  
  # Search the current map for re-usable treasure NPCs
  variable&#40;ID, arg, tag&#41;
  for&#40;ID, 0, 499&#41; do&#40;
    arg &#58;= read NPC&#40;ID, NPCstat&#58;scriptargument&#41;
    if&#40;arg >= first refiller && arg <= last refiller&#41; then&#40;
      # This NPC ID is a refillable treasure
      g &#58;= read global&#40;arg&#41;
      if&#40;g == 0&#41; then&#40;
        # The global counter for this NPC has run out!
        tag &#58;= abs&#40;read NPC&#40;ID, 9&#41;&#41;
        # Make the NPC reappear
        set tag&#40;tag, OFF&#41;
      &#41;
    &#41;
  &#41;
end
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)

Code: Select all

plotscript, my other eachstep thingie, begin
  eachstep refiller update
 # then do a
 # bunch of
 # other stuff
 # right here
end
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)
Last edited by Bob the Hamster on Wed May 18, 2016 5:39 pm, edited 2 times in total.
User avatar
kylekrack
Liquid Metal Slime
Posts: 1188
Joined: Mon Jun 16, 2014 8:58 am
Location: USA
Contact:

Post by kylekrack »

This feels like good wiki material.
My pronouns are they/them
Ps. I love my wife
User avatar
Taco Bot
Meat, Cheese, and Silicon
Posts: 484
Joined: Fri Jul 18, 2014 12:15 am
Location: Santa Cruz
Contact:

Post by Taco Bot »

Alright, it appears to be kinda working? This is my modified version of the script (set up to match my game's stuff)

Code: Select all

plotscript, berryGet, arg, npc, begin
   variable&#40;i&#41;
   variable&#40;item&#41;
   variable&#40;tag&#41;
   variable&#40;bushType&#41;
   i &#58;= random &#40;berryMin, berryMax&#41;
   doWhateverWithThis &#58;= i
   bushType &#58;= readNpc&#40;npc, npcStat&#58;palette&#41; -- 23
   if &#40;bushType == col&#58;red&#41; then &#40;
      getItem&#40;item&#58;¡ Red, i&#41;
      $str&#58;doWhateverWithMe = "Red"
   &#41; else if &#40;bushType == col&#58;orange&#41; then &#40;
      getItem&#40;item&#58;¡ Orange, i&#41;
      $str&#58;doWhateverWithMe = "Orange"		
   &#41; else if &#40;bushType == col&#58;yellow&#41; then &#40;
      getItem&#40;item&#58;¡ Yellow, i&#41;
      $str&#58;doWhateverWithMe = "Yellow"
   &#41; else if &#40;bushType == col&#58;green&#41; then &#40;
      getItem&#40;item&#58;¡ Green, i&#41;
      $str&#58;doWhateverWithMe = "Green"
   &#41; else if &#40;bushType == col&#58;blue&#41; then &#40;
      getItem&#40;item&#58;¡ Blue, i&#41;
      $str&#58;doWhateverWithMe = "Blue"
   &#41; else if &#40;bushType == col&#58;purple&#41; then &#40;
      getItem&#40;item&#58;¡ Purple, i&#41;
      $str&#58;doWhateverWithMe = "Purple"
   &#41;
   showTextBox&#40;text&#58;berryGet&#41;
   waitForTextbox
   tag &#58;= abs&#40;readNpc&#40;npc, 9&#41;&#41;
   setTag&#40;tag, on&#41;
   writeGlobal&#40;arg, refillSteps&#41;
end

plotscript, berryRefillUpdate, begin
   variable&#40;i, g&#41;
   for &#40;i, berryArrayStart, berryArrayEnd&#41; do &#40;
      g &#58;= readGlobal&#40;i&#41;
      if &#40;g > 0&#41; then &#40;
         writeGlobal&#40;i, g -- 1&#41;
      &#41;
   &#41;
   variable&#40;ID, arg, tag&#41;
   for &#40;ID, 0, 499&#41; do &#40;
      arg &#58;= readNpc&#40;ID, NpcStat&#58;scriptargument&#41;
      if &#40;arg >= berryArrayStart && arg <= berryArrayEnd&#41; then &#40;
         g &#58;= readGlobal&#40;arg&#41;
         if &#40;g == 0&#41; then &#40;
            tag &#58;= abs&#40;readNpc&#40;ID, 9&#41;&#41;
            setTag&#40;tag, off&#41;
         &#41;
      &#41;
   &#41;
end
And the necessary constants n 'variables:

Code: Select all

define constant, begin
   ### Strings
   1, str&#58;doWhateverWithMe
   ### Textboxes
   174, text&#58;berryGet
   ### Palettes
   24, pal&#58;redBB
   25, pal&#58;orangeBB
   26, pal&#58;yellowBB
   27, pal&#58;greenBB
   28, pal&#58;blueBB
   29, pal&#58;purpleBB
   ### Colours
   1, col&#58;red
   2, col&#58;orange
   3, col&#58;yellow
   4, col&#58;green
   5, col&#58;blue
   6, col&#58;purple
   ### Other Stuff
   5, berryMin
   10, berryMax
   500, refillSteps
   5000, berryArrayStart
   7000, berryArrayEnd
end

global variable, begin
   1, doWhateverWithThis
end
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).
Last edited by Taco Bot on Thu May 19, 2016 4:13 am, edited 1 time in total.
Sent from my iPhone
User avatar
Taco Bot
Meat, Cheese, and Silicon
Posts: 484
Joined: Fri Jul 18, 2014 12:15 am
Location: Santa Cruz
Contact:

Post by Taco Bot »

Attached is the error message. Hopefully useful.
Attachments
Error message
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
User avatar
Bob the Hamster
Liquid Metal King Slime
Posts: 7460
Joined: Tue Oct 16, 2007 2:34 pm
Location: Hamster Republic (Ontario Enclave)
Contact:

Post by Bob the Hamster »

Oh! I forgot about those error messages.

I can come up with a workaround. Give me a bit to think about it...
User avatar
Taco Bot
Meat, Cheese, and Silicon
Posts: 484
Joined: Fri Jul 18, 2014 12:15 am
Location: Santa Cruz
Contact:

Post by Taco Bot »

Is there any command that can return whether or not an NPC definition exists? Because then I could just iterate through all the NPCs until it returns false, and save that number to a variable which I could replace the "499" with.
Sent from my iPhone
User avatar
Bob the Hamster
Liquid Metal King Slime
Posts: 7460
Joined: Tue Oct 16, 2007 2:34 pm
Location: Hamster Republic (Ontario Enclave)
Contact:

Post by Bob the Hamster »

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.

Code: Select all

plotscript, berryRefillUpdate, begin
   variable&#40;i, g&#41;
   for &#40;i, berryArrayStart, berryArrayEnd&#41; do &#40;
      g &#58;= readGlobal&#40;i&#41;
      if &#40;g > 0&#41; then &#40;
         writeGlobal&#40;i, g -- 1&#41;
      &#41;
   &#41;
   variable&#40;ref, arg, tag&#41;
   ref &#58;= next NPC reference&#40;&#41;  # The first NPC
   while&#40;ref&#41; do&#40;
      arg &#58;= readNpc&#40;ref, NpcStat&#58;scriptargument&#41;
      if &#40;arg >= berryArrayStart && arg <= berryArrayEnd&#41; then &#40;
         g &#58;= readGlobal&#40;arg&#41;
         if &#40;g == 0&#41; then &#40;
            tag &#58;= abs&#40;readNpc&#40;ref, 9&#41;&#41;
            setTag&#40;tag, off&#41;
         &#41;
      &#41;
      ref &#58;= next NPC reference&#40;ref&#41;
   &#41;
end 
User avatar
Taco Bot
Meat, Cheese, and Silicon
Posts: 484
Joined: Fri Jul 18, 2014 12:15 am
Location: Santa Cruz
Contact:

Post by Taco Bot »

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:

Code: Select all

plotscript, berryGet, arg, npc, begin
	variable&#40;i, item, tag, bushType&#41;
	i &#58;= random &#40;berryMin, berryMax&#41;
	doWhateverWithThis &#58;= i
	bushType &#58;= readNpc&#40;npc, npcStat&#58;palette&#41; -- 23
	if &#40;bushType == col&#58;red&#41; then &#40;
		getItem&#40;item&#58;¡ Red, i&#41;
		$str&#58;doWhateverWithMe = "Red"
	&#41; else if &#40;bushType == col&#58;orange&#41; then &#40;
		getItem&#40;item&#58;¡ Orange, i&#41;
		$str&#58;doWhateverWithMe = "Orange"		
	&#41; else if &#40;bushType == col&#58;yellow&#41; then &#40;
		getItem&#40;item&#58;¡ Yellow, i&#41;
		$str&#58;doWhateverWithMe = "Yellow"
	&#41; else if &#40;bushType == col&#58;green&#41; then &#40;
		getItem&#40;item&#58;¡ Green, i&#41;
		$str&#58;doWhateverWithMe = "Green"
	&#41; else if &#40;bushType == col&#58;blue&#41; then &#40;
		getItem&#40;item&#58;¡ Blue, i&#41;
		$str&#58;doWhateverWithMe = "Blue"
	&#41; else if &#40;bushType == col&#58;purple&#41; then &#40;
		getItem&#40;item&#58;¡ Purple, i&#41;
		$str&#58;doWhateverWithMe = "Purple"
	&#41;
	showTextBox&#40;text&#58;berryGet&#41;
	waitForTextbox&#40;&#41;
	tag &#58;= abs&#40;readNpc&#40;npc, 9&#41;&#41;
	setTag&#40;tag, on&#41;
	writeGlobal&#40;arg, refillSteps&#41;
end

plotscript, berryRefillUpdate, begin
	variable&#40;i, g&#41;
	for &#40;i, berryArrayStart, berryArrayEnd&#41; do &#40;
		g &#58;= readGlobal&#40;i&#41;
		if &#40;g > 0&#41; then &#40;
			writeGlobal&#40;i, g -- 1&#41;
		&#41;
	&#41;
	variable&#40;ref, arg, tag&#41;
	ref &#58;= nextNpcReference&#40;&#41;
	while &#40;ref&#41; do &#40;
		arg &#58;= readNpc&#40;ref, npcStat&#58;scriptargument&#41;
		if &#40;arg >= berryArrayStart && arg <= berryArrayEnd&#41; then &#40;
			g &#58;= readGlobal&#40;arg&#41;
			if &#40;g == 0&#41; then &#40;
				tag &#58;= abs&#40;readNpc&#40;ref, 9&#41;&#41;
				setTag&#40;tag, off&#41;
			&#41;
		&#41;
		ref &#58;= nextNpcReference&#40;ref&#41;
	&#41;
end
Sent from my iPhone
User avatar
Bob the Hamster
Liquid Metal King Slime
Posts: 7460
Joined: Tue Oct 16, 2007 2:34 pm
Location: Hamster Republic (Ontario Enclave)
Contact:

Post by Bob the Hamster »

Hmmm... how about adding a

Code: Select all

show value&#40;read global&#40;2000&#41;&#41;
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.
Post Reply