Not logged inOpenClonk Forum
Up Topic Development / Scenario & Object Development / Minor improvements
1 2 Previous Next
- - By Marky [de] Date 2016-01-18 21:21
I am currently writing a script that displays collected wipfs in the lorry. Yay or nay? Also, maybe we can collect minor improvements in this thread.
Parent - - By Maikel Date 2016-01-18 21:30
Yay! (If it is a script in the wipf, not the lorry).
Parent - - By Marky [de] Date 2016-01-18 21:40
It is in the lorry at the moment. I set the layers with GFXOV_MODE_Object so that it displays up to 5 wipfs. Unfortunately, the wipf graphics do not rotate with the lorry. Why is that? I think it would be a lot of additional effort to calculate the position and rotation for the layer every frame.
Anyway, it would be possible to have this functionality in the wipf, too, but why is this preferrable?
Parent - - By Zapper [de] Date 2016-01-18 21:45

>Anyway, it would be possible to have this functionality in the wipf, too, but why is this preferrable?


It's preferrable to be kept maintainable and dynamic.
In real words: add only things that are absolutely necessary AND make sure other people can also use them. For example, if I had an own monster/item (a WOPF!) and I wanted to also show that in a lorry, I could ideally do that in a few lines without changing the lorry. (Because the lorry is in Objects.ocd and my Wopf is in ZappersBetterObjects.ocd).

Oh, and the only real solution would probably be to just attach the wipf meshs to the lorry. Then the wipfs would rotate properly, be IN the lorry (e.g. in the picture) and much more!

(I have nothing against having it in the lorry btw. Or in an additional library that my Wopf would just include.)
Parent - - By Marky [de] Date 2016-01-18 21:51
If I have another vehicle that should display both the wipf and wopf, and in a different place (lorry: in the middle, airplane: in the seat), then I need an interface somewhere in the vehicle as well.
Did not think about attaching meshes, this probably is a good solution.
Parent - - By Zapper [de] Date 2016-01-18 21:58

>Did not think about attaching meshes, this probably is a good solution.


It's done like that e.g. in the catapult.

>then I need an interface somewhere in the vehicle as well.


You don't need an interface for attaching stuff. It's as simple as calling AttachMesh.
You do need an interface (in the lorry) for making sure that you attach max. 5 meshes, that you add and remove them when they enter/leave the lorry or are randomly removed by a script. Stuff like that.

(And I still have nothing against doing that in the lorry)
Parent - - By Marky [de] Date 2016-01-18 22:08
Interface: I do not mean a GUI or anything, I am talking about functions such as IsPrey() or IsToolProduct() that tell other objects something about this object. For example the lorry could tell the wipf where it may sit. Otherwise the wipf script would have to know all the vehicles that it can sit in (as well as the wopf).
Parent - By Zapper [de] Date 2016-01-18 22:22

>Interface: I do not mean a GUI or anything, I am talking about functions such as IsPrey() or IsToolProduct() that tell other objects something about this object.


Yes, I know. I was just saying that attaching the mesh is not the code-intensive/error-prone part. You mentioned the plane, which is a completely different usecase and there it's probably really enough to use AttachMesh without needing some sort of library that cares about attaching stuff.
Parent - - By Pyrit Date 2016-01-18 23:42

>I set the layers with GFXOV_MODE_Object so that it displays up to 5 wipfs.


How do you draw the Wipfs *behind* the lorry?
I'm asking, because I'm looking for a way to have an (2d) object attached to a mesh and have it always face the camera. (billboarding) The problem is that I don't want the overlay in front of the parent object, but rather somewhere between.
Is there some sort of depth check for overlays set with SetGraphics?
Parent - - By Clonk-Karl [us] Date 2016-01-19 03:25

> Is there some sort of depth check for overlays set with SetGraphics?


No -- depth checks are only performed for attached meshes. In principle overlays could be drawn before the object itself is drawn, but I think the engine does not do this, either.
Reply
Parent - - By Pyrit Date 2016-01-19 09:12 Edited 2016-01-19 09:19
To achieve a billboard, would it work to set an overlay onto an invisible 3d helper object and then attach the mesh of the invisible 3d object to a parent?

In other words: Do meshes keep their overlays when attached?
Parent - By Clonk-Karl [us] Date 2016-01-19 20:12

> Do meshes keep their overlays when attached?


No, sorry.
Reply
Parent - - By Clonkonaut [de] Date 2016-01-19 10:21
I remember a very old feature wish (maybe it was in CR) to allow for negative overlay numbers, drawing those behind the object!
Reply
Parent - By Marky [de] Date 2016-01-19 20:02
The reminder is still in the code, I found a comment where it says that they are not supported yet.
Parent - By Marky [de] Date 2016-01-19 05:36
It's a little bit dirty: I have the lorry, then x <= 5 layers of wipfs, then another layer that draws the lorry base graphics on layer x+1. This is not that good, however, because if the lorry has a different material it will suddenly look like a standard lorry once you put a wipf in it. So Zapper is right, attaching meshes is a lot better in this situation.
Parent - - By Marky [de] Date 2016-01-20 21:22
Is there a reason for the placement functions, such as Fish->Place(), to return only the object that was placed last? I'd rather have an array, so that I can do something with all the objects that were placed.
Parent - - By Sven2 [us] Date 2016-01-20 21:29
I think you should get a single object if the count parameter is "nil" and an array if the count is an integer (even if it's 1).
Parent - - By Marky [de] Date 2016-01-20 21:36
It depends on the object. For the trunk it is like that, but fish only return the last object. I will change the behaviour to what you said if I encounter it.
Parent - By Sven2 [us] Date 2016-01-20 23:30
Actually Trunk->Place() does nothing and returns []. Yes I think Place() functions should be changed so that they all behave the same.
Parent - - By Clonkonaut [de] Date 2016-01-20 22:26
It should return an array if more than one object has been created. If not, it's a bug!
Reply
Parent - - By Maikel Date 2016-01-20 23:55
So either nil (no object), object (1 object), array (multiple objects).
Parent - - By Matthias [de] Date 2016-01-21 01:53
That sounds like a horrible api to make dynamic placements with. Why not always return an array? That would be most consistent.
Reply
Parent - By Maikel Date 2016-01-21 08:37
True, then maybe Sven's suggestion is the best.
Parent - - By Pyrit Date 2016-01-21 02:19
You can't know in advance if it will be only one object or multiple. So a scripter doesn't know what to do with the outcome?
Parent - - By Sven2 [us] Date 2016-01-21 02:26 Edited 2016-01-21 02:29
That's the point of returning the direct object pointer only when the count parameter is nil (or not supplied). If the count parameter is 1, you return an array of one object. If it's zero, you return an empty array.

I think the scripter has control over whether he supplied nil or a number.

So you can either write:

Clonk->Place()->SetName("Wolli");

or

for (clonk in Clonk->Place(Random(10))) clonk->SetName("Wolli");

But I'm also not opposed to leaving out the first option (i.e. always return an array) if others think that makes the API too complicated.
Parent - By Matthias [de] Date 2016-01-21 09:55
Well, its basically two different functions if the return type differs. I think its not so much complicated but rather confusing. If both options should be available to devs, I'd suggest making a "PlaceOne()" shorthand  in the placement libraby that just retuns "Place(1)[0]". Using the name to differentiate between different functions seems like the most natural way here.
Reply
Parent - By Zapper [de] Date 2016-01-21 11:40

>Clonk->Place()->SetName("Wolli");


But if it always returned an array, you could also write
for (var clonk in Clonk->Place()) clonk->SetName("Wolli");
and it wouldn't even break when no Clonk could be created without having to check whether clonk == nil!
Parent - - By Marky [de] Date 2016-01-23 00:10 Edited 2016-01-23 08:08
I want to merge the Vendor Library (extracted the buy menu from the flagpole so that the implementation can be used in custom sellers). I do not know who scripted the original menu, so I still need to know who the author was. Any objections?

[Update]
What about moving the old buy and sell implementation from Library_Base to the vendor library, as well as removing the old engine menu?

[Update]
The base library also has a "bug": Do buy looks for buyable material of the player that calls the menu, but decreases the material of the player that owns the base. Usually this is the same player, but this is wrong imo.

[Update]
I will present a reworked version later
Parent - - By Maikel Date 2016-01-23 08:28

> The base library also has a "bug": Do buy looks for buyable material of the player that calls the menu, but decreases the material of the player that owns the base. Usually this is the same player, but this is wrong imo.


This was intended in CR, in OC I left it like this. So we need some opinions, I think I'd leave it like it is.
Parent - - By Marky [de] Date 2016-01-23 09:02
But this does not make sense. Say player A has 1 wood, player B does not. Player A buys material at player B's base: He can buy one wood, because it is in his material. He buys it, player B loses 1 wood (which has no effect, does it?), player A loses wealth. However, player A could buy wood again, because he still has 1 wood in his own material.
Parent - By Maikel Date 2016-01-23 13:14
Then it is wrong yes, the script should check the same player for material as it subtracts the material from. For me that would be the owner of the base.
Parent - - By Sven2 [us] Date 2016-01-23 15:40
Looks good. But I would move this function to the flagpole:

// Interface for custom buy conditions
public func AllowBuyMenuEntries(){ return !ObjectCount(Find_ID(Rule_BuyAtFlagpole));}


and keep it as a simple "return true" in the vendor library. So we can have a dedicated market building in the future and just keep the rule for some special scenarios where this is not feasible (e.g. quick base melees where you want to combine both structures). Then the market could be a "high tier" building requiring advanced stuff like cloth to build.

Also remember to call indirectly (this->AllowBuyMenuEntries() instead of AllowBuyMenuEntries()) to allow runtime overloads.
Parent - By Marky [de] Date 2016-01-23 20:57
Actually I did some more changes but did not push them to my repository yet (probably tomorrow). You raise some good points there, I will incorporate them. This will also include a sell functionality that will be ignored by the flagpole.
Parent - - By Marky [de] Date 2016-01-24 18:07
Originally I wanted to add a sell menu, too. This would help with selling stuff, obviously. For instance, in the flagpole I do not know what items exactly have "IsValuable", probably gems and gold. Having them displayed as sellable below the buy menu would make things more clear.
On the other hand, only the cursor of the player is passed as a parameter to the menu, so if I select a lorry on one tab of the menu, then the flag still only displays the clonk's contents as sellable. For now I'll skip the sell menu.
Parent - By Sven2 [us] Date 2016-01-24 18:25
The same problems arises with almost any container. E.g. producers can only take the items used to construct something, the power plant only takes fuel, the sawmill only takes wood, etc.

So I don't like the extra sell area. Instead, we should highlight the items in the container that can be transferred somehow. Or gray out the ones which can not.
Parent - Date 2016-01-25 22:02
Parent - - By Marky [de] Date 2016-02-14 22:25
Does anyone, especially Maikel, know why the resource gain goal converts the resources that have to be mined to a number of objects, then converts it back to remaining material for some calculations? Would it not be easier to not count everything as material amount, then divide by the ratio again?
Parent - - By Maikel Date 2016-02-15 07:49
Can you point to the lines of code?
Parent - By Marky [de] Date 2016-02-15 18:20
For example in theold version: Lines 97, 132, 154;
or in the new version: Lines 70, 97, 133
Parent - - By Marky [de] Date 2016-03-03 22:44
As a side effect I am doing a unit test for the stackable library. Is it intended that you can increase the stack beyond the maximum with SetStackCount() and DoStackCount()? However, increasing this by stacking objects is not possible.
Parent - - By Sven2 [us] Date 2016-03-04 01:23
It's common to do non-standard stack counts by script when designing scenarios. That's usually for balancing reasons (e.g. you give small bomb arrow stacks but larger regular arrow stacks). Usually we give less, but I could imagine giving more too. E.g. maybe I want to give 10 spears in a big stack to an AI enemy.
Parent - - By Marky [de] Date 2016-03-06 23:33 Edited 2016-03-07 22:05
I am nearly done with the tests, but there are some things that I consider strange:
- the stack can be set to contain 0 items (the object gets removed if you use DoStackCount() but not with SetStackCount()). This can lead to strange behaviours, because the returned stack count still is 1. The function should either be consistent in that the object is always removed on stack count 0, or that the correct stack count is returned.
- in the documentation there is an example use case: Clonk with arrow stack, bow with arrow stack, the Clonk collects a third arrow stack. This third arrow stack fills the bow arrows first, then the inventory slot arrows and gets collected by the Clonk. In practice, in my test, only the bow arrow stack is filled and the stack is not collected. Which behaviour is desired? I think the way it behaves currently is not that bad, because an infinite stack would fill a lot of stacks once it is collected.
- the function name "TryPutInto" suggests, imo, that it would make the stack enter another object, but it rather tries to fill existing stacks in a container. If it cannot fill any stack it stays where it is - this is misleading. Any suggestions?

The tests revealed another problem:
Infinite stacks currently count as 50 objects. The infinite stack gets deleted if you remove 50 or more items from an infinite stack.
Parent - - By Marky [de] Date 2016-03-08 22:59
I'd like to continue with the liquid container stuff and do some changes to the stackable library:
- stacks would always be removed if set/changed to a stack count of 0, since this seems more consistent
- infinite stacks would not get removed by taking 50 or more objects from them. They should get removed when merging infinite stacks, though.
- the behaviour of TryPutInto() should stay the same, even though the name suggests that the object might enter the other object
- do not change the behaviour of filling stacks - use case #2 from the stackable documentation would not work like that. The desired behaviour has to be discussed though and may be changed later.

I need actual feedback on my proposed changes, so that I can continue.
Parent - - By Newton [de] Date 2016-03-08 23:50
I am somewhat out of the code but as the one who originally created the stackable library over 6 years ago, I can tell you that your suggestions sound reasonable. But at this point, I think you are incorrect in the assumption that you need feedback to continue as I think you are currently the one who understands the library the best.
I don't get your last point. What documentation?

Personally, I do not find TryPutInto misleading, but what about TryAdd() or TryPut() then?
Parent - - By Zapper [de] Date 2016-03-09 07:15

>Personally, I do not find TryPutInto misleading, but what about TryAdd() or TryPut() then?


How would that help? I'd need a longer name such as TryToPutIntoContainedStack to clear up the ambiguity. (I am the one who invented that name, I guess). Or TryMergeInto.

PS: I checked and at least the comment above that function is very concise about what it does and what not :)
Parent - - By Newton [de] Date 2016-03-09 10:27
I thought the ambiguity came from "...Into(Object anotherObject)"
Parent - - By Zapper [de] Date 2016-03-09 11:40
What the function does is that it tries to put as much of it as possible into stacks contained in the other object (possibly recursive: arrows in bow in Clonk).
Parent - - By Newton [de] Date 2016-03-09 17:53
Ah... oh well, then it is pretty misleading. I thought it was trying to put the given object (or at least the stack within that object) into the this object!

Why not the other way around? I expect a method to rather modify itself than another object.
Parent - - By Zapper [de] Date 2016-03-09 21:53

>Why not the other way around? I expect a method to rather modify itself than another object.


What exactly do you mean?
Parent - - By Newton [de] Date 2016-03-09 23:14
I.e.
listA.transferElementsIntoOtherList(listB)
listB.transferElementsFrom(listA)

Not pushing your content into other objects but pulling content into your object.
Up Topic Development / Scenario & Object Development / Minor improvements
1 2 Previous Next

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill