Here's a copypasteable way to do this using a bit of javascript that will enable the same common event to be usable for every item that is meant to teach characters something:
- Create a common event and paste the script below into an event's conditional branch script box.
- Have an item (single target, not full party) call this common event. Make sure this item is nonconsumable (we'll consume it in the common event only if it successfully teaches something to someone). Set the ID of the skill to be taught in the item's note tag as follows: <Skill: 12345>, with 12345 being whatever the skill's ID is. The note tag is case sensitive, so make sure it's "Skill" and not "skill" or "SKILL" etc.
- Set actors to be able to learn a given skill by having it in their normal level-up skill list. If you don't want them to learn it normally, just set it to something absurdly high (past whatever level cap you might have, if you can do that. Can you? I didn't test that...)
- The big long mess posted below will return true if it teaches the actor the skill, false if they already know it or it isn't in their class's available skill list.
Code:
(function(x){ return !($gameParty.targetActor().currentClass().learnings.reduce((arr, obj) => arr.concat(obj.skillId), []).contains(x) && !$gameParty.targetActor().hasSkill(x) ? $gameParty.targetActor().learnSkill(x) : true); })(+$gameParty.lastItem().meta.Skill || 0)
Common event should be something like this:
Note that you can set the veriable to be whichever one you want, like 10 or 200 or something in case you're already using 1. Just make sure to reflect it it in the text displays, too (the \V[1] part).
Good luck and let me know if it doesn't work.
PS: I know everyone says "find out which actor was targeted in common events using a hidden state and conditional branches," but you can more easily get the target actor with $gameParty.targetActor(). Hence why there's no hidden states required in this solution.