Will Script For Food :-)

Users who are viewing this thread

Lav

Sergeant Knight at Arms
This thread contains scripting requests that have been accepted by myself as a freebie for the community.

There are no guarantees that any accepted request will actually be delivered, but there's a guarantee that I'll either deliver the code or notify that I'm not going to. :smile:

Early requests are more likely to be implemented than late requests.

If you are reading this, any request you might have is a late request. But there's always a chance if I find your request really interesting and have the time.

Two exceptions:

One, I'm just not interested in multiplayer. Like, at all. Got enough of this without Warband. :smile:

Two, I'm doing OSP stuff. If you want to get some code that won't make sense as an individual OSP pack, well, sorry, but please ask someone else.


Active Requests

1. Improved Trading Interface by Duh. Under discussion.
2. Two new buildings (Hospital and Mine) by Frenzied_Crocoduck_Herder. Considered for implementation.
3. Alliance war feature by Frenzied_Crocoduck_Herder. Too complex.
4. Prisoner purchasing faction (Night Watch or Ottoman Janissaries) by produno. Considered for implementation.
5. Mining system (reference: Skyrim) by 9jakub9. Completed (URL).
6. Crafting system (reference: Skyrim) by 9jakub9. In progress.

I'm bored ATM, so requests for scripts are being accepted (except requests for MP code).

All code will be considered OSP.

This is a short time offer.
 
I am looking for somebody to do pretty presentations for my eco system. Everything is supposed to be osp.

To be more specific, it would be a barter presentation that replaces the native inventory trading and works with the player proposing deals and the merchant making a decision on whether its sensible to agree to the proposal or not (based on the market, relationship, trading skill).

M.png
 
Duh said:
I am looking for somebody to do pretty presentations for my eco system. Everything is supposed to be osp.

To be more specific, it would be a barter presentation that replaces the native inventory trading and works with the player proposing deals and the merchant making a decision on whether its sensible to agree to the proposal or not (based on the market, relationship, trading skill).

M.png
Looks interesting but there are many ways to interpret your screen.

Hmm, let's put it like this. In vanilla game, player moves items he wants to sell to merchant's inventory and items he wants to buy to his own inventory, while the game tracks the price difference as the transaction amount. You want to keep traded items in a separate area in the middle, that's understandable, but apart from that, what are the differences from vanilla barter? What are the intended mechanics behind the offer/counteroffer functionality? Essentially, what you are trying to achieve? If you could provide a few use-cases that would show how your system is different and/or better than vanilla, it would hopefully help to understand it.
 
I am typing this from my cell so please bear with the typos. My hands are closer to paws than to fingers.

The eco system aims beyond just a new trade screen. The real goal is to increase th scope within which the player can interact with the economy. Natively there is a very complex system in place, but one sees very little of it ingame - the accesability is quite limited in the way it is presenred and to what extent the player can impact it.

To change that i took out natives system, which i felt was sometimrs to precise (herds and fields and shipping fleets one would never see) and replaced it with a system that revolves around population and prosperity. I picked a number of consumption values that seemed reasonable, but are in the end arbitrary and not really important (aside from the total vase worth produced) and added in some randomization elements with a stage of productiob (agricultral up to processed) and a limit for the population that can be supported. The system develops in a cycle in that a town produces surplus which leads to wealth which causes pop to grow which in turn eventually leads to an overconsumption and deficit and so on.

All of this required a review of how goods ahould be handled and how rrade should and could be done. In these dimensions, i decided slots would work much better and more precisely than the native trade items.

The actual barter process should consider whether a good is locally produced, whether it is locally or factionally availavle, whether its demand type is satisfied (f.e. food), how well the player is liked and how good hos trading skill is.

This ties directly into a towns wealth and they should usually profit from such a transaction. That means they ll want to earn more than what they d get from the script logic that governs local growth.

I would however be perfectly fine with taking care of the logic myself, i just dont excell at making things enjoyable to look at ( like say your companion oberseer) :grin:

If you find this generally interesting - i should be home in a few hours, so just send me your steam nick via pm and i ll get in touch with you there. Should you prefer to keep things on the forum, just ask away here or via pm. It may take a little bit of time to present the project fully.
 
If you need work, you could always take over the role of scripting for Calradia: Imperial Age? :lol: If you won't do that, then could you show me how to stop vassals from receiving reinforcements from the party templates, and stop them from upgrading their troops?

I have a script from a friend that I want to implement, but I want to make sure the two tasks above are out of the way.
 
Frenzied_Crocoduck_Herder said:
If you need work, you could always take over the role of scripting for Calradia: Imperial Age? :lol: If you won't do that, then could you show me how to stop vassals from receiving reinforcements from the party templates, and stop them from upgrading their troops?

I have a script from a friend that I want to implement, but I want to make sure the two tasks above are out of the way.

Is this to happen part way through the game or from the very start? If from the very start you shouldnt need any scripts, just alter the values concerned with reinforcements and upgrades. Or did you want it removing completely? Which i think would take quite a bit more work.
 
Duh said:
It seems we are on different pages at the moment.

What I mean is, well, it's cool to have an entirely different economy system for the module, but how does your system visibly affect the actual trading process? Because all that stuff with keeping track of population, prosperity, player/merchant relations et cetera ad infinitum can be handled perfectly fine without changing current trading interface at all. Essentially in your entire request only one thing has direct visible effect on trading: the ability for merchant to haggle and therefore to receive more money than he would receive with current system where results of haggling are automatically pre-calculated for player. So your request essentially boils down to three points:

1. Traded items are not put into player's/merchant's inventories and are instead kept "on the table" until the transaction is either confirmed or cancelled.
2. Haggling requires player input and is not pre-calculated into price.
3. There are merchant's and player's portraits on the trading screen.

Such an interface, once implemented, could be used for both Native economy or your economy and the player will not notice a difference (except for how prices are formed). Am I right?

Now the way I see it, improved trading interface is an interesting task. I have serious doubts about haggling feature as I have yet to see a game where it actually improves player's experience instead of forcing him into a "make a few extra clicks or lose money" mini-game.  But that could be implemented as an optional presentation feature, so no problem. But (and it's an important "but" for me) just making two minor visual improvements is setting a bar too low. So with your permission I'm going to boil this idea in my head for a bit. :smile:

Frenzied_Crocoduck_Herder said:
If you need work, you could always take over the role of scripting for Calradia: Imperial Age? :lol: If you won't do that, then could you show me how to stop vassals from receiving reinforcements from the party templates, and stop them from upgrading their troops?

I have a script from a friend that I want to implement, but I want to make sure the two tasks above are out of the way.
Not interested in joining any of the major teams at the moment, sorry.

As for your request, you could get answer for it in Q&A thread. Essentially, reinforcements to lord parties are handled by script_hire_men_to_kingdom_hero_party which calls script_cf_reinforce_party. You can prevent vassals from getting reinforcements in either script.

As for upgrading, it happens in many places, but regular routine upgrade for lord parties and centers is done by a simple trigger. Just search for the line:
Code:
  # Give some xp to hero parties
 
Lav said:
Duh said:
It seems we are on different pages at the moment.

What I mean is, well, it's cool to have an entirely different economy system for the module, but how does your system visibly affect the actual trading process? Because all that stuff with keeping track of population, prosperity, player/merchant relations et cetera ad infinitum can be handled perfectly fine without changing current trading interface at all.
I was largely trying to explain that i am purely using slots to keep track of items rather than actual items_ and why i chose to do so. :wink:

Lav said:
Essentially in your entire request only one thing has direct visible effect on trading: the ability for merchant to haggle and therefore to receive more money than he would receive with current system where results of haggling are automatically pre-calculated for player. So your request essentially boils down to three points:

1. Traded items are not put into player's/merchant's inventories and are instead kept "on the table" until the transaction is either confirmed or cancelled.
2. Haggling requires player input and is not pre-calculated into price.
3. There are merchant's and player's portraits on the trading screen.
Bartering is indeed the main change, though i find it goes beyond just "receiving more or less money". While it is certainly the goal of trade to maximize profits, it ll require the player to collect and review information about the town/village, some of which are showcased in this presentation. That means an important factor of the presentation is an increased accessability to the trading process (which is also why there is the merchant should be able to make a counter offer, to nudge the player into the right direction) - informations should be faster to access and trading itself should be a more enjoyable matter. With that i also mean that rather than selling item packages, the player will be able to sell very specific amounts (unlike natives "packages of 10 or 50) and trade items for items rather than having to sell and then buy - while it is a minor improvement, i feel that these little changes pay off for actions often repeated.

Lav said:
Such an interface, once implemented, could be used for both Native economy or your economy and the player will not notice a difference (except for how prices are formed). Am I right?
Well one might argue that the real consequences wouldnt be noticed immediately, but there are significant differences nonetheless:
- Unlike native, this directly ties into a towns financial developement and in a significant manner as well. The items offered by the merchant are what makes up the towns economic growth in its entirety, which means buying and selling to him will change the towns prosperity development very differently from natives +1/prosp for x money in merchant inventory
- Merchant inventories arent based on probability, but rather on what is produced, bought and sold. I suppose one could attempt to tie this to natives base_production, but from a quick glance (i really havent worked with natives system for a long while), it would require some serious changes to track item amounts across markets.
- Slots vs actual items in the inventory

I guess we may still be on different pages, though i feel the above points would be difficult to translate into native, while ignoring them and purely making an aesthetical change to how trade is done in native would not be worth the effort.

Lav said:
Now the way I see it, improved trading interface is an interesting task. I have serious doubts about haggling feature as I have yet to see a game where it actually improves player's experience instead of forcing him into a "make a few extra clicks or lose money" mini-game.  But that could be implemented as an optional presentation feature, so no problem. But (and it's an important "but" for me) just making two minor visual improvements is setting a bar too low. So with your permission I'm going to boil this idea in my head for a bit. :smile:
My hope with the bartering system is to make trading more interesting and challenging (in that one needs to do more to do good), while still allowing for non-merchant play styles. For the latter one ought to be fine with just offering the estimated base worth and/or agreeing to the merchants counter-offer, but for the former one has to take into account the factors i mentioned earlier and devise a deal that is still interesting to the merchant. There is 1 free try, which is followed by a counter offer and any "bad" offers by the player thereafter would cause a relationship loss with the merchant, which in turn affects what kind of deal can be struck - this is necessary as people could otherwise just spam high offers until they hit one that just meets the criteria for success.

I feel this setup has its optionality already included, but improves the entertainment value for merchant play styles (not enough for it to be self-sufficient, but well this is only 1 feature aimed at eventually achieving that). I do think something like this could also be designed for native, but i honestly have not thought about it and what factors it should be based on and how it could impact the world enough to add something significant to the aspect of trade.
 
I've got some actual requests for scripts for you, Lav, rather than just requests for help. I need a coalition/alliance script similar to that of Europe 1805 that'll force factions into alliances when they join.

I also want the ability to purchase some new property in towns: I want a hospital that'll improve relations over time and a mine that'll improve the wealth of the town over time and provide income.

If you can do these for me, I'll be in your debt!  :smile:
 
Duh said:
I was largely trying to explain that i am purely using slots to keep track of items rather than actual items_ and why i chose to do so. :wink:
Well, possible I guess, and actually makes sense with trade goods and ammo. Less so with armor and weapons though.

Duh said:
Bartering is indeed the main change, though i find it goes beyond just "receiving more or less money". While it is certainly the goal of trade to maximize profits, it ll require the player to collect and review information about the town/village, some of which are showcased in this presentation. That means an important factor of the presentation is an increased accessability to the trading process (which is also why there is the merchant should be able to make a counter offer, to nudge the player into the right direction) - informations should be faster to access and trading itself should be a more enjoyable matter. With that i also mean that rather than selling item packages, the player will be able to sell very specific amounts (unlike natives "packages of 10 or 50) and trade items for items rather than having to sell and then buy - while it is a minor improvement, i feel that these little changes pay off for actions often repeated.
Huh? Player can easily trade items for items in vanilla game.

Trading specific and arbitrarily small/large amounts of trade goods is useful, yes, but this applies only to trade goods and ammo. Horses, weapons and armor, which are the most important items for player, are perfectly fine as they are.

Finally, the gathering trade information part is what I'm having most doubts about. Right now player does not have to collect any information - it's all abstracted into his Trade skill value and calculated behind the screens. You want player to actually do some research if he wants to get a better deal and not spoil his relations with merchants. My point is: will this process actually be interesting, or will it turn into aforementioned "make several extra clicks or lose money" mini-game?

Personally I feel you are approaching the problem from the wrong angle. For as long as it's "make extra effort or the NPC will cheat you of your money", this extra effort will feel like a chore for the player. If you could somehow make it into "by making some extra effort you can cheat NPC of his money", the perception would likely be completely different.

Duh said:
Well one might argue that the real consequences wouldnt be noticed immediately, but there are significant differences nonetheless:
- Unlike native, this directly ties into a towns financial developement and in a significant manner as well. The items offered by the merchant are what makes up the towns economic growth in its entirety, which means buying and selling to him will change the towns prosperity development very differently from natives +1/prosp for x money in merchant inventory
- Merchant inventories arent based on probability, but rather on what is produced, bought and sold. I suppose one could attempt to tie this to natives base_production, but from a quick glance (i really havent worked with natives system for a long while), it would require some serious changes to track item amounts across markets.
- Slots vs actual items in the inventory
When it's about trade goods, vanilla merchants are actually selling what's produced in town, with a bit of randomization to reflect the other merchants activities.

And furthermore, IIRC trading effects are more complicated in vanilla than what you describe. Not only merchant's profits matter, but also the price shifts that are the results of player's trade. Though I may be wrong and it actually applies to enterprises, not background economy.

Duh said:
My hope with the bartering system is to make trading more interesting and challenging (in that one needs to do more to do good), while still allowing for non-merchant play styles. For the latter one ought to be fine with just offering the estimated base worth and/or agreeing to the merchants counter-offer, but for the former one has to take into account the factors i mentioned earlier and devise a deal that is still interesting to the merchant. There is 1 free try, which is followed by a counter offer and any "bad" offers by the player thereafter would cause a relationship loss with the merchant, which in turn affects what kind of deal can be struck - this is necessary as people could otherwise just spam high offers until they hit one that just meets the criteria for success.

I feel this setup has its optionality already included, but improves the entertainment value for merchant play styles (not enough for it to be self-sufficient, but well this is only 1 feature aimed at eventually achieving that). I do think something like this could also be designed for native, but i honestly have not thought about it and what factors it should be based on and how it could impact the world enough to add something significant to the aspect of trade.
In other words, this is exactly the system I hate. :smile: With my OCD I cannot abstain from trying to squeeze the best price out of the merchants, but the amount of effort I have to achieve an essentially predetermined result is annoying me like hell.

Your system might work if it's not deterministic. However if for any combination of goods, skills and relations there's always some optimum price and player has a specific algorithm on how to achieve it - then the entire process would better be abstracted in my opinion.

Sorry if I'm raining critique on your ideas, you just managed to request a feature that I really dislike in many games. :grin:

Apart from that, trading interface still remains an interesting task, but I won't start with it - I'm feeling it still needs a lot of flamy discussion and tinkering at the moment. :smile:
 
Frenzied_Crocoduck_Herder said:
I've got some actual requests for scripts for you, Lav, rather than just requests for help. I need a coalition/alliance script similar to that of Europe 1805 that'll force factions into alliances when they join.

I also want the ability to purchase some new property in towns: I want a hospital that'll improve relations over time and a mine that'll improve the wealth of the town over time and provide income.

If you can do these for me, I'll be in your debt!  :smile:
Buildings shouldn't be a problem, there's even a tutorial on that IIRC.

Alliance can be tricky, as once a kingdom is a part of an alliance, it cannot declare wars and sign peace on it's own leisure. Alliance implies some level of internal negotiations about such issues. Or alternatively a specific war could be an alliance war (fought by the entire alliance) or a separate individual war of an alliance member which does not put any obligations on other alliance members.

Depending on how it's described, amount of work can vary a lot with this feature. I'd recommend you to write down all possible political actions of an individual kingdom (war, ceasefire, peace, anything else specific to your mod) and possible situations (two independent kingdoms against each other, kingdom vs an alliance, two alliances, kingdom with some set of relations joining an alliance, kingdom leaving the alliance etc). Match them against each other and consider how you want each combination resolved.
 
I've written down a number of rules for the alliance script:

There will be two alliances headed by two of the major factions, kingdom_1 and kingdom_5

Coalition leaders:

- Each coalition has a leading faction that cannot leave.

-When one of the leading factions hosts a campaign, the other allied coalition factions must join the campaign.

- Leading factions also have the power to negotiate peace with each other, however, wars can be started by any faction that are with in the coalition.

- A leading faction may invite independent factions to join, but cannot invite rival coalition factions.

-When a leading faction is destroyed, the alliance is destroyed with it, rendering all alliances with in the coalition void.

Coalitions and the player faction:

- The player's faction may join a coalition (For a 10,000 fee unless they are invited) and will be subjected to the rules below.

- A player cannot start their own alliance.

- A player's right to rule must be at 50, and the player's fame must be at 1,200 to be invited to a coalition

- A player will receive a 1,000 income boost whilst a part of an alliance.

Coalition members:

-When a faction with in a coalition declares war on an independent faction (Or vice versa), all the allied coalition factions must join the war.

-When a faction with in a coalition declares war on another coalition faction (Or vice versa), all the allied coalition factions must join in the war on both sides.

- When the lead coalition faction negotiates peace with an independent faction, allied coalition factions must end the war also.

-When the lead coalition faction negotiates peace with another leading coalition faction, all parties involved must also end the war.

-When a coalition faction falls far enough in relations with an allied coalition faction, the offending faction must be kicked from the coalition.

-Coalition factions cannot trade with factions outside of the coalition, and must only trade with their allies, no matter what their relations are.

-When a coalition member leaves their alliance, they must wait a week to join another.

-There must only be three factions per alliance.

Independent factions and coalitions:

-Independent factions may have war with each other, but when an independent faction joins an alliance whilst at war with another faction, the alliance leader must negotiate a peace treaty.

-Independent factions cannot join an alliance they're at war with.

-When a coalition faction becomes independent, they risk going to war with their old allies.
 
That's what I was afraid of, this is essentially an entire mod in itself and a bit too much for what I'm ready to give. :smile:
 
Lav said:
Well, possible I guess, and actually makes sense with trade goods and ammo. Less so with armor and weapons though.
Sorry for not being clear about that beforehand. I was talking specifically about trade goods - that is what i feel this type of presentation would serve well. For any equipment type items the current system is okay, though i suppose it could be improved by f.e. allowing the player to directly buy for and equip the companions.

Lav said:
Huh? Player can easily trade items for items in vanilla game.
I meant the streamlining aspect of being able to trade 327 beans for 255 dates directly rather than selling 5 packages of beans consecutively, then buying 4 packages of dates. As mentioned, i dont view this as a significant factor, but wanted to answer your inquiry about the desired changes fully.

Lav said:
Trading specific and arbitrarily small/large amounts of trade goods is useful, yes, but this applies only to trade goods and ammo. Horses, weapons and armor, which are the most important items for player, are perfectly fine as they are.
Agreed. Sorry for the miscommunication once more.

Lav said:
Finally, the gathering trade information part is what I'm having most doubts about. Right now player does not have to collect any information - it's all abstracted into his Trade skill value and calculated behind the screens. You want player to actually do some research if he wants to get a better deal and not spoil his relations with merchants. My point is: will this process actually be interesting, or will it turn into aforementioned "make several extra clicks or lose money" mini-game?
Well i am aiming for the former of course and simply by increasing the impact of the trade interaction on the world, i believe things will become more interesting. You are right to point out that there is a risk to overcomplicate things or worse to make the process simply tedious rather than engaging. Because towns are unique however, i dont think it is a case of just "make more clicks to win", yes accessing information will require you clicking, but so does everything else in the game and the clicking itself wont provide you with more money. Taking the information you gained, analyzing it and making an educated guess of where to buy how much of something and where to sell it, is to me the essence of trading. Some may not find that engaging, but nobody is forced to play as a trader - after all the native brute force approach to the game will remain as it is.

Lav said:
Personally I feel you are approaching the problem from the wrong angle. For as long as it's "make extra effort or the NPC will cheat you of your money", this extra effort will feel like a chore for the player. If you could somehow make it into "by making some extra effort you can cheat NPC of his money", the perception would likely be completely different.
To me that sounds like same thing, but with different words. Yes the latter sounds better, but really a trade interaction can be viewed either way and optimally could lead to either option. Effort will lead to a better outcome for you, thats the essence of both statements and thats the goal of the system.

Lav said:
When it's about trade goods, vanilla merchants are actually selling what's produced in town, with a bit of randomization to reflect the other merchants activities.
From what i remember its a random amount added to the inventory, rather than an actual production that determines whats in the inventory. Yes the kind is predetermined, but it isnt actually produced and tracked afaik.

Lav said:
And furthermore, IIRC trading effects are more complicated in vanilla than what you describe. Not only merchant's profits matter, but also the price shifts that are the results of player's trade. Though I may be wrong and it actually applies to enterprises, not background economy.
The price shift is limited to that particular merchant i believe, but i would have to dig around to verify it.

Lav said:
In other words, this is exactly the system I hate. :smile:
:lol:

Lav said:
With my OCD I cannot abstain from trying to squeeze the best price out of the merchants, but the amount of effort I have to achieve an essentially predetermined result is annoying me like hell.
But then what kind of system that actually allows significant levels of player input would you propose?

Lav said:
Your system might work if it's not deterministic. However if for any combination of goods, skills and relations there's always some optimum price and player has a specific algorithm on how to achieve it - then the entire process would better be abstracted in my opinion.
There is a maximum price the merchant is willing to pay, which is the worth of the goods after the base worth has received all other influences (basically he ll probably agree even if he only makes or saves 1 denar compared to local growth, unless he dislikes you). So i guess there is an optimum, but it is very unlikely that you can pinpoint it.

Edith: To be clear, this maximum price varies from town to town and over time (depending on the markets and the towns situation).

Lav said:
Sorry if I'm raining critique on your ideas, you just managed to request a feature that I really dislike in many games. :grin:
Critique is good, it helps to improve things :smile:

Lav said:
I'm feeling it still needs a lot of flamy discussion and tinkering at the moment. :smile:
In regards to discussion, i would very much be interested in how you would spice up the trade process, if not with some form of bartering.
 
Duh said:
In regards to discussion, i would very much be interested in how you would spice up the trade process, if not with some form of bartering.
Well, currently my ideas are along the following lines:

1. No bartering. It's boring, so it's abstracted.
2. Player can influence the local market by spreading rumors, making backroom dealings etc. Exact details are once again abstracted.
3. Player's influence is determined by his Trade skill, his relations with town in general, his relations with goods merchant and guildmaster and (to a much smaller degree) armor/weapons/horse merchants.
4. Player uses his market influence to drive prices for some goods up or down. He can use his entire influence to affect one specific trade good, or spread it evenly on all trade goods, or whatever.
5. Once spent, player's influence is long-term and should affect the town economy for game days, probably weeks.
6. Player can "renew" an active influence, but cannot stop it prematurely. He can, however, spend any free influence points to influence the same good in opposite direction.
7. If player's influence drops lower than the amount necessary to keep his current influences within the town, his oldest influences are cancelled prematurely.
8. Market influence should ideally have indirect consequences. Dropping iron price in an iron-producing town should result in iron mining becoming less profitable - hence iron mines start closing - hence as time goes by iron prices in town start to rise to compensate. So not only in time the prices will recover, but once the player's influence will run out, they will soar (and result in the opposite process of iron mining becoming more profitable etc). This however depends on underlying economic model and is not directly related to trading.

Essentially, player is given the tools to "cheat" the merchants by fixing the prices to be more favorable to him.
 
If you are going to do something good, best do it yourself mate. No matter Lav is giving it away anyway.
 
Mining System
(by request of 9jakub9)​

Allows creation of "mineable" or "gatherable" scene props.

This code is part of Open Source Project and can be used freely in any M&B mod.

Features:

1. Up to 128 different resource-yielding props per scene.
2. Resource can be extracted by mining (hitting the prop) or gathering (activating). To enable gatherable props, mod author needs to set can_use_scene_props_in_single_player option to 1 in module.ini file.
3. Modder determines what resource can be extracted from each prop and how much.
4. For mineable props, modder determines how many hits are necessary to yield a single resource batch (gatherable props always yield a batch per each use).
5. Modder determines how much resource is yielded per single batch.
6. Props can be defined as non-recoverable (once all resource has been mined, it will never regenerate), instantly recoverable (prop will always be full when scene is loaded) and gradually recoverable (modder determines number of hours requires to fully regenerate the resource).
7. Script script_cf_check_mining_tool is provided to check if player is using appropriate tool to mine resource. So no mining iron ore with bare fists or cutting wood with lances. Script always succeds by default - modder is expected to override it with whatever resource/tool restrictions he wishes to use.

Notes.

1. Resource props are identified by 2nd variation number, which must be unique for each resource prop on the scene! If you have two same props sharing the same variation number, they will work properly but share their resource "pool" (which might actually be useful to display mineral veins consisting of several visible deposits). If you have two different props (especially with different resources) sharing the same variation number, results may be... interesting at best. :smile:
2. It recommended to modify script_game_get_use_string to provide meaningful names for your resource props.

Code

Open the spoiler for code.

Code:
mining_storage = "trp_mining_storage"

slot_prop_resource_id    = 0
slot_prop_hits_per_batch = 1
slot_prop_haul_per_batch = 2
slot_prop_recovery_time  = 3
slot_prop_current_hits   = 4
slot_prop_data_offset    = 5

Code:
    ["mining_storage","mining_storage","mining_storage",tf_hero|tf_inactive, 0, 0, fac_no_faction, [], 0, 0, 0, 0],

Code:
    # "script_find_mining_data"
    # Finds dynamic vein information in resource storage troop and creates a new record if necessary.
    # INPUT:
    #   arg1 = scene_id where mining takes place
    #   arg2 = vein_id for resource prop (2nd variation number)
    #   arg3 = default resource amount in vein
    #   arg4 = vein full recovery time (MUST be > 0)
    # OUTPUT:
    #   reg0 = amount of resource in vein at current moment
    #   reg1 = vein data offset in "trp_mining_storage"
    ("find_mining_data", [
        (store_script_param, ":scene_id", 1),
        (store_script_param, ":vein_id", 2),
        (store_script_param, ":resource_max", 3),
        (store_script_param, ":recovery_time", 4),
        (store_current_hours, ":current_time"),
        (assign, ":found", 0),
        (assign, ":max_range", "$g_mining_veins_count"),
        (try_for_range, ":slot_id", 0, ":max_range"),
            (val_lshift, ":slot_id", 2),
            # Check it's the same scene
            (troop_slot_eq, mining_storage, ":slot_id", ":scene_id"),
            (val_add, ":slot_id", 1),
            # Check it's the same vein
            (troop_slot_eq, mining_storage, ":slot_id", ":vein_id"),
            (val_add, ":slot_id", 1),
            # Load data for recovery calculation
            (troop_get_slot, ":previous_time", mining_storage, ":slot_id"),
            (troop_set_slot, mining_storage, ":slot_id", ":current_time"),
            # Remember current slot for script output
            (assign, reg1, ":slot_id"),
            # Load vein resource amount and apply recovery if necessary
            (val_add, ":slot_id", 1),
            (troop_get_slot, ":previous_qty", mining_storage, ":slot_id"),
            # Calculate vein recovery, depending on how much time has passed
            (try_begin),
                # If instant recovery (recovery time < 0)
                (lt, ":recovery_time", 0),
                (assign, reg0, ":resource_max"),
            (else_try),
                # If gradual recovery (recovery time > 0)
                (gt, ":recovery_time", 0),
                (store_sub, ":recover_qty", ":current_time", ":previous_time"),
                (val_mul, ":recover_qty", ":resource_max"),
                (val_div, ":recover_qty", ":recovery_time"),
                (store_add, reg0, ":previous_qty", ":recover_qty"),
                (val_min, reg0, ":resource_max"),
            (else_try),
                # If no recovery (recovery time = 0)
                (assign, reg0, ":previous_qty"),
            (try_end),
            (troop_set_slot, mining_storage, ":slot_id", reg0),
            # Set found flag so we don't create a new record
            (assign, ":found", 1),
            # End try_for_range cycle immediately
            (assign, ":max_range", 0),
        (try_end),
        (try_begin),
            # If we haven't found vein record, create a new one
            (eq, ":found", 0),
            (store_mul, reg1, "$g_mining_veins_count", 4),
            (val_add, "$g_mining_veins_count", 1),
            (troop_set_slot, mining_storage, reg1, ":scene_id"),
            (val_add, reg1, 1),
            (troop_set_slot, mining_storage, reg1, ":vein_id"),
            (val_add, reg1, 2),
            (troop_set_slot, mining_storage, reg1, ":resource_max"),
            (val_sub, reg1, 1),
            (troop_set_slot, mining_storage, reg1, ":current_time"),
            (assign, reg0, ":resource_max"),
        (try_end),
    ]),

    # "script_initialize_mining_prop"
    # Initializes scene_prop instance as a mineable vein.
    # INPUT:
    #   arg1 = scene prop instance id
    #   arg2 = resource item_id
    #   arg3 = number of successful hits to yield a single resource batch, 0 if resource cannot be mined with hits
    #   arg4 = amount of resource yielded in a single batch
    #   arg5 = vein size in resource units
    #   arg6 = vein full recovery time
    # OUTPUT:
    #   None
    ("initialize_mining_prop", [
        (store_script_param, ":instance_id", 1),
        (store_script_param, ":resource_id", 2),
        (store_script_param, ":hits_per_batch", 3),
        (store_script_param, ":haul_per_batch", 4),
        (store_script_param, ":resource_max", 5),
        (store_script_param, ":recovery_time", 6),
        (store_current_scene, ":scene_id"),
        (prop_instance_get_variation_id_2, ":vein_id", ":instance_id"),
        (call_script, "script_find_mining_data", ":scene_id", ":vein_id", ":resource_max", ":recovery_time"),
        (scene_prop_set_slot, ":instance_id", slot_prop_data_offset, reg1),
        (scene_prop_set_slot, ":instance_id", slot_prop_resource_id, ":resource_id"),
        (scene_prop_set_slot, ":instance_id", slot_prop_hits_per_batch, ":hits_per_batch"),
        (scene_prop_set_slot, ":instance_id", slot_prop_haul_per_batch, ":haul_per_batch"),
        #(scene_prop_set_slot, ":instance_id", slot_prop_resource_max, ":resource_max"),
        (scene_prop_set_slot, ":instance_id", slot_prop_recovery_time, ":recovery_time"),
        (scene_prop_set_slot, ":instance_id", slot_prop_current_hits, 0),
        (try_begin),
            (eq, reg0, 0), # Vein is empty
            (scene_prop_set_hit_points, ":instance_id", 0),
        (else_try),
            (gt, ":hits_per_batch", 0),
            (store_mul, ":hp", ":hits_per_batch", 1000),
            (scene_prop_set_hit_points, ":instance_id", ":hp"),
        (else_try),
            (scene_prop_set_hit_points, ":instance_id", 1000),
        (try_end),
    ]),

    # "script_cf_check_mining_tool"
    # 
    # INPUT:
    #   arg1 = mining scene_prop instance_id
    #   arg2 = agent_id who is doing the mining
    # OUTPUT:
    #   Fails or succeeds depending on check result
    ("cf_check_mining_tool", [
        #(store_script_param, ":instance_id", 1),
        #(store_script_param, ":agent_id", 2),
        #(scene_prop_get_slot, ":resource_id", ":instance_id", slot_prop_resource_id),
        #(agent_get_wielded_item, ":tool_id", ":agent_id", 0),
        (assign, ":allowed", 0),
        (try_begin),
            # Insert any code to check for tool/resource match here and set ":allowed" to 1 if successful.
            (assign, ":allowed", 1),
        (try_end),
        (eq, ":allowed", 1),
    ]),

    # "script_process_resource_mining"
    # 
    # INPUT:
    #   arg1 = mining scene_prop instance_id
    #   arg2 = agent_id who is doing the mining
    #   arg3 = damage delivered by agent when mining (pass 0 when mining by use)
    # OUTPUT:
    #   None
    ("process_resource_mining", [
        (store_script_param, ":instance_id", 1),
        (store_script_param, ":agent_id", 2),
        (store_script_param, ":damage", 3),
        (scene_prop_get_slot, ":hits_per_batch", ":instance_id", slot_prop_hits_per_batch),
        (assign, ":haul", 1),
        (try_begin),
            (gt, ":hits_per_batch", 0),
            (scene_prop_get_slot, ":current_hits", ":instance_id", slot_prop_current_hits),
            (val_add, ":current_hits", 1),
            (try_begin),
                (ge, ":current_hits", ":hits_per_batch"),
                (scene_prop_set_slot, ":instance_id", slot_prop_current_hits, 0),
                (store_mul, ":hp", ":hits_per_batch", 1000),
            (else_try),
                (scene_prop_set_slot, ":instance_id", slot_prop_current_hits, ":current_hits"),
                (store_sub, ":hp", ":hits_per_batch", ":current_hits"),
                (val_mul, ":hp", 1000),
                (assign, ":haul", 0),
            (try_end),
        (else_try),
            (assign, ":hp", 1000),
        (try_end),
        (val_add, ":hp", ":damage"), # Compensate for damage from current strike
        (scene_prop_set_cur_hit_points, ":instance_id", ":hp"),
        (try_begin),
            (eq, ":haul", 1),
            (scene_prop_get_slot, ":resource_id", ":instance_id", slot_prop_resource_id),
            (scene_prop_get_slot, ":haul", ":instance_id", slot_prop_haul_per_batch),
            (scene_prop_get_slot, ":slot_id", ":instance_id", slot_prop_data_offset),
            (val_add, ":slot_id", 1),
            (troop_get_slot, ":resource_qty", mining_storage, ":slot_id"),
            (val_min, ":haul", ":resource_qty"), # We cannot mine more than what's currently there
            (val_sub, ":resource_qty", ":haul"),
            (troop_set_slot, mining_storage, ":slot_id", ":resource_qty"), # Write down what remains in the vein
            (try_begin),
                (gt, ":haul", 0),
                (call_script, "script_resource_mined", ":agent_id", ":resource_id", ":haul"),
            (try_end),
            (try_begin),
                (eq, ":resource_qty", 0),
                (scene_prop_set_cur_hit_points, ":instance_id", 0),
                (call_script, "script_resource_mined_out", ":instance_id", ":agent_id", ":resource_id"),
            (try_end),
        (try_end),
    ]),

    # "script_resource_mined"
    # Process actual mining success (give some resource to miner).
    # INPUT:
    #   arg1 = agent_id who has mined some resource
    #   arg2 = item_id of resource being mined
    #   arg3 = amount of resource mined
    # OUTPUT:
    #   None
    ("resource_mined", [
        (store_script_param, ":agent_id", 1),
        (store_script_param, ":resource_id", 2),
        (store_script_param, ":amount", 3),
        (assign, reg0, 0), # How much we managed to actually store (with inventory constraints in mind)
        (agent_get_troop_id, ":troop_id", ":agent_id"),
        (assign, ":empty_slot", 0),
        (troop_get_inventory_capacity, ":capacity", ":troop_id"),
        (try_for_range, ":slot_id", num_equipment_kinds, ":capacity"),
            (troop_get_inventory_slot, ":item_id", ":troop_id", ":slot_id"),
            (try_begin),
                (eq, ":empty_slot", 0),
                (eq, ":item_id", -1),
                (assign, ":empty_slot", ":slot_id"),
            (else_try),
                # If item in this slot is the same as we have mined:
                (eq, ":item_id", ":resource_id"),
                (troop_inventory_slot_get_item_amount, ":qty", ":troop_id", ":slot_id"),
                (troop_inventory_slot_get_item_max_amount, ":max", ":troop_id", ":slot_id"),
                (store_sub, ":store", ":max", ":qty"),
                (val_min, ":store", ":amount"),
                # If we can store some of our resource here:
                (gt, ":store", 0),
                (val_add, ":qty", ":store"),
                (val_add, reg0, ":store"),
                (val_sub, ":amount", ":store"),
                (troop_inventory_slot_set_item_amount, ":troop_id", ":slot_id", ":qty"),
                # If we have nothing else to store, cancel the cycle:
                (eq, ":amount", 0),
                (assign, ":capacity", 0),
            (try_end),
        (try_end),
        (try_begin),
            # If we still have to store some resource and an empty slot to store it:
            (gt, ":amount", 0),
            (gt, ":empty_slot", 0),
            (troop_set_inventory_slot, ":troop_id", ":empty_slot", ":resource_id"),
            (troop_inventory_slot_set_item_amount, ":troop_id", ":empty_slot", ":amount"),
            (val_add, reg0, ":amount"),
        (try_end),
        (str_store_item_name, s0, ":resource_id"),
        (try_begin),
            (eq, ":troop_id", "trp_player"),
            (display_message, "@{!}You have mined {s0}[{reg0}]!"),
        (else_try),
            (str_store_agent_name, s1, ":agent_id"),
            (display_message, "@{!}{s1} has mined {s0}[{reg0}]!"),
        (try_end),
    ]),

    # "script_resource_mined_out"
    # Process mining failure (i.e. resource is mined out).
    # INPUT:
    #   arg1 = instance_id of resource vein that's been mined out
    #   arg2 = agent_id who has mined out the vein
    #   arg3 = item_id of mined resource
    # OUTPUT:
    #   None
    ("resource_mined_out", [
        #(store_script_param, ":instance_id", 1),
        #(store_script_param, ":agent_id", 2),
        (store_script_param, ":resource_id", 3),
        (str_store_item_name, s0, ":resource_id"),
        (display_message, "@{!}{s0} has been mined out."),
    ]),

Example.

Scene prop provided below is both mineable and gatherable. In reality you'll need only one trigger: either ti_on_scene_prop_use (with spr_use_time header) or ti_on_scene_prop_hit.

This scene prop is provided as an example. Modder is expected to create his own, using this code for guidelines.

Code:
    ("example_iron_vein",sokf_moveable|sokf_destructible|sokf_show_hit_point_bar|spr_use_time(5),"snowy_barrel_a","bo_snowy_barrel_a",
        [
            (ti_on_init_scene_prop, [
                (store_trigger_param_1, ":instance_id"),
                (call_script, "script_initialize_mining_prop", ":instance_id", "itm_iron", 3, 10, 50, 20*24),
                # Parameters explanation: [itm_iron] vein, [3] hits yield [10] iron, contains [50] iron and fully recovers in [20*24] hours.
            ]),

            # If you want your vein to be mineable by hitting, use this trigger. Expand with extra effects as appropriate
            (ti_on_scene_prop_hit, [
                (store_trigger_param_1, ":instance_id"),
                (store_trigger_param_2, ":damage"),
                (set_fixed_point_multiplier, 1), # To ensure next operation yields correct result
                (position_get_x, ":agent_id", pos2),
                (call_script, "script_cf_check_mining_tool", ":instance_id", ":agent_id"),
                (call_script, "script_process_resource_mining", ":instance_id", ":agent_id", ":damage"),
            ]),

            # If you want your vein to be mineable by activating, use this trigger. Expand with extra effects as appropriate
            (ti_on_scene_prop_use, [
                (store_trigger_param_1, ":agent_id"),
                (store_trigger_param_2, ":instance_id"),
                (call_script, "script_process_resource_mining", ":instance_id", ":agent_id", 0),
            ]),

            # We do nothing here, but you can use this trigger to replace the exhausted vein with a different scene prop to indicate it's status, or do other things
            (ti_on_scene_prop_destroy, [
            ]),
        ]
    ),
 
Back
Top Bottom