Language: 
To browser these website, it's necessary to store cookies on your computer.
The cookies contain no personal information, they are required for program control.
  the storage of cookies while browsing this website, on Login and Register.

Author Topic:  Generating Items with lua  (Read 170 times)

0 Members and 1 Guest are viewing this topic.

Dolfo

« on: 10, January 2022, 12:56:53 »
I am still learning here. It's really not easy, if you need build all the logic, by looking and searching the whole server code or searching for code hints in forum. One more example could have saved hours of my life. So i hope i can safe hours of life for others, when i post this here.  :)

using pl:CreateObjectInside or pl:CreateObjectInsideEx
Code: [Select]
  local x = pl:CreateObjectInsideEx("scroll_x", game.IDENTIFIED, 1)
  assert(x, "Could not create scroll!")
  x.level = 3
This generates 1 identified scroll_x in player inventar.
If scroll_x is not defined in archetype or artifacts, the whole lua script or the whole lua function do nothing.
The generated scroll first gets the level from archetype/artefact, in my example i have level 1 there.
The assert command currently i didn't have the view, what this does. I have an idea what this command does, but i am not sure.
x.level = 3 changes the level.

And here is the first problem of CreateObjectInside(Ex)
It generates a level 1 scroll, this information goes to client, then it changes to level 3, this information don't goes to client. On client side you can examine scroll with level 3, but in inventar the scoll is showed with level 1. You need drop it once, or relog with player. Changing the position of the assert command didn't change this behavior.

Depending to this, this level 1 scroll also don't stack to the level 3 scrolls. Again you need drop it or relog. I don't tested what happens, when you have some real level 1 spells in your inventar and create a level 3 scrolls with this system. I think it will stack to your level 1 scrolls and then you change levels of all the scrolls or it crashes? Must test this.

So using CreateObjectInside(Ex) is currently a very bad style in lua and every scripter uses this function. It's ok if you want to create a unique special quest item and don't want this put in a container.

My next solution is a little better. Using game:LoadObject. This was really tough for me to find, because i have no demo script how to use this. I found 1 forum thread to this.
Code: [Select]
  local test_arch = "arch scroll_x\nend"
  local test = game:LoadObject(test_arch)
  test.level = 5
  test:InsertInside(pl)
My understanding of this way is still limited. But it looks like we generate a unique arch definition. You can define the whole arch definition in the string before you load the object. But to be more compatible to above code, i only use this empty  test_arch = "arch scroll_x\nend" definition. It looks like arch are identified by name and title of the arch, so when generating this, server graps first the object definition out of archetypes/artifacts when we use game:Object(test_arch).

So till here it's the same then with CreateObjectInside(Ex), except our object is not loaded to the player inventar. So now we can change, before client get the informations. Here i change the level of the scroll to 5 and than i use test:InsertInside(pl). This way scroll is showed with correct level and stacks correct.

But this way we have still the same Ticket 75 problem, scrolls don't go to an open container. Didn't managed to make the pickup function working to test this way, i will try to go there next.
« Last Edit: 10, January 2022, 13:04:12 by Dolfo »
Don't believe the shit, you hear in mainstream. Believe your own body. Your body is speaking always the true to you. But you need to understand your body. Hear to your body, not to your ego. And when body is calling to you: "Hey something is wrong!" find the reason(s) for that. Man in White don't go for that, they don't want to heal you. They want earn money and sell you medicine, you should take rest of your life. You are not the patient, you are their customer. Never forget this!

Dolfo

« Reply #1 on: 11, January 2022, 16:53:07 »
Code: [Select]
  local test_arch = "arch scroll_x\nend"
  local test = game:LoadObject(test_arch)
  test.level = 5
  pl:PickUp(test)
But better fix this bug first.
https://www.daimonin.org/12234/nasty-bug-in-thingpickup/msg109654/topicseen/#msg109654

I feels good to read:
"You pick up the scroll to write spells (lvl 5) and put it into your basilisk leather rucksack."
It also works with my idea of marked containers. I must check if the above bugfix also cleaned another bug i noticed.

And then we have the problem, that the "whole world" used CreateObjectInside(Ex) ?
Perhaps we go there in and make a kind of logic to fix this problem there? But normaly all scripts should uses PickUp. :o
« Last Edit: 11, January 2022, 16:58:39 by Dolfo »
Don't believe the shit, you hear in mainstream. Believe your own body. Your body is speaking always the true to you. But you need to understand your body. Hear to your body, not to your ego. And when body is calling to you: "Hey something is wrong!" find the reason(s) for that. Man in White don't go for that, they don't want to heal you. They want earn money and sell you medicine, you should take rest of your life. You are not the patient, you are their customer. Never forget this!

Dolfo

« Reply #2 on: 11, January 2022, 21:51:16 »
Ok. I have read that game:LoadObject is not good on time sensitive coding. It also looks bad to code this way in lua. I looked deeper and found a better way. I build a "new" lua function. Ok it's more a clone, where i cutted some lines.
daimonin_object.h
Code: [Select]
static int  GameObject_CreateObject(lua_State *L);
daimonin_object.c
Code: [Select]
static int GameObject_CreateObject(lua_State *L)
{
  object_t *myob;
  int         value = -1, id = 0, nrof = 1;
  char       *archname;
  lua_object *whatptr;

  get_lua_args(L, "Os|iii", &whatptr, &archname, &id, &nrof, &value);

  myob = hooks->arch_to_object(hooks->find_archetype(archname));

  if (!myob)
  {
      char buf[MEDIUM_BUF];

      sprintf(buf, "object:Create(): Can't find archetype '%s'", archname);
      luaL_error(L, buf);

      return NULL;
  }
  if (value != -1) /* -1 means, we use original value */
      myob->value = value;

  if (id)
  {
    THING_IDENTIFY(myob);
  }
  if (nrof > 1)
      myob->nrof = nrof;

  return push_object(L, &GameObject, myob);
}
From lua site it's now 2 code lines.
Code: [Select]
  local ob = pl:CreateObject("bread1", game.IDENTIFIED, 1) -- create 1 identified item
  pl:PickUp(ob)
And between CreateObject and PickUp we can change the attributes. It now depends on scripters if they want force object creation in player inventar with CreateObjectInside(Ex) or want the container logic from PickUp. Can you close ticket 75?  :P
« Last Edit: 11, January 2022, 21:56:08 by Dolfo »
Don't believe the shit, you hear in mainstream. Believe your own body. Your body is speaking always the true to you. But you need to understand your body. Hear to your body, not to your ego. And when body is calling to you: "Hey something is wrong!" find the reason(s) for that. Man in White don't go for that, they don't want to heal you. They want earn money and sell you medicine, you should take rest of your life. You are not the patient, you are their customer. Never forget this!

Dolfo

« Reply #3 on: 13, January 2022, 17:21:35 »
Ok, when you want to PickUp more then 1 item you need other syntax.
Code: [Select]
  local ob = pl:CreateObject("bread1", game.IDENTIFIED, 10) -- create 10 identified items
  pl:PickUp(ob, nil, 10)
You can also change nil to say where to pickup, but normaly in most cases nil is better so pickup can go to applied containers.
Don't believe the shit, you hear in mainstream. Believe your own body. Your body is speaking always the true to you. But you need to understand your body. Hear to your body, not to your ego. And when body is calling to you: "Hey something is wrong!" find the reason(s) for that. Man in White don't go for that, they don't want to heal you. They want earn money and sell you medicine, you should take rest of your life. You are not the patient, you are their customer. Never forget this!

_people_

« Reply #4 on: 14, January 2022, 17:59:14 »
I committed this to trunk but with a couple of changes. First, I moved it to the Game class because the object calling it doesn't get utilized at all. The other change I made was to replace the "if !myob" block contents with just a single "return luaL_error" call because that also supports VarArgs like sprintf does. Also because my compiler threw warnings treated as errors because of returning NULL from a function returning an int.
-- _people_ :)

Dolfo

« Reply #5 on: 14, January 2022, 18:21:31 »
Cool, i still try to read deeper how lua handles objects. I am currently here.
Code: [Select]
local ob = pl:CreateObject(test_arch, game.IDENTIFIED, 10) -- create 1 identified obj
local mem_ob = ob
pl:Write(ob.quantity, game.COLOR_YELLOW) -- <- output is 10
local re_ob = pl:PickUp(ob,nil,n) -- <- Pickup returns 0 or an object
if re_ob~= nil then
  pl:Write(ob.quantity, game.COLOR_YELLOW)
  pl:Write(re_ob.quantity, game.COLOR_YELLOW)
  pl:Write(mem_ob.quantity, game.COLOR_YELLOW)
end
Sadly all 3 objects have the same value. This means when pickup merge to another stack for example put 10 water to 100 water, all three objects have quantity 110. And when pickup splits the ob because of weightlimit, we have the same effect, we get the splitted quantity and rest of the object is lost.
I can write a workaround in lua, make a memory for the quantity and try to compare that later.
But when i buy 100 water and can carry only 50 and perhaps i have also 50 on inventory before, my compare idea is nuts. Same would be if i try to clone the object before and give it an own instance.

So yeah the return behavior from PickUp is very hard, so PickUp must handle this alone. I try to read deeper there. It's really ugly there. The whole weight logic is broken, don't know if it handles container of reducing weight?

Edit: I have seen you have changed logic in PickUp. I must test this this enforcement of weight check too.
« Last Edit: 14, January 2022, 18:37:23 by Dolfo »
Don't believe the shit, you hear in mainstream. Believe your own body. Your body is speaking always the true to you. But you need to understand your body. Hear to your body, not to your ego. And when body is calling to you: "Hey something is wrong!" find the reason(s) for that. Man in White don't go for that, they don't want to heal you. They want earn money and sell you medicine, you should take rest of your life. You are not the patient, you are their customer. Never forget this!

Dolfo

« Reply #6 on: 15, January 2022, 12:13:39 »
Ok here is a balm of minor healing level 5 now using game:CreateObject
Code: [Select]
--local balm = game:CreateObject("balm_generic", game.IDENTIFIED, 1)
local balm = game:CreateObject("balm_first_aid", game.IDENTIFIED, 1)
balm.title = "of minor healing"
balm.level = 5
balm.spellpoints = 2 -- minor healing spell -- c uses sp -- lua uses spellpoints for the spellnumber
pl:PickUp(balm) -- pl:PickUp(balm, nil, 1)
Was a long trip to come here. But now i can build this from archetype balm_generic or artifact balm_first_aid. They are nearly the same. One is defined as magic balm, other not.

And your name conversation to lua is ugly.
In c it's "sp" for spellpoints or for spellnumber -> lua it's "spellpoints" for spellpoints or for spellnumber
same "shit" here
In c it's "nrof" for the amount of items -> lua it's "quantitiy" for this?
I searched hours how to change nrof, till i have recognized this difference in name definitions.
That's really really ugly to define the same object with different attribut names.
Who made such nonsense?  :P
« Last Edit: 15, January 2022, 12:20:12 by Dolfo »
Don't believe the shit, you hear in mainstream. Believe your own body. Your body is speaking always the true to you. But you need to understand your body. Hear to your body, not to your ego. And when body is calling to you: "Hey something is wrong!" find the reason(s) for that. Man in White don't go for that, they don't want to heal you. They want earn money and sell you medicine, you should take rest of your life. You are not the patient, you are their customer. Never forget this!

Tags:
 

Related Topics

  Subject / Started by Replies Last post
6 Replies
2958 Views
Last post 11, September 2006, 21:33:47
by swords_kid
2 Replies
1753 Views
Last post 07, September 2007, 13:00:46
by smacky
15 Replies
2750 Views
Last post 21, April 2008, 17:52:10
by smacky
8 Replies
20192 Views
Last post 24, October 2012, 15:57:13
by clobber
7 Replies
138 Views
Last post 14, August 2023, 14:26:48
by Dolfo