New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds support for weapons with reach #24395
Conversation
This bypasses obstacles. You need a bit of tuning, mayhap. |
Any recommendations? Don't know how to find dense objects in a path |
Hey somebody's actually coding it!!! ❤ xhuis the god |
Oh this will need support for recognizing the distance hit from so we can have different effects for hits at different ranges |
code/_onclick/click.dm
Outdated
@@ -129,7 +129,7 @@ | |||
|
|||
// Allows you to click on a box's contents, if that box is on the ground, but no deeper than that | |||
if(isturf(A) || isturf(A.loc) || (A.loc && isturf(A.loc.loc))) | |||
if(A.Adjacent(src)) // see adjacent.dm | |||
if(A.Adjacent(src) || W.reach >= get_dist(src, A)) // see adjacent.dm |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if someone wants to make a weapon that only works when standing on the same tile?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not supported unfortunately unless I remove the adjacent check. That's not something I'd do lightly, either!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
else if(!A.Adjacent(src)) && w.reach blah blah can do the trick, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose it could.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A weapon that only works on the same tile already works.
Look at the logic, it's Adjacent OR having a reach more or equal to the distance between you and the target.
if you're on top of eachother, there's no distance, so a reach of 0 would be "same tile only"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And that it would succeed regardless and make reach 0 weapons irrelevant.
Sorry for double post, goddamn phone
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would, but this if is an OR (||
)
var/A = FALSE
var/B = TRUE
if (A || B)
world << "wew"
this, not surprisingly, produces "wew"
Are you tired? drunk? high? I don't see how at this point in time you don't know how an OR works, if I have time at some point you'll have to throw some questions my way because these past few PRs have shown you seem really far behind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I do see however that adjacency would always win the 0 case, if that's what you were trying to say. (The if will always succeed on a same-tile 0 range weapon)
You could snowflake a reach of 1 to be the only case that runs Adjacent()
, if you -really- want 0 reach weapons.
if(W.reach == 1 && A.Adjacent(src))
...
else if(W.reach >= get_dist(src, A))
if(do_some_checks_like_dense_lines_and_stuff())
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I woke up thirty minutes ago, so I guess I'm just tired. Here's how I'm reading it:
Adjacent is true if they're nearby.
Reach is true if they're within a certain range
Say we have the prank gun, which works on only your tile. And you have a mob on your tile that you want to prank.
Both checks pass. Mob gets pranked. YouTube ad revenue goes through the roof.
Now the mob moves one tile above you.
The reach check fails, so we check Adjacent. That one succeeds, because the mob is indeed adjacent.
Thus, the hit succeeds, because it uses either check and not both checks.
Analogies aside, it's super easy to change this, and I likely will later today to support these kind of weapons.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, didn't see your comment. thanks mobile git!
@PKPenguin321 I did this before, with full support for larger attack animation too (because otherwise you have a weapon that reaches 3 tiles but the animation only goes one turf), I didn't PR it because it just generally doesn't feel right. and for that, I guess I'm 👎 on this |
@Xhuis why not have it just hit obstacles in its path? Then we could have something going where you could accidentally recoil yourself if you miss. Any weapon can accidentally bash pipes in maint etc. If not a mob, add recoil (unless there is none) in not very technical terms. |
It certainly can, but I'm still not sure how to get a list of turfs between here and there to check for those obstacles at. I'll have to experiment around later. |
@Xhuis alternatively, some kind of projectile. |
That solves most of my problems. Thanks! I still don't know if this is worth it, though, because of how much slower it's going to make every attack. |
@Xhuis simple, only run that code IF it's the reach that caused the attack, if it was adjacency that caused it, there's no real line to check anyway. |
At this point, I have a dilemma. Either I can cut out the adjacent check entirely and replace it with the reach check and an incapacitated check to stop silly attacks, or I can put in reach checks for special cases. Which one would be better? |
Well, ideally it'd all be one proc that did the "is this attack valid?", so you'd need a proc that uses the |
Hm. So, like, a new proc called 'CheckReach' or something? That could work, especially if I just include that adjacency check in it for weapons of range 1 or higher. I'll have to do that when I get home, though, because I'm not a computer whiz and I won't write code from my phone on the GitHub editor. |
@Xhuis yes, exactly,
Not tested, but that should be p.solid, it's basically: |
Sounds good to me. Any way to check if a dense object actually blocks an attack, I.e. a table won't but a window can? |
@Xhuis |
Well, that solves a lot. Adjacent it is! |
@Xhuis you mean |
you know that that's what I meant >:( |
I dont think there is any good way to communicate reach weapons visually Or to even balance them for that matter |
They would probably need large inhands (which I think we support, remie added it I think?) and to draw a beam from attacker to victim. They could definitely be balanced by making different hit effects depending on how far away you hit a target from. Check the thread on the forums |
Just a small update so you know that I haven't abandoned this and close-happy maintainers don't shut it down for being stale. I haven't worked much in this, as I'm still not sure if the niche cases that this will apply to is worth checking every attack for. I also still don't know how to check if something should block an attack. Density and opacity, the two variables I could use, both don't make sense, and I don't know if adding an obstruction variable to every atom would be wise. |
Can anyone think of some cases where this framework might actually be used? Spears are all that I can think of, making me apprehensive about even coding this further. |
long dongs that reach across zlevels when |
Xhuis, go check the forum thread again GIVE librarian whip |
Doing some more work on this today. I can't go with @RemieRichards' proc as-is, because it doesn't account for dense objects that might also logically allow an attack to go past them (such as a rack or a table). To resolve this, I'm adding a new var to /atom, If you know a better way for this, I'd be happy to take it. |
honestly just make reach weapons.... basically guns, except with instant projectiles and a longer attack cooldown |
That's... an odd way of doing it, but not a bad one either. Projectiles already check this kind of thing, too, so I suppose I could refer to their code for a more efficient way of doing this. |
The argument I'm currently having with Remie reminded me of this, so I'll continue on it once I get home. |
All right, done! I added proper checking through dense objects. The method I ended up using was what @ChangelingRain recommended; I used an invisible dummy object that moved from turf to turf, checking if it could pass by. The attacks pass over the same things that projectiles do. |
Did you ever do this
I cant tell if your code does that |
No, but it's very easy to implement with a quick |
This should be ready. |
code/_onclick/click.dm
Outdated
return 1 | ||
if(!dummy.Move(T)) //we're blocked! | ||
return | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aaaaaaaa training return
code/_onclick/click.dm
Outdated
if(2 to INFINITY) | ||
var/obj/dummy = new(get_turf(here)) //We'll try to move this every tick, failing if we can't | ||
dummy.pass_flags |= PASSTABLE | ||
QDEL_IN(dummy, 10) //1-second grace period for calculation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just qdel it after the loop, no need to keep it around
yes |
As requested by like three people on the forums. Want a whip that can smack people from long-distance? Now you can. This PR doesn't change the reach of any weapons but just adds support, so we can hopefully make combat more interesting.