Jump to content
  • 0

Looking To Hire A Consultant


tk422

Question


Hello

 

I'm hoping to find someone willing to act as a consultant for my project. The goal is to have a dedicated person i can email or Skype with to answer questions or make suggestions mostly related to AI and more advanced scripting. I'm not looking to annoy or waste anyone's time with silly things like setup or basic administration tasks.

 

I will of course pay you for your time and expertise.

 

By day i work as an IT consultant / programmer and am great at solving problems on my own when given small hints or direction.

Sometimes with L2 stuff though it's difficult to find documentation or explanations beyond the basics.

 

Here's an example of the current questions i have:

 

// AI


        Is there a more complete list or documentation for each functions?

- How would i find a list of all the handlers and their associated parameters? 

- Handlers pass in objects with types like CSharedPartyData, SharedCreatureData and SkillQuestList.

        How do i figure out what properties are available for each?

- Does myself == the NPC who's is executing the AI? Similar to the 'this' keyword in C++ when referencing an instance of the a class?

- What is myself.sm?

- Is the gg namespace just a pool of global util functions? Is there a list of them?

 

// Scripts

In some cases like with Vuku Orc, in NPCData there are multiple parameters set for npc_ai.

 

npc_ai={[vuku_orc];{[MoveAroundSocial]=138};{[MoveAroundSocial1]=138};{[MoveAroundSocial2]=138};{[setHateRace]=@race_elf};{[setHateRaceRatio]=10}}

 

It looks like these are declared in the monster_parameter parent class and that the values  are injected at runtime from NPCData.

   - Is this accurate? 

 

If i were to make a new param of type string called "name" and then added {[Name]=ScaryMonster} in NPCData,

    - Would this work?

 

- Could i then something like myself::Say(Name); ?

 

 

- What is watch_list.txt for?

- What is skill_pch2.txt for?

- What is quest_pch2.txt.txt for?

 

 

Thanks to everyone for their time.

Edited by tk422
Link to comment
Share on other sites

7 answers to this question

Recommended Posts

  • 0

1. No, leaked files generally do not contain guides on how to optimally abuse their intellectual propety.

2. You have the programs that use them, go research. ...but should be a list of a function events and handlers in this forum somewhere for both GF & C4, most are self explanatory.

3. See above.

4. myself is the AI instance\class where code is executed, which doesn't always mean a NPC instance but could be a Makerinstance also.

5. A CSharedCreatureData struct within AI class, for npc instances.

6. Yes, see 2.

7. Load time, not run time.

8. If declared properly, yes.

9. See above.

10. A watch list, most likely used with l2logd. Fairly pointless for most private servers. Probably monitoring measures if large quantity or rare items suddenly explode within the game world.

11. Same as skill_pch - just with different data.

12. Same as above, with quest.

Edited by mcbigmac
Link to comment
Share on other sites

  • 0

Wow, thanks for all the info!

 

LOL at number 1. I meant community documentation, but i guess was a silly question either way.

Sorry about that. :P

 

I have have the list of handlers and functions, but its the parameters that i'm not sure about.

 

Example:

EventHandler MY_DYING( always_list, code_info, i9, last_attacker, lparty, member, random1_list, target )

always_list   = ??

cose_info     = ??

i9                  = ??

last_attacker = Last player to attack the NPC

lparty            = Last party to attack the NPC?

member        = Last member of the party to attack the npc? Doesn't this always equal last_attacker?

random1_list = ??

target            = The target NPC had when it was killed.

Edited by tk422
Link to comment
Share on other sites

  • 0

If you actually viewed AI you'd see it make sense.

 

i0 to i9 are empty integer storage registers for integer vars

c is the same for creatures.

 

_list are list variables of creatures\members used to store run thru checks for quests when a party is the last attacker.

code_info is related as well.

 

The actual logic for why things are coded this way i forget - but going thru AI should reveal why the need for temporary storage vars are needed.

I believe but i can't remember for sure - it's used for proper threading\handling due to l2npc lag being a very real thing when badly coded handlers are executed 100 times per second.

This is especially true for itemgiving \ dropping commands that go back to l2server with interpacket communication.

 

If no logic is found - then l2npc is always there to research why specificly.

Either way following their syntax\logic for new quests is advised.

Edited by mcbigmac
Link to comment
Share on other sites

  • 0

Wow, ok really interesting!

 

So for example:

handler 1 39    //  ATTACKED
    variable_begin
        "myself"
        "_choiceN"
        "_code"
        "_from_choice"
    variable_end

When decompiled looks like: (Took this from Frintezza just because it has a lot of handlers to look at)

  EventHandler ATTACKED()
  {
    if( myself.sm.db_value == 1 )
    {
      myself::SetDBValue( myself.sm, 2 );
      myself::AddTimerEx( 10000, 1000 );
    }
  }

The actual compiled AI handler is sort of saying 

- "Here are all the registers / vars i'm willing to give you to work with for this handler."

- "Whatever AI code you're going to write, it must only take up *this* amount of memory".

- "You can reassign them, reuse them, whatever, but you may not have any more ram."

 

1. Is this somewhat accurate?

 

Looking at the ATTACKED handler for the "warrior" base class:

handler 1 807    //  ATTACKED
    variable_begin
        "attacker"
        "damage"
        "f0"
        "myself"
        "_choiceN"
        "_code"
        "_from_choice"
    variable_end

This has more params passed in. attacker, damage, f0.

 

2. Why were these not available for Frintezza's ATTACKED handler?

3. I'm assuming f0 = foat register 0?

 

There is also another oddity:

In some of the handlers, "gg" is passed in. In others, it's used without being defined as a compiled param or a decompiled one.

You can see below that GG is used (i realise this is a comment but you can see it in the decompiled version)

class 1 orc : warrior_passive
handler 10 289    //  MY_DYING
    variable_begin
        "always_list"
        "c1"
        "code_info"
        "i9"
        "last_attacker"
        "lparty"
        "member"
        "random1_list"
        "target"
        "myself"
        "_choiceN"
        "_code"
        "_from_choice"
    variable_end

    push_event    //  always_list
    push_const 688
    add
    push_reg_sp
    fetch_i
    push_event    //  gg <<<<<<<<<<<<<<<<<<<
    push_const 632

4.

Looking at Orc's superclass "warrior" i'm noticing that the MY_DYING handler is defined here too.

AND Orc's MY_DYING handler calls super.

So is the gg param definition init'd in the super class which is why you can use it in the child?

You're basically extending the super handler?

 

5.

Would you say this rule is somewhat accurate:

- All "word" params passed in to a handler's arguments like "talker", "myself", "lparty", "member", "target", etc are "living" objects that can be queried / operated on.

- All things like c0, f0, i0 are just registers for you to work with. Kind of like CPU registers in real ASM.

 

6.

If you look at the compile at for Imp you can see that i9 has been defined.

class 1 imp : warrior_passive
handler 10 268    //  MY_DYING
    variable_begin
        "always_list"
        "c1"
        "code_info"
        "i9"
        "last_attacker"
        "lparty"
        "member"
        "random1_list"
        "target"
        "myself"
        "_choiceN"
        "_code"
        "_from_choice"
    variable_end

Looking at the super classes though the only one that has i-anyhting is warrior, but that only provides i0, and i1.

So where are i2 - i8 being used?

 

BTW, Can't thank you enough for taking the time to help with this. Hope im not being annoying, just trying to figure out the system to all this.

Edited by tk422
Link to comment
Share on other sites

  • 0

1. No.

Go see 1. of previous post - and research l2npc for true definitions.

Anything in native handlers can be considered fairplay - rest should be tested.

 

2.

Is frintezza native  ? - no it's custom-made.

 

3. Yes.

 

4. GG is a namespace, not a variable, event or similar. call_super does exactly what it says, calls the superceeding class, no more no less.

 

5. All living used objects need to be declared in the handler. How logic specificly works\requires - you can find in l2npc.

I do not recall the side-effects of not declaring - but there are some- While the code may technicly execute to your desired effect. (probably memory leaks and wastage for cleanup when handler is done).

 

6.

 

Oh look, r8\r9 is not used anywhere - where are they?

Dumb question.

 

 

.text:000000000082CEB0 sub_82CEB0 proc near
.text:000000000082CEB0 push    rbp
.text:000000000082CEB2 sub     rsp, 20h
.text:000000000082CEB6 mov     rbp, rdx
.text:000000000082CEB9 lea     rcx, [rbp+48h]
.text:000000000082CEBD call    sub_402930
.text:000000000082CEC2 add     rsp, 20h
.text:000000000082CEC6 pop     rbp
.text:000000000082CEC7 retn
.text:000000000082CEC7 sub_82CEB0 endp
Link to comment
Share on other sites

  • 0

Sent you a PM.

 

Anyway,

 

Opened a C4 NPC server in Hopper and found these:

 

- int CNPC::HandleEvent(CNPCEvent* pEvent)

- void CNPC::Attacked(CSharedCreatureData* spAttacker, int nDamage, int nWeaponClassID, int nSkillNameID, bool bPartyEvent)

- CNPCEvent* CNPCEventFactory::CreateAttackedEvent(CNPC* pNPC, CSharedCreatureData* spAttacker , float damage, int nWeaponClassID, int nSkillNameID)
 
I have to guess what happens since i don't quite understand ASM.
 
- When NPC server starts it creates a lookup table in memory of all the NPC's.
- As it parses the AI.obj file, for each NPC it reads the AI handlers defined in AI.obj, Attacked, My_Dying, etc.
- Those are then turned into CNPCEvent objects and then added to the npc's handler lookup table.
- When an NPC is attacked (or whatever) the NPC server checks to see if that event is handled then
   executes the handler like this->HandleEvent(event);
 
1.
- I'm assuming that the reason the NPC server uses the compiled format is due to speed.
- On NPC server boot, when a handler is created according to the behavior defined
  in NPCData, the AI must be parsed as-is and stored internally as the ASM-like sequence
  of instructions you see in the "compiled" language.
- i'm assuming that the ASM-ish language is faster to parse than something that needs to be jit'd
  or compiled during NPC server boot.
- Also AFAIK NPC's don't exist until a player walks in, all the AI would need to be jit'd
  which would be a huge pain for situations where there are many different NPC's in one area.
 
2. - I think i'm somewhat heading in the right direction but none of it answers how to know
      what handler params are valid.
 
    - If i wrote a parser that read through the AI file and make lists of all possible
      params for a particular handler, could i then assume that if it's used somewhere
      by some NPC, it's got to be valid always for that handler?
 
    - Example: if i find that an ATTACKED handler for one NPC passes the "damage" param and thats it,
      if i see another NPC that has "damage" AND "attacker" that means the first one COULD ALSO
      have had "attacker" it just didnt because it wasn't used?
    - If c1 was passed in for one handler (say My_Dying) but i don't see it for another, can i assume
      it could have been defined but just wasn't?
 
3. Are the registers that are passed in (f0, c1, i2, etc) kind of like guaranteed free
    space for you to work with if you need to store something temporarily?
    (I think this is what you wrote earlier but i want to be sure)
 
Again, thanks for taking the time to help with this.
Edited by tk422
Link to comment
Share on other sites

  • 0

1.

Yes.

And L2npc can pause-stop execution of active instances if no player near. In c4 its a switch in menu - whereas its more automated in GF.

 

2.

Yes

 

3.

 

Yes - although coNfirmed that iN last post last answer.

Edited by mcbigmac
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

AdBlock Extension Detected!

Our website is made possible by displaying online advertisements to our members.

Please disable AdBlock browser extension first, to be able to use our community.

I've Disabled AdBlock