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:  skill trainer  (Read 369 times)

0 Members and 1 Guest are viewing this topic.

Dolfo

« on: 01, November 2022, 04:25:36 »
I reworked my weapon trainer script. Made it more dynamic. You can mostly define skills, you want to allow to train, in an array. I cannot repeat often enough, how great this feels, to see a weapon trainer in early game in guildhall complex.

On my local server i have a dwarf npc called gimli there. I give an example, what a new player from dock is seeing, when he is talking to Gimli. In this example player is slash and also trained to level 3 slash.

Learn Cleave Weapons - 5s and 25c - I can teach you Cleave Weapons
Learn Impact Weapons - 5s and 25c  - I can teach you Impact Weapons
Learn Pierce Weapons - 5s and 25c  - I can teach you Pierce Weapons
Train Slash Weapons Level 4 - 35s and 28c - Train first more physique
Train Throwing Level 2 - 8s and 82c - Train first more agility

I used a new formula for training skill with money.
Code: [Select]
-- local costs = slevel * slevel * (50+slevel) * 3 -- old formula
local costs = 100 * slevel * slevel * 2 --new formula

This formula increase the prices for early game training by some silver and reduces the prices of late game skills about half the gold. So to train with a level 5 trainer to 110, we are still above 200 gold costs.

But a level 5 trainer can only train up to skill level 5, so you need to find a level 110 trainer to max a skill by money training and a 110 trainer takes 110% more money for this training.

I added throwing skills to my trainer, to see if the dynamic can also handle different skill groups, so looks fine. To use a trainer you need only to define the array with the lua skillname and an icon you want to see for this skill. Adjusting the level of a trainer goes to max level you can train and the costs.

Script need some update for hybrid training. For example if a player has grinded half a level, he need only half the money to finish his training by trainers. Currently i miss a function in lua to read the exp for next level. So this is todo.

In early game this feels really great, to see the weapon trainer. New players are often insecure, if they picked the right mellee skill. If they see the trainer, they also see, "Cool i can also learn the other skills here." This also eleminate the inbalance of item drops, if players can use every weapon at some point. Of course they need to train skills also by grinding or paying. But requirements are ph for weapon use, so they can use higher weapons to train there lower skills. example player trained slash to 10, he found a pierce 10 weapon, he starts to train his pierce 1 skill with this pierce weapon 10.

It also gives grinding for levels a new value. For example a player sees the cost of training for his next weapon skill. Then he thinks : "Wow my grinding training slash to level 4 is worth 35s and 28c? Why i am in town wasting time, lets kill more ants!"

If we implement weapon trainers and open all 4 mellee skills, we need some fixes on other scripts. It's mostly the winter weapon script, we need to rework. Best would be there, to let player choose what weapon style he want to pick as quest reward. For early fist weapon fanrir script we need also a small rework. I have some prototypes for this.

I can only say again and again, game will become much more better with weapon trainers and with all 4 weapon skills and all 3 archery skills opened to players. This is also a player wish, you can find in forum years ago.

Here is code of lua script
Code: [Select]
local me= event.me
local pl = event.activator

local MAX = 110 -- TODO if there is a way to get max player level from serverdefinitions, this would be better here

-- 1 must be the correct lua definitions for the skills
-- 2 must be valid icon for npc dialog
local to_train =
{
 {skill_name = "Cleave Weapons", icon = "axe_small.101"},
 {skill_name = "Impact Weapons", icon = "club.101"},
 {skill_name = "Pierce Weapons", icon = "dagger.101"},
 {skill_name = "Slash Weapons", icon = "shortsword.101"},
 {skill_name = "Throwing", icon = "t_dagger.101"}
}

-- lua has no good table count function, so we need to hardcode max length of our array or use this function
function getTableSize(t)
 local count = 0
 for _, __ in pairs(t) do
  count = count + 1
  end
 return count
end

local function npc_fee(costs)
 -- trainer % change depending to his level
 -- level 1 trainer wants 1% more
 -- level 10 trainer wants 10% more
 -- level 110 trainer wants 110% more
 costs = costs + costs / 100 * me.level
 return costs
end

local function to_pay(skill)
 local sobj = pl:GetSkill(game.TYPE_SKILL, skill)

 if sobj == nil then
  return 0 -- we simply return 0 here, only to avoid crash, normaly the checks for the skills are outside this function
 end

 local slevel = sobj.level + 1
 -- local costs = slevel * slevel * (50+slevel) * 3
 local costs = 100 * slevel * slevel * 2

 -- hybrid training - reduce the costs in relation to your present grinded exp.
 -- !!! this part need the GetExpThreshold function in daimonin_object.c
 -- without this function hybrid training didn't work
 local exp_threshold = pl:GetExpThreshold(slevel);
 if (exp_threshold) then
  local sexp = sobj.experience
  local exp_delta=exp_threshold - sexp
  if (exp_delta>0) then
   local exp_percent=100*exp_delta/exp_threshold
   costs = costs/100*exp_percent
  end
 end
 return costs
end

require("interface_builder")
local ib = InterfaceBuilder()

local function topic_greeting()
 ib:SetTitle("Greetings")
 ib:SetMsg("Ey, you want some weapon training?")
 ib:AddMsg("\n\nI know a lot about weapons.\n")
 ib:AddMsg("\n\nI can train you to handle cleave, impact, pierce, slash weapons and can show you, how to become better in this skills.\n")
 ib:AddMsg("\n\nI also know some basics about throwing weapon skills, if you need some training there.\n")
 ib:AddLink("Sure.","Services")
 ib:AddLink("No, not now.","")
 ib:SetLHSButton("Services")
end

local function topic_services()
 ib:SetTitle("Training")
 ib:SetMsg("So, what do you want?")
 ib:AddMsg("\n\nYou have " .. pl:ShowCost(pl:GetMoney()) .. ".")

 for index, data in to_train do
  local skill_number=game:GetSkillNr(data.skill_name)
  if skill_number==-1 then
   ib:AddMsg("\n\nERROR : There is no definition for " .. data.skill_name .."!")
  else
   local skill = pl:GetSkill(game.TYPE_SKILL, skill_number)
   if skill == nil then
    ib:AddSelect("Learn " .. data.skill_name .. " - " .. pl:ShowCost(npc_fee(500)) , "learn " .. index, data.icon, "I can teach you ".. data.skill_name)
   else
    local slevel = skill.level + 1 -- level to train
    if (slevel<MAX) then
     if (slevel<=me.level) then
      local skill_group = pl:GetSkill(game.TYPE_SKILLGROUP, skill.magic) -- in skill.magic we find the skill group
      if skill_group ~= nil then
       if skill_group.level >= slevel then
        ib:AddSelect("Train " .. data.skill_name .. " Level " .. slevel .. " - " ..   pl:ShowCost(npc_fee(to_pay(skill_number))) , "train " .. index, data.icon, "I can train you in ".. data.skill_name)
      else
       ib:AddSelect("Train " .. data.skill_name .. " Level " .. slevel .. " - " .. pl:ShowCost(npc_fee(to_pay(skill_number))) , "services" , data.icon, "Train first more " .. skill_group.name)
      end
     else
      ib:AddMsg("\n\nERROR : Somehow you managed to get " .. data.skill_name .." skill without a skillgroup !")
     end
    else
     ib:AddSelect("Train " .. data.skill_name .. " Level " .. slevel, "services", data.icon, "I can't train you anymore.")
    end
   else
    ib:AddSelect("Train " .. data.skill_name, "services", data.icon, "Who in the world should train you? You are really a master!")
   end
  end
 end
end
ib:SetLHSButton("Back","services")
end

local function topic_learn(index)
 ib:SetTitle("Learn skill " .. index)
 ib:SetLHSButton("Back", "Services")

 if index~=nil then
  local i = tonumber(index)
  if i>0 and i <= getTableSize(to_train) then
  local skill_number=game:GetSkillNr(to_train[i].skill_name)
   if skill_number~=-1 then
    if pl:GetSkill(game.TYPE_SKILL, skill_number) ~= nil then
     ib:SetMsg("\nYou like to troll me?.\nYou already know this skill.")
     return
    end

    if pl:PayAmount(npc_fee(500)) == 1 then -- 5 silver + npc fee
     pl:AcquireSkill(skill_number, game.LEARN)
     ib:SetMsg("You learned " .. to_train[i].skill_name)
    else
     ib:SetMsg("\nYou don't have enough money.\nCome back if you have the money.")
    end
   return
   end
  end
 end
ib:SetMsg("I don't know this skill.")
end

local function topic_train(index)
 ib:SetTitle("Train skill " .. index)
 ib:SetLHSButton("Back", "Services")

 if index~=nil then
  local i = tonumber(index)
   if i>0 and i <= getTableSize(to_train) then
    local skill_number=game:GetSkillNr(to_train[i].skill_name)
     if skill_number~=-1 then
      skill = pl:GetSkill(game.TYPE_SKILL, skill_number)
      if skill == nil then
       ib:SetMsg("\nYou like to troll me?.\nYou better learn this skill first, before try to train it.")
      return
    end

    local slevel = skill.level + 1
    if (slevel>me.level) then
     ib:SetMsg("I can't train you anymore.")
     return
    end
    if (slevel>MAX) then
     ib:SetMsg("Who in the world should train you? You are really a master!")
     return
    end

    local skill_group = pl:GetSkill(game.TYPE_SKILLGROUP, skill.magic) -- in skill.magic we find the skill group

    if skill_group ~= nil then
     if skill_group.level >= slevel then
      if pl:PayAmount(npc_fee(to_pay(skill_number))) == 1 then
       pl:SetSkill(game.TYPE_SKILL, skill_number, slevel, 0)
       ib:SetMsg("You trained " .. skill.name)
      else
       ib:SetMsg("\nYou don't have enough money.\nCome back if you have the money." )
      end
      return
    else
     ib:SetMsg("Train first more " .. skill_group.name)
    end
    return
   else
    ib:SetMsg("\n\nERROR : Somehow you managed to get " .. data.skill_name .." skill without a skillgroup !")
    end
    return
   end
  end
 end
 ib:SetMsg("I don't know this skill.")
end

require("topic_list")
local tl = TopicList()

tl:SetDefault(topic_greeting)
tl:AddServices(nil, topic_services)
tl:AddTopics("learn (%d+)", topic_learn)
tl:AddTopics("train (%d+)", topic_train)
ib:ShowSENTInce(game.GUI_NPC_MODE_NPC, tl:CheckMessage(event, true))
« Last Edit: 02, November 2022, 16:43:33 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: 01, November 2022, 10:10:56 »
build in a function in plugin_lua to get access to ExpThreshold array.

declaration in daimonin_object.h
Code: [Select]
static int  GameObject_GetExpThreshold(lua_State *L);
declaration in daimonin_object.c
Code: [Select]
{"GetExpThreshold", (lua_CFunction) GameObject_GetExpThreshold},
function in daimonin_object.c
Code: [Select]
/* get the ExpThreshold value for a specific level  */
static int GameObject_GetExpThreshold(lua_State *L)
{
 lua_object *self;
 int level;

 get_lua_args(L, "Oi", &self, &level);
 if (level<0 || level >110) // todo this should be servermaxlevel not hardcoded 110
 {
  return 0; // error
 }

lua_pushnumber(L, hooks->exp_threshold[level]);
return 1;
}

edit: I updated the above lua script. It supports now hybrid training. This means mainly the costs for training to next level goes cheaper when you grind exp before. So players can stop their grinding for example at 90% and finish the skill with only 10% rests costs. Hybrid calculation only works with the above GameObject_GetExpThreshold function.

edit: I updated lua script. I removed calls for deprecated lua funcion FindSkill. It's now all done by GetSkill.
« Last Edit: 02, November 2022, 16:45:19 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: 14, November 2022, 15:12:48 »
I have separated the kernel logic to npc_trainer.lua, like i have done with shop. Also trainer logic targets now topic_training instead of topic_services, so services is free and could be a kind of "Table of Contents" for the services a npc can do. So services should be splitted to a kind of.

shop
training
smithery - or split this more in
-> repairing
-> reforging
-> rebalancing
-> identifying
...

But for the moment i am lucky, that i had split shop and training from services. Also for some npc`s we don't need a split between hi and services. It could be enough to combine this, like

"Hi, i am npcX. What can i do for you? You want see my shop. Or do you need some training." When we manage to improve Sentence this could go also to site menu."

So my combined old_ninja shop/punch trainer works fine now. I also updated my other scripts to this. Tried also to change frahka to the new skill trainer idea.

I stop posting lua snippets here in forum, it's a pain to format this to a readable text. I used my old github presentation server to upload my newer lua scripts there. So it's a bit messy with older lua scripts in there. But you see the timestamps whats new.

npc_trainer is in https://github.com/Kamor/Dolfo/tree/main/maps/scripts
npc in castle area are in https://github.com/Kamor/Dolfo/tree/main/maps/planes/human_plane/castle/scripts
npc in guildhall area are in https://github.com/Kamor/Dolfo/tree/main/maps/planes/human_plane/castle/guildhall
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: 16, November 2023, 22:35:45 »
I uploaded this now on trunk. Tested mainly everything on trunk. I need some last test for non trunk quests, like winterweapon quest, but this is mainly some script fixing. Could be, this works also fine, when it targets the new melee_weapon_skill.lua?

So I made skill trainer now this way.
First you need to find a skill trainer. Atm there is only Gimli level 5 in trunk guildhall.
Then it depends on the trainer level and what skills he is allowed to train.
Players need at least the main level to train skills. So all chars must grind their main exp for sure.
Players can also train skills including the stats (skill group). But this will double the costs.
Costs also depends on trainer level, so it's good to train first on the lower trainers, so far they can train.

If you think this is to inbalanced to train now skills, think of this.
To train a level 109 skill to 110, you need a 110 trainer.
The costs for this training is atm 1 silver * skilllevel^2 * 2.
That's 242 gold. But the 110 trainer takes a 110% fee, so we have 508,2 gold here.
If this skill is also increasing the stats (skill group) this will double the costs, so we have more than 1 mith costs here.

If skills are grindable, and you have grinded exp, before going to the trainer, this will reduce the costs, in relation to the percentage experience. So if player grinded 90% to next level, he needs only pay 10% of the total costs, to finish his level. I call this hybrid training.

Rest depends on players and their playstyles.

We had often situation, where one player has ask another player for some group actions, where the answer was, "Ok, but let me finish first my level." Now we have options to finish this level in town.

This is also a big money sink and opens a new playstyle to train skills, by making business and getting money.

Campers can try to sell their camped gear to other players (I still hope we come there back) and invest this money in skill training they want.

Also low skill training is now much more interesting. You invest some gold coins, till you think that's enough waste of your money and continue to grind the skill in your favourite hunting areas.

Classic grinding becomes a new value, when you see, "Wow, that skill trainer wanted to rip me, I grinded this now and safed my money. He can eat his bread from yesterday now, and I buy me booze, harhar."

And don't forget this opens also multi skill, so this are 5 more skills (+3 melee,+2 archery) each player can train.

So currently it's only Gimli in guildhall on trunk, he is level 5 and can teach and train all 4 melee weapon skills and the throwing skill to 5. That's all.

Next scripts I want to implement trainer logic is Frah'ak level 8 for traps and commander Taleus level 25 for range weapon skill. I have also a ninja level 45 training punching, but this need to wait till I can upload my npc_shop, because this ninja should be a punch trainer and ninja gear seller.
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!

Shroud

« Reply #4 on: 18, November 2023, 00:57:09 »
Well I looked into numbers and training a skill from lvl 1 to 110 is around 9m. If you add a 110% trainer surcharge to that then total ends up at around 18.9m for one skill to get maxed out. If I was using it I'd probably either just use it to learn skill or spend around 100g that gets you to lvl 24 or if really impatient then 1m that gets you to lvl 52 and in both cases that's before trainer surcharge.

It feels expensive but I guess if someone finds a RoA they'll be able to max out all their stats if they sell it.

I'm unsure if it will work that way but potentially players could skip the archery quest altogether and learn all 3 archery skills at the skill trainer. I don't think it would break the quest if you got all 3 beforehand as I think some people with the level bug would have broken it when they lost all skills and had it manually added by SAs
Doesn't matter, you'd die anyway. ;D Shroud's a hacker. After many hours of deep thought I have came to that conclusion.

Dolfo

« Reply #5 on: 18, November 2023, 02:27:57 »
Sure this could be rebalanced. We could also increase the money gain on royal bounty hunter. Don't forget you can also train hybrid, so using this mechanic to speed up level training a little.

Archery quest are my next todo, working on chereth, frahak and taleus quest, where frahak and taleus should also be skill trainers. I want a more intelligent reward. If you have not the skill, you get this as reward. If you have it bought before, you get instead perhaps 1k exp for this skill. Must see.

Also all npc's miss atm discount and other bonuses we have in normal shop. So prices could be decreased by bankcard, charisma and royal fame later. That could be around 11%+11%+15% you can buy it cheaper.

Talking about the fee, you can also save a lot money, if you find lower trainers. So perhaps you level a skill with a level 10 trainer first to level 10 for +10% fee, than travel to next trainer level 50, you continue there to train your level to 50 for +50% fee, perhaps you find also a level 100 trainer somewhere, till you finally finish at a level 110 trainer. Could be there is no level 110 trainer in game.

In relation to this I want implement a transfer from royal exp to skill exp, so we have a third option to train skills and players can shortcut low skill training by money or royal experience or finish a 90% grinded level with money/royal experience. I also thinking about books you can find to gain skill exp, but this is more an idea for later.

For the money based training we must find the balance between what is fair, but also hard enough price to train a skill from 1 to 110 by only using money for this. We can't make it to cheap. Clicking a skill from 1 to 110 for 1 mith, I think is to cheap.
« Last Edit: 24, November 2023, 03:14:00 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
12 Replies
1667 Views
Last post 07, September 2005, 17:39:53
by Elephantey
2 Replies
9568 Views
Last post 17, June 2007, 22:16:47
by modularfish
0 Replies
724 Views
Last post 29, June 2007, 21:21:25
by zrubavel
21 Replies
19801 Views
Last post 18, September 2011, 15:52:39
by vencam3
4 Replies
184 Views
Last post 27, February 2022, 19:56:22
by Shroud