Reverse Concatenation


#1

I understand how concatenation works, but is there a way to reverse it, to pull data out of a concatenated string, if I used a separator.

Here is an example:

I have a NPC follower that I want to replace with another NPC follower, but when I dismiss the first follower I would like to be able to rehire him later in the game with all his current stats and inventory intact. If I concatenate all his data into a string with separators, say... "Name|Armor|Weapon|HP" etc... Is there a way to extract the data from the string back into the appropriate variables using only choicescript, or would I have to use *script?

I could create separate variables for every stat for every companion in the above example, but this is not practical in the game I am working on.

I have tried searching the forums and the documentation with no luck.

I am thinking that some sort of loop is the answer, just not sure how to identify the separator.

Any help would be appreciated.

cryptickosh,


#2

Something along these lines?

Might also be worth looking into arrays, mentioned in this topic:


#3

It would be simpler to just use a fake associative array, e.g.:

*create str_bruiser 10
*create dex_bruiser 4
*create int_bruiser 2

*set followername "bruiser"
${str[followername]} is equal to 10

#4

That would definitely work, though it would not be elegant. Then again, what I'm attempting isn't really elegant either.

Just looking at that syntax and usage, I think I'd have to set up a loop that extracted a letter, checked whether or not it was the separator, if it wasn't to pass it to a temp variable and concat it with anything else currently there. If it was the separator, dump the current value of the temp variable to the appropriate stat variable and then proceed to run it again through the rest of the string.

As long as I always stored the same number of values, even if some of them are empty, then this should work.

Anyone have any thoughts on a simpler method?

cryptickosh,


#5

@CJW How could I use that to accomplish what I am trying in my example? I am not seeing how that solves the problem?

Could you explain?

cryptickosh,


#6

You're retaining all follower data, just via easily accessible variables, not long and horrible to parse strings.

Two followers:

*create str_bruiser 10
*create dex_bruiser 4
*create int_bruiser 2

*create str_archer 6
*create dex_archer 8
*create int_archer 4

Whenever you want to increase your current follower's stats, or check them, use the array syntax:

${str[followername]}

And

*set str[followername] 20

Then when you want to change your follower, simply:

*set followername "archer"

If you follow that pattern, you'll achieve the same effect.


#7

It might make more sense if I use your example stats:

*create hp_archer 10
*create name_archer "Deadshot"
*create armor_archer "leather"

...
*set follower "archer"
${name[follower]} has ${hp[follower}HP and is equipped with ${armor[follower]} armor.

#8

@CJW Okay, that would work, but unless I'm misunderstanding, I would still have to create individual variables for each followers stats. str_bruiser, dex_bruiser, int_bruiser, str_archer, dex_archer, int_archer, etc... Accessing them via array is definitely the easy way to reference the values. But the thing I'm trying to avoid is the creation of all of those variables.

The plan is create a list of active variables, for the above example...

active_companion_name ""
active_companion_armor ""
active_companion_weapon ""
active companion_hp 100

Then, when I switch to another companion, send all that data to one variable, something like companion1_stats "Bob|Plate|Great Sword|100"

This would allow me to store a lot of data about them in a single variable. While in the above example, creating all those variables would not be that bad. My actual usage, would be more extreme. I currently have 20 vaules per person I want to track, and I want to do that with greater than 100 characters.

I understand that it is probably a little crazy to attempt with choicescript. I would probably be better served using a full fledged programming language, but I like the challenge of trying to do it in choicescript and as efficiently as possible.


#9

String parsing with # and the like is your only option then. That's not going to be any sort of efficient, but if you're only doing it occasionally (i.e. not madly looping over it), it should be fine.

I'd still recommend the array method though. If you're adverse to lots of typing you can precompute the create list, with another language or script. Actually, you could even do this in CS if you wanted:

*create follower_stat_1 "name"
*create follower_stat_2 "hp"
*create follower_stat_3 "armour"
*create follower_stat_4 "weapon"

*comment how many stats above?
*temp stat_count 4
*comment how many followers?
*temp char_count 10

*temp char 0
*temp stat 0
*label char_loop
*set char + 1
*if char <= char_count
    *label stat_loop
    *set stat + 1
    *if stat <= stat_count
        *comment only way to print * commands:
        *temp str "*create follower_${follower_stat[stat]}_${char}"
        ${str}
        *line_break
        *goto stat_loop
    *set stat 0
    *goto char_loop

Just copy and paste the result of that into your game's startup.txt. You'll need to tweak it if you want to reference stats by a name and not a numerical id though (homework task! :wink:).


#10

@CJW I was afraid of that. My issue isn't with the typing, I was just trying to avoid a huge startup file. With thousands of variables in it. Since I want to allow saving, that would create a monster save file too.

Though I just thought of another issue that may necessitate me creating them all anyway.

I'm not aware of anyway way in choicescript to change the type of input. For instance in my example, if I store the HP as "100" along with the other information, when I pull it back out it will be text, not a number, because choicescript variables are dynamically typed.


#11

You're storing exactly the same amount of the data. In modern browsers the use of the extra variables will be a negligible overhead, maybe if you get into the thousands there will be a slight pause on your game's startup, but otherwise you won't notice a difference. ChoiceScript is dynamically typed, but it will also implicitly convert, like so:

*temp num "12"
*temp result (5 + num)
${result} = 17

#12

@CJW That last bit is good to know. Yeah, I guess I will just go ahead and create them all implicity. While it will mean a ton of variables, it will probably be easier in the long run than debugging the loop necessary to make my previous idea work.

Thank you for the responses.

cryptickosh,


#13

This kind of thing can definitely be done. I wrote a password system in pure ChoiceScript that works basically the same way you suggested, but it does cause quite a bit of lag, and I honestly don't know what would happen if it was ever ported to a published version.


#14

@stainedofmind I'm not that worried about publishing. What I'm working on is more of a "I wonder if it can be done" kind of project. I'm sure the creators of the game I'm recreating in choicescript would not be happy if it was published, but as a pure exercise it will be interesting to some people.

The plan is to get the various mechanics working, then model just enough of the game to demonstrate it works and then post it. It will essentially give people a framework to make similar games.