DSB's idle
Moderator: Sophia
Forum rules
Please read the Forum rules and policies before posting.
Please read the Forum rules and policies before posting.
DSB's idle
I was working on a EOB-esque two-weapon system for DSB, and was wondering about a few things concerning how DSB's champion idle works.
First, I noticed that it blocks mouse clicks in the attack option area for that champion if it's above 0. Under the old system, this was probably neccessary, but now the renderer handles the blocking by simply not creating a 'msgzone'. I'm wondering if this is redundant, or is there another reason for it.
Also, does the idle do anything else besides that (and act as a timer to tell the renderer it can draw the msgzone again)? I ask because in the system I used, I pretty much bypass the idle entirely (well, I still use it so that I didn't have to rewrite all the 'methods.lua' code, but I immediately set it to 0 after I get the value), and it seems to work, but I'm wondering if I'm unknowingly introducing side-effects I don't know about.
First, I noticed that it blocks mouse clicks in the attack option area for that champion if it's above 0. Under the old system, this was probably neccessary, but now the renderer handles the blocking by simply not creating a 'msgzone'. I'm wondering if this is redundant, or is there another reason for it.
Also, does the idle do anything else besides that (and act as a timer to tell the renderer it can draw the msgzone again)? I ask because in the system I used, I pretty much bypass the idle entirely (well, I still use it so that I didn't have to rewrite all the 'methods.lua' code, but I immediately set it to 0 after I get the value), and it seems to work, but I'm wondering if I'm unknowingly introducing side-effects I don't know about.
Hey ! Where is your R ???
If every one on the forum drops the last letter, things will get very confusing...
About the methods :
I've got a problem with my two-handed weapon : If the player opens the method menu, and then remove the left hand dummy item, he still gets a free two-handed attack.
I don't know how to solve that, in fact, I accepted it in the first place (as the same things happens with spellcasting) except by quickly removing and replacing the weapon in the right hand...
If every one on the forum drops the last letter, things will get very confusing...
About the methods :
I've got a problem with my two-handed weapon : If the player opens the method menu, and then remove the left hand dummy item, he still gets a free two-handed attack.
I don't know how to solve that, in fact, I accepted it in the first place (as the same things happens with spellcasting) except by quickly removing and replacing the weapon in the right hand...
What Is Your Quest ?
The 'R' was there out of habit - alot of places already have "Remy"s registered, but I prefer Remy to RemyR (it's also easier to type).If every one on the forum drops the last letter, things will get very confusing...
I'm not sure I quite understand you're problem (actually, I understand the problem, I don't understand what you're doing), so if I have this wrong, my apologies.
You have an weapon that requires two hands to use, so you "block" the left hand when the item is equipped by placing a dummy item into it. Or is it that to use the item, the player must combine two items (one in each hand)?
If it's the first, what happens normally when the player removes the dummy item? The way I would do this is with 'fit' and 'from' event functions on the main item. When it's placed in the right hand, spawn a new "dummy" item in the left (if there's room - if there's not, 'fit' should return false). When the dummy item is removed, you swap it for the main item (push the main item from the right hand to the mouse pointer) and destroy the dummy item.
I'm not sure how to handle the second scenario, though (two combined items), short of doing what you said - using the 'from' event to pop the right hand item out momentarily to clear the method menu. But, really, are they getting anything for free? If they use the method, they'll still get hit with the stamina drain and the delay penalty, right? So all they get to do is move the dummy item around, which really doesn't do them any good. Granted, it'd look wierd, but it's not rule-breaking per-se.
Basically, the two handed axe works this way :
When equiped, it offers only one method : "Wield".
If the left-hand is free, the method wield fills it with a dummy item, and sets an exvar for the two handed axe.
If the exvar is set, the two handed axe gives 3 attack methods, instead of the wield method.
If the dummy item is manipulated, it is destroyed and the exvar is cleared.
If the axe is manipulated, the dummy item is destroyed and the exvar is cleared.
When equiped, it offers only one method : "Wield".
If the left-hand is free, the method wield fills it with a dummy item, and sets an exvar for the two handed axe.
If the exvar is set, the two handed axe gives 3 attack methods, instead of the wield method.
If the dummy item is manipulated, it is destroyed and the exvar is cleared.
If the axe is manipulated, the dummy item is destroyed and the exvar is cleared.
What Is Your Quest ?
Well, just my opinion, but you might consider using dsb_push_mouse() to push the "true" axe to the mouse when a player tries to remove it from the left hand after you clear the exvar and destroy the dummy. It'll clear the method menu for you, and it fits logically with the player's actions (they're trying to unequip the axe - why should they get nothing?).
Well, for now the dummy item is just a hand with a doted outline to show it's being used.
I can consider replacing that by a shaded version of the axe, but I don't want to double all my icons just for that,
so I would have to create a shade mask... It can get really complicated.
I set "after_l_hand" for the dummy item and "after_r_hand" for the axe to the following function :
And the attack method function for the axe :
I can consider replacing that by a shaded version of the axe, but I don't want to double all my icons just for that,
so I would have to create a shade mask... It can get really complicated.
I set "after_l_hand" for the dummy item and "after_r_hand" for the axe to the following function :
Code: Select all
function un_wield(self,id,who)
local l_hand = dsb_fetch(CHARACTER, who, INV_L_HAND, 0)
local r_hand = nil
local mouse = dsb_fetch(MOUSE_HAND, 0, 0, 0)
if (l_hand and (dsb_find_arch(l_hand).class == "SECOND_HAND" ) ) then
if exvar[mouse] then
exvar[mouse].two_hands = nil
end
exvar[l_hand]=nil
dsb_delete(l_hand)
elseif (mouse and (dsb_find_arch(mouse).class == "SECOND_HAND") ) then
r_hand = dsb_fetch(CHARACTER, who, INV_R_HAND, 0)
if exvar[r_hand] then
exvar[r_hand].two_hands = nil
end
exvar[mouse]=nil
dsb_pop_mouse()
dsb_delete(mouse)
end
end
Code: Select all
function method_wield(name, ppos, who, what)
local item_id = nil
local weapon = nil
local hand = dsb_fetch(CHARACTER, who, INV_L_HAND, 0)
if (what) then weapon = dsb_find_arch(what) end
if (hand) then
dsb_write(system_color, dsb_get_charname(who) ..
" NEEDS HIS LEFT HAND TO WIELD THE WEAPON")
dsb_set_idle(ppos, dsb_get_idle(ppos) + 1)
else
item_id = dsb_spawn("second_hand", CHARACTER, who, INV_L_HAND, 0)
if (not exvar[what]) then
exvar[what] = { two_hands = true }
else
exvar[what].two_hands = true
end
dsb_write(system_color, dsb_get_charname(who) ..
" WIELDS HIS WEAPON WITH BOTH HANDS")
dsb_set_idle(ppos, dsb_get_idle(ppos) + 2)
end
end
What Is Your Quest ?
- Sophia
- Concise and Honest
- Posts: 4240
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
It's redundant now. I forgot to take it out.Remy wrote:First, I noticed that it blocks mouse clicks in the attack option area for that champion if it's above 0. Under the old system, this was probably neccessary, but now the renderer handles the blocking by simply not creating a 'msgzone'. I'm wondering if this is redundant, or is there another reason for it.
No, all it does is tell the renderer what to do now, and save the designer some exvar hijinks (provided you want a close approximation of the DM system, anyway...)Remy wrote:Also, does the idle do anything else besides that (and act as a timer to tell the renderer it can draw the msgzone again)?
You could always set an exvar on the dummy item that associates it with the real one, something like:Joramun wrote:I've got a problem with my two-handed weapon
Code: Select all
exvar[item_id] = { controller = what }
Code: Select all
if (exvar[id].controller) then
dsb_push_mouse(exvar[id].controller)
end
I just noticed something; there isn't a way for an arch's 'onthrow' event to tell whether it was called from a mouse throw or a method throw.
Now, normally this doesn't matter, but it could lead to a potential problem if the designer is using both 'onthrow' events and making changes to calc_tpower and/or calc_throw to allow for different inventory locations to return different results (for example: a throw from the left hand is weaker than a throw from the right hand).
The problem comes from this: normally, you'd use dsb_lastmethod to determine which inventory slot the attack originated. But the game engine calls the 'onthrow' event directly (without a method call) if the arch is thrown with the mouse. dsb_lastmethod won't neccesarily match in this case (and if the mouse throw is the first "method" that champion used in the game, dsb_lastmethod will return 'nil', which could be bad). sys_mouse_throw handles this by using a global ('mouse_throwing_hand'), but if there's an 'onthrow' event, sys_mouse_throw is bypassed entirely.
This is, of course, a very limited problem (it's the only sort of special case - all other attacks that may call upon calc_tpower and calc_throw come from methods), and I only noticed it because my idle system doesn't have a universal way of handling 'onthrow' events. The only potential solution I see at the moment is to just use sys_mouse_throw to call the 'onthrow' event (the same way method_throw_obj does now) instead of the engine doing it directly, that way they can be overriden to also pass along a inventory location to the event -- but then, I might be inclined to think that because it also fixes my idle system problem.
Now, normally this doesn't matter, but it could lead to a potential problem if the designer is using both 'onthrow' events and making changes to calc_tpower and/or calc_throw to allow for different inventory locations to return different results (for example: a throw from the left hand is weaker than a throw from the right hand).
The problem comes from this: normally, you'd use dsb_lastmethod to determine which inventory slot the attack originated. But the game engine calls the 'onthrow' event directly (without a method call) if the arch is thrown with the mouse. dsb_lastmethod won't neccesarily match in this case (and if the mouse throw is the first "method" that champion used in the game, dsb_lastmethod will return 'nil', which could be bad). sys_mouse_throw handles this by using a global ('mouse_throwing_hand'), but if there's an 'onthrow' event, sys_mouse_throw is bypassed entirely.
This is, of course, a very limited problem (it's the only sort of special case - all other attacks that may call upon calc_tpower and calc_throw come from methods), and I only noticed it because my idle system doesn't have a universal way of handling 'onthrow' events. The only potential solution I see at the moment is to just use sys_mouse_throw to call the 'onthrow' event (the same way method_throw_obj does now) instead of the engine doing it directly, that way they can be overriden to also pass along a inventory location to the event -- but then, I might be inclined to think that because it also fixes my idle system problem.
- Sophia
- Concise and Honest
- Posts: 4240
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
If I'm understanding correctly, the main limitation is that on_throw doesn't know where the throw originated.
How about this?
I'll change the beginning of method_throw_obj to the following:
Now, an on_throw invoked from an attack method will provide the location.
The on_throw called by the engine before a mouse throw won't provide this parameter, because it's not really "originating" from anywhere. (If you want to use the same hack the DSB code does, go ahead and use the mouse_throwing_hand global) This way, you'll be able to know where the throw came from, or that the throw was from the mouse hand, because that'll show up as nil. Old code will still work because it's not expecting that paremter anyway.
How about this?
I'll change the beginning of method_throw_obj to the following:
Code: Select all
local used_method, att_loc = dsb_lastmethod(ppos)
-- call the on_throw so we're consistent with sys_mouse_throw
if (throw_arch.on_throw and throw_arch:on_throw(what, att_loc)) then
return true
end
The on_throw called by the engine before a mouse throw won't provide this parameter, because it's not really "originating" from anywhere. (If you want to use the same hack the DSB code does, go ahead and use the mouse_throwing_hand global) This way, you'll be able to know where the throw came from, or that the throw was from the mouse hand, because that'll show up as nil. Old code will still work because it's not expecting that paremter anyway.
That'll work.
I did some testing, and realized that I was half-wrong. I thought that if an on_throw existed for an arch, it would supercede sys_mouse_throw: in other words, the event function would have to handle all the power settings and stuff and pass all that to dsb_shoot all by itself, and sys_mouse_throw would never be called. I, of course, was wrong. (Which I would have realized if I'd given the method_throw_obj a second thought - 'cause if throw events handled the actual "Throwing", that method would throw things twice...)
The lesson today is test before you speak.
But still, if someone was using on_throw events, it might be helpful for the function to know if it was originating from a method (and which location) or from a general mouse throw.
I did some testing, and realized that I was half-wrong. I thought that if an on_throw existed for an arch, it would supercede sys_mouse_throw: in other words, the event function would have to handle all the power settings and stuff and pass all that to dsb_shoot all by itself, and sys_mouse_throw would never be called. I, of course, was wrong. (Which I would have realized if I'd given the method_throw_obj a second thought - 'cause if throw events handled the actual "Throwing", that method would throw things twice...)
The lesson today is test before you speak.
But still, if someone was using on_throw events, it might be helpful for the function to know if it was originating from a method (and which location) or from a general mouse throw.
- Sophia
- Concise and Honest
- Posts: 4240
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Actually, you're half right both ways.
A non-nil (or non-false) return value from on_throw means "I've taken care of everything, don't do anything else." The normal attack method function (or sys_mouse_throw) won't be called. Otherwise, it will still proceed.
So, if you have a magic apple that turns into a ful bomb when you throw it, return false. If it just flat-out explodes when you try to throw it, return true.
A non-nil (or non-false) return value from on_throw means "I've taken care of everything, don't do anything else." The normal attack method function (or sys_mouse_throw) won't be called. Otherwise, it will still proceed.
So, if you have a magic apple that turns into a ful bomb when you throw it, return false. If it just flat-out explodes when you try to throw it, return true.