as stated in the title I want to make a arrow that executes a command on all entities in a certain range of the arrow, the range I would like to be 10x10 from the center of the arrow. but I have not been able to get it working.
execute as #e[type=spectral_arrow,tag=ShotFromLightningBow] at #s run execute as #e[tag=!MageAlly,distance=10..10] run effect give #s wither 5 5 true
This is what I tried last.
Your problem is in the distance tag. distance=a..b means the distance to the entity must be between the numbers a and b (both inclusive). In your command both are 10, meaning the effect only gets applied to entities with a distance of exactly 10 blocks. You proboably want to do distance=..a, which means all entities that are at most a blocks away.
Related
I am trying to find a (SoP)-expression using the embedded K-map. I have a box of size 4x4 which is a permitted use however I am having a hard time understanding how I could implement it.
To me the 4x4 box represents that the output is always 1 independet on any of the variables. Then I'd like to use the 2x4 box to the right and produce:
1 OR (Qc AND !Qd), but this does not produce the correct result.
I can see several alternative ways to produce the correct result. My questions are specifically:
Why can't I use the 4x4 box, or perhaps, how do I represent it correctly?
How do I know when I can represent parts of the output as a 4x4 box?
Perhaps Im missing something more fundamental.
Thx in advance.
The point of placing rectangles in a K-map is to eliminate variables from an expression. When the result of a rectangle is the same for the variable values X and X', then the variable X is not needed and can be removed. You do this by extending an existing rectangle by doubling the size and eliminating exactly one variable, where every other variable stays the same. For the common/normal K-map with four variables this works with every such rectangle because in a way the columns/rows are labelled/positioned. See the following example:
The rectangle has eliminated the variables A and B, one variable at a time when the size of the rectangle has been extended/doubled. This results in the function F(A,B,C,D) = C'D'. But check the following K-map of four variables:
Notice that the columns for the D variable has been changed (resulting in a different function overall). When you try to extend the red rectangle to catch the other two 1 values as well, you are eliminating two variables at the same time (B and D). As you cannot grow the rectangle anymore, you are left with two rectangles, resulting in the function F(A,B,C,D) = BC'D' + B'C'D (which can be simplified to C' * (BD' + B'D)).
The practice in placing rectangles in the K-map isn't just placing the biggest rectangle possible, but to eliminate variables in the right way. To answer your questions, you can always start with the smallest rectangle and extend/double its size to eliminate one variable. See the following example:
The green rectangle grows in these steps:
Start with A'BC'D'E
Eliminate the (only) variable A by growing "down", resulting in BC'D'E
Eliminate the (only) variable D by growing "right", resulting in BC'E.
But now, the rectangle cannot grow/double its size anymore because that would eliminate the variable E, but also somehow eliminate the variable C. You cannot eliminate the variable E, because you have 0 values to the left of the green rectangle and 1 values to the right of the green rectangle (all in the left half of the K-map, where you have the value C'). The only way to increase/grow the rectangle is to get the "don't care" values to eliminate the B variable (not shown here).
The overall function for this K-map would be F(A,B,C,D,E) = C'E + DE' + CD' (from three 2x4 rectangles).
I've followed "Procedural Generation in Godot: Dungeon Generation" by KidsCanCode #https://www.youtube.com/watch?v=o3fwlk1NI-w and find myself unable to debug the current problem.
This specific commit has the code, but I'll try to explain in more detail bellow.
My main scene has a Camera2D node, a generic Node2D calles Rooms and a TileMap, everything is empty.
When the script starts, it runs a
func make_room(_pos, _size):
position = _pos
size = _size
var s = RectangleShape2D.new()
s.custom_solver_bias = 0.5
s.extents = size
$CollisionShape2D.shape = s
A few times and it fills $Rooms using .add_child(r) where r is a instance of the node that has the make_room() function. It will then iterate over $Rooms.get_children() a few times to create a AStar node to link all the rooms:
The magic comes when make_map() is called after afterwards, it fills the map with non-walkable blocks and then it carves the empty spaces, which works fine too:
There is a find_start_room() that is called to find the initial room, it also sets a global variable to the Main script start_room, which is used to write 'Start' on the map using draw_string(font, start_room.position - Vector2(125,0),"start",Color(3,4,8))
When I hit 'esc' it runs this simple code to instance the player:
player = Player.instance()
add_child(player)
player.position = start_room.position + Vector2(start_room.size.x/2, start_room.size.y/2)
play_mode = true
The problem comes when spawning the player. I tried doing some 'blind' fixing, such as adding or subtracting a Vector2(start_room.size.x/2, start_room.size.y/2) to player.position to see if I could make it fall within the room, to no avail.
Turning to the debugger didn't help, as the positions expressed by the variable inspectors don't seem to mean anything.
I tried implementing a simple 'mouse click print location':
print("Mouse Click/Unclick at: ", event.position)
print("Node thing",get_node("/root/Main/TileMap").world_to_map(event.position))
And also a 'start_room' print location:
print(get_node("/root/Main/TileMap").world_to_map(start_room.position))
And a when player moves print location, written directly into the Character script:
print(get_node("/root/Main/TileMap").world_to_map(self.position))
Getting results like the ones bellow:
Mouse Click/Unclick at: (518, 293)
Node thing(16, 9)
(-142, 0)
(-147, -3)
So, the player doesn't spawn on the same position as the start_room and the mouse position information is not the same as anything else.
Why is the player now spawning correctly? How can I debug this situation?
EDIT1: User Theraot mentioned about how the RigidBody2D is doing some weird collisions, and from what I understood, changing their collision behavior should fix the whole thing.
There's a section on the code that -after generating the random rooms- it removes some of the rooms like this:
for room in $Rooms.get_children():
if randf() < cull:
room.queue_free()
else:
room.mode = RigidBody2D.MODE_STATIC
room_positions.append(Vector3(room.position.x, room.position.y, 0))
From what I understand, if the room is randomly selected it will be deleted using queue_free() OR it will be appended to a room_positions for further processing. This means if I shift all the rooms to a different collision layer, the player/character instance would be alone with the TileMap on the same collision layer.
So I just added a simple room.collision_layer = 3 changing this section of the code to
for room in $Rooms.get_children():
if randf() < cull:
room.queue_free()
else:
room.mode = RigidBody2D.MODE_STATIC
room.collision_layer = 3
room_positions.append(Vector3(room.position.x, room.position.y, 0))
It doesn't seem to have changed anything, the player still spawns outside the room.
Do you see the rooms spread outwards?
You didn't write code to move the rooms. Sure, the code gives them a random position. But even if you set their position to Vector2.ZERO they move outwards, avoiding overlaps.
Why? Because these rooms are RigidBody2D, and they do push other physics objects. Such as other rooms or the player character.
That's the problem: These rooms are RigidBody2D, and you put your KinematicBody2D player character on top of one of them. The RigidBody2D pushes it out.
The tutorial you followed is exploiting this behavior of RigidBody2Ds to spread the rooms. However you don't need these RigidBody2D after you are done populating your TileMap.
Instead, you can store the start position in a variable for later placing the player character (you don't need offsets - by the way - the position of the room is the center of the room), and then remove the RigidBody2Ds. If you want to keep the code that writes the text, you would also have to modify it, so it does not fail when the room no longer exists.
Alternatively, you can edit their collision layer and mask so they don't collide with the player character (or anything for that matter, but why would you want these RigidBody2Ds that collide with nothing?).
Addendum post edit: Collision layers and mask don't work as you expect.
First of all, the collision layer and mask are flags. The values of the layers are powers of two (1, 2, 4, 8...). So, when you set it to 3, it is the layer 1 plus the layer 2. So it still collides with a collision mask of 1.
And second, even if you changed the collision layer of the rooms to 2 (so it does not match the collision mask of 1 that the player character has). The player character still has a layer 1 which match the collision mask of the rooms.
See also the proposal Make physics layers and masks logic simple and consistent.
Thus, you would need to change the layer and mask. Both. in such way that they don't collide. For example, you can set layer and mask to 0 (which disable all collisions). The algorithm that populates the TileMap does not use the layer and mask.
This is a bit of a long-shot. I really don't know where to ask this question.
I've been trying out CodeConnection + MakeCode with Minecraft and I haven't been able to figure out if there is correct way to place half-slabs at 0.5 step y axes increments.
I tried using a line between 2 points, but it left gaps between each slab.
If I try moving up 0.5, then it rounds it up to 1, and again leaves gaps.
It appears that all of the builder functions seem operate at a resolution of 1 block. However in-game I can obviously place slabs in 0.5 block increments to make stairs etc.
Blocks only exist at integer coordinates. Half slabs that exist in the top half of their space are still at a full integer coordinate. They just have a BlockState value of bottom=top (or top_slot_bit=true on Bedrock, represented by the integer value 8 as a bitflag, eg: 0b1... where the . bits are the integer representation of what type of slab (wood, stone, quartz...)).
What you're looking for is this widget, under Blocks:
You can set the block and then an integer representation of the desired data value (see the wiki on data values) in the numerical slot. This widget can then be dragged into the (block) portion of any block widget:
You'll probably have to some variable fiddling to get the data value to swap back and forth as you need it to, but that should solve the hurdle you've been facing.
I am building a work-logging app which starts by showing a list of projects that I can select, and then when one is selected you get a collection of other buttons, to log data related to that selected project.
I decided to have a selected_project : Maybe Int in my model (projects are keyed off an integer id), which gets filled with Just 2 if you select project 2, for example.
The buttons that appear when a project is selected send messages like AddMinutes 10 (i.e. log 10 minutes of work to the selected project).
Obviously the update function will receive one of these types of messages only if a project has been selected but I still have to keep checking that selected_project is a Just p.
Is there any way to avoid this?
One idea I had was to have the buttons send a message which contains the project id, such as AddMinutes 2 10 (i.e. log 10 minutes of work to project 2). To some extent this works, but I now get a duplication -- the Just 2 in the model.selected_project and the AddMinutes 2 ... message that the button emits.
Update
As Simon notes, the repeated check that model.selected_project is a Just p has its upside: the model stays relatively more decoupled from the UI. For example, there might be other UI ways to update the projects and you might not need to have first selected a project.
To avoid having to check the Maybe each time you need a function which puts you into a context wherein the value "wrapped" by the Maybe is available. That function is Maybe.map.
In your case, to handle the AddMinutes Int message you can simply call: Maybe.map (functionWhichAddsMinutes minutes) model.selected_project.
Clearly, there's a little bit more to it since you have to produce a model, but the point is you can use Maybe.map to perform an operation if the value is available in the Maybe. And to handle the Maybe.Nothing case, you can use Maybe.withDefault.
At the end of the day is this any better than using a case expression? Maybe, maybe not (pun intended).
Personally, I have used the technique of providing the ID along with the message and I was satisfied with the result.
I have a stream network in ArcGIS - i.e. a series of polylines, and along each stream part I have added points. For each of the points I have extracted the height and flow from underlying rasters and I have also extracted data from the intersecting polylines including minimum, mean and max height of the polyline, the HydroID and the nextdownID. The points also have their own ID but I have noticed these are not in order.
What I would like is to add stepID to each of the points, where at the beginning of each river reach (each polyline) the first point is step 1 and this increments upwards until the end of the reach. So if there were 10 points along a polyline, the first point would have a stepID value of 1 and the last point would have a stepID value of 10.
This sounds quite easy but not sure how to do it. Any help would be great.
You can construct points along the line at specific intervals using the construct points tool/function.
Click the Edit tool Edit Tool on the Editor toolbar.
Click the line feature along which you want to generate points.
Click the Editor menu and click Construct Points.
http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//001t00000029000000.htm
To automate the numbering, you might look into flipping the lines so all the tails point in one direction - up or downstream. Double click on a line, then right click to see the "flip" command. If you use the points set up from the method above, it might order from tail to head.
Another option is to create your own field for the stepID. Create a attribute join to the stream segment, and give each joined record a unique number. Go through your records selecting each group of ten, then sort by FID (check these are in order) then calculate value for stepID = FID - x
where x = the lowest FID in the stream segment's stepID. This thought might help you figure out how to coax the numbers out correctly.
I had this problem before and solved it this way. It is NOT a pretty solution. Would love to hear if there is a more elegant way of doing this
.
For clarity I'll call the pointdataset you mention the 'inputpoints'.
Step 1: getting the points in the right order
If your inputpoints are sometimes far away from the lines, first project them to your lines.
Give your lines a unique line number and join it to the closest inputpoint features
Generate points along lines: use your polylines and genarate a lot of points on them. I'll call this dataset the helperpoints. Fill in a distance that is smaller then the smallest distance between two of your inputpoints.
Make sure your polylines have the right 'direction'. You can check it by using a symbology with arrows, and if needed correct it with the flip editing tool.
Add an IDfield to your helperpoints, type float or double, and create sequential idnumbers in it (https://support.esri.com/en/technical-article/000011137).
Spatial join: the inputpoints are your target, the helperpoints the join features. Keep all the target features. You only need to join the IDfield from the helperpoints. Right click the IDfield in the field map, and make the merge rule 'Mean'. Set the Match option to 'within a distance', and make the search radius 1.5 x the distance that you used in the generate points along line step.
Use the sort tool and sort your spatial join output on the IDfield you just added, then on the lineID you you added on step one. If you have the advanced licence you can do it at once.
Step 2: Generating the StepID
Add a new field to your sort output, and call it StepID
Use the field calculator to fill it. I used this code to make the numbering restart every time there is a new line.
rec=0
oldid = -1
def autoIncrement(lineid):
global rec
global oldid
pStart = 1
pInterval = 1
if rec == 0 or lineid!= oldid :
rec = pStart
else:
rec += pInterval
oldid = lineid
return int(rec)
Expression: autoIncrement( !lineID! )
Expression type: Python
It might still mess up if you have lines very close to each other, or have weird curls on the end. But for the rest this should work!