Why does this function not get called but after its his turn again it gets called this time - func

I am making a turn based game, currently I am trying to add a critical hit system it shows that it is doing critical hit damage but doesnt play the critical hit function,the thing that doesnt make sense too me is, it gets called when its his turn again so something in the first turn is making the function not be called but gets called at the second time, It seems to be who ever attacks first doesnt get the dialogue function to be called, but plays fine after the first turn.
func check_if_player(attacker, target):
if attacker == player_node:
print(attacker.move_slot[move_index].name)
dialogue_text.text = (attacker.name + " is attacking")
dialogue_ani.play("TextScroll")
target.take_damage(attacker.move_slot[move_index],attacker)
yield(get_tree().create_timer(2), "timeout")
_update_view()
if attacker.crit:
attacker.crit = false # Where I turn it off
print(attacker.crit)
yield(critical_hit(attacker),"completed")
else:
yield(attack(attacker, target), "completed")
func attack(attacker, target):
var random_move = randi() % 3 + 1
print(attacker.move_slot[move_index].name)
dialogue_text.text = (attacker.name + " is attacking")
dialogue_ani.play("TextScroll")
target.take_damage(attacker.move_slot[random_move],attacker) # Calls the function to take damage
yield(get_tree().create_timer(2), "timeout") #Wait for 2 seconds
_update_view()
if attacker.crit:
attacker.crit = false # Where I turn it off
print(attacker.crit)
yield(critical_hit(attacker),"completed")
these two functions is how I check if the player is attacking I need to do this because I want the player to use a selected move, if isnt player then play enemy attack
and this is my monster script, where I detect if a critical hit happens, I should say this the monster script is a resource and is separate from the other script, where player, enemy and critical hit function is all in one script.
func take_damage(move,attacker):
randomize()
var critical = 1
#var critical_chance = randi() % 100 + 1
var critical_chance = 5
if critical_chance <= 99.25:
crit = true
critical = 2
var type : float = Get_effectiveness(move.type,type_1) * Get_effectiveness(move.type,type_2)
var modifier : float = rand_range(0.85,1.0) * type * critical
var a : float = (2.0 * attacker.level / 5.0 + 2.0)
var b : float = (a * attacker.attack * move.power / defence) / 50.0
var c : float = (b + 2.0) * modifier
var damage = int(c)
current_health -= damage
print(str(attacker.name) + " = " + str(damage))
#print(a)
#print(b)
Currently I have it pretty much be true every time the player or enemy attacks so it should call/ show the critical hit function, I turn the crit bool to false in the first few functions so it should only happen once
This is the function that adds text to the screen it also prints it to tell me its working but it doesnt print it, if its the first attacking monster, am I making a noobie mistake here?
func critical_hit(attacker):
dialogue_text.text = (attacker.name + " has landed a critical hit!")
dialogue_ani.play("TextScroll")
print(attacker.name + " has landed a critical hit!")
yield(get_tree().create_timer(3), "timeout")

Related

Model Shakes when moved long distance - Godot

I am making a space game in Godot and whenever my ship is a big distance away from (0,0,0) every time I move the camera or the ship, it shakes violently. Here is my code for moving the ship:
extends KinematicBody
export var default_speed = 500000
export var max_speed = 5000
export var acceleration = 100
export var pitch_speed = 1.5
export var roll_speed = 1.9
export var yaw_speed = 1.25
export var input_response = 8.0
var velocity = Vector3.ZERO
var forward_speed = 0
var vert_speed = 0
var pitch_input = 0
var roll_input = 0
var yaw_input = 0
var alt_input = 0
var system = "System1"
func _ready():
look_at(get_parent().get_node("Star").translation, Vector3.UP)
func get_input(delta):
if Input.is_action_pressed("boost"):
max_speed = 299792458
acceleration = 100
else:
max_speed = default_speed
acceleration = 100
if Input.is_action_pressed("throttle_up"):
forward_speed = lerp(forward_speed, max_speed, acceleration * delta)
if Input.is_action_pressed("throttle_down"):
forward_speed = lerp(forward_speed, 0, acceleration * delta)
pitch_input = lerp(pitch_input, Input.get_action_strength("pitch_up") - Input.get_action_strength("pitch_down"), input_response * delta)
roll_input = lerp(roll_input, Input.get_action_strength("roll_left") - Input.get_action_strength("roll_right"), input_response * delta)
yaw_input = lerp(yaw_input, Input.get_action_strength("yaw_left") - Input.get_action_strength("yaw_right"), input_response * delta)
func _physics_process(delta):
get_input(delta)
transform.basis = transform.basis.rotated(transform.basis.z, roll_input * roll_speed * delta)
transform.basis = transform.basis.rotated(transform.basis.x, pitch_input * pitch_speed * delta)
transform.basis = transform.basis.rotated(transform.basis.y, yaw_input * yaw_speed * delta)
transform.basis = transform.basis.orthonormalized()
velocity = -transform.basis.z * forward_speed * delta
move_and_collide(velocity * delta)
func _on_System1_area_entered(area):
print(area, area.name)
system = "E"
func _on_System2_area_entered(area):
print(area, area.name)
system = "System1"
Is there any way to prevent this from happening?
First of all, I want to point out, that this is not a problem unique to Godot. Although other engines have automatic fixes for it.
This happens because the precision of floating point numbers decreases as it goes away form the origin. In other words, the gap between one floating number and the next becomes wider.
The issue is covered in more detail over the game development sister site:
Why loss of floating point precision makes rendered objects vibrate?
Why does the resolution of floating point numbers decrease further from an origin?
What's the largest "relative" level I can make using float?
Why would a bigger game move the gameworld around the Player instead of just moving a player within a gameworld?
Moving player inside of moving spaceship?
Spatial Jitter problem in large unity project
Godot uses single precision. Support for double precision has been added in Godot 4, but that just reduces the problem, it does not eliminate it.
The general solution is to warp everything, in such way that the player is near the origin again. So, let us do that.
We will need a reference to the node we want to keep near the origin. I'm going to assume which node it is does not change during game play.
export var target_node_path:NodePath
onready var _target_node:Spatial = get_node(target_node_path)
And we will need a reference to the world we need to move. I'm also assuming it does not change. Furthermore, I'm also assuming the node we want to keep near the origin is a child of it, directly or indirectly.
export var world_node_path:NodePath
onready var _world_node:Node = get_node(target_node_path)
And we need a maximum distance at which we perform the shift:
export var max_distance_from_origin:float = 10000.0
We will not move the world itself, but its children.
func _process() -> void:
var target_origin := _target_node.global_transform.origin
if target_origin.length() < max_distance_from_origin:
return
for child in _world_node.get_children():
var spatial := child as Spatial
if spatial != null:
spatial.global_translate(-target_origin)
Now, something I have not seen discussed is what happens with physics objects. The concern is that The physics server might be trying to move them in the old position (in practice this is only a problem with RigidBody), and it will overwrite what we did.
So, if that is a problem… We can handle physic objects with a teleport. For example:
func _process() -> void:
var target_origin := _target_node.global_transform.origin
if target_origin.length() < max_distance_from_origin:
return
for child in _world_node.get_children():
var spatial := child as Spatial
if spatial != null:
var body_transform := physics_body.global_transform
var new_transform := Transform(
body_transform.basis,
body_transform.origin - target_origin
)
spatial.global_transform = new_transform
var physics_body := spatial as PhysicsBody # Check for RigidBody instead?
if physics_body != null:
PhysicsServer.body_set_state(
physics_body.get_rid(),
PhysicsServer.BODY_STATE_TRANSFORM,
new_transform
)
But be aware that the above code does not consider any physics objects deeper in the scene tree.

Godot Inversing selected rectangle area made up of two Vector2 objects

This seems like a really simple question but I've been at this for a couple of hours and need an outsiders perspective.
I'm migrating a start of a game to Godot from Unity.
I'm selecting an area of tiles (startDragPosition, endDragPosition, both Vector2 objects) from a TileMap and setting them to a certain tile. Currently the dragging only works if the direction is top->bottom and left->right, so if the ending x and y are larger than the starting x and y
In Unity(C#) I had a few simple lines to flip the rectangle values if it was dragged in reverse.
if (end_x < start_x) {
int tmp = end_x;
end_x = start_x;
start_x = tmp;
}
if (end_y < start_y) {
int tmp = end_y;
end_y = start_y;
start_y = tmp;
}
However in when I try a similar approach in Godot it is not working for some reason. I'm thinking that I'm messing up somewhere earlier and any help would be appreciated. If there is an easier way of doing this please tell me I'm fairly new to Godot itself.
Here is the function responsible for dragging in my Godot script(GD)
func Drag():
if(Input.is_action_just_pressed("click")):
startDragPosition=get_global_mouse_position()
if(Input.is_action_pressed("click")):
endDragPosition=get_global_mouse_position()
print("01 START: "+String(stepify(startDragPosition.x-8,16)/16)+"_"+String(stepify(startDragPosition.y-8,16)/16))
print("01 END: "+String(stepify(endDragPosition.x-8,16)/16)+"_"+String(stepify(endDragPosition.y-8,16)/16))
if(endDragPosition.x<startDragPosition.x):
var temp = endDragPosition.x
endDragPosition.x=startDragPosition.x
startDragPosition.x=temp
if(endDragPosition.y<startDragPosition.y):
var temp = endDragPosition.y
endDragPosition.y=startDragPosition.y
startDragPosition.y=temp
for x in range(startDragPosition.x,endDragPosition.x):
for y in range(startDragPosition.y,endDragPosition.y):
get_node("../DragPreview").set_cell((stepify(x-8,16))/16,(stepify(y-8,16))/16,0)
#get_node("../DragPreview").update_bitmask_area(Vector2((stepify(x-8,16))/16,(stepify(y-8,16))/16))
if(Input.is_action_just_released("click")):
print("START: "+String(stepify(startDragPosition.x-8,16)/16)+"_"+String(stepify(startDragPosition.y-8,16)/16))
print("END: "+String(stepify(endDragPosition.x-8,16)/16)+"_"+String(stepify(endDragPosition.y-8,16)/16))
startDragPosition=null
endDragPosition=null
When you drag, you always write to endDragPosition.
When you drag to the left or drag up, and you update endDragPosition, it will have smaller coordinates than it had before. Because of that you swap the coordinates with startDragPosition… And then you keep dragging left or up, and that updates endDragPosition again. The original startDragPosition is lost.
Either you work with a copy when you are deciding the start and end:
var start = startDragPosition
var end = endDragPosition
if(end.x<start.x):
var temp = end.x
end.x=start.x
start.x=temp
if(end.y<start.y):
var temp = end.y
end.y=start.y
start.y=temp
for x in range(start.x,end.x):
for y in range(start.y,end.y):
# whatever
pass
Or you forget this swapping shenanigans, and give the loops a step:
var start = startDragPosition
var end = endDragPosition
for x in range(start.x,end.x,sign(end.x-start.x)):
for y in range(start.y,end.y,sign(end.y-start.y)):
# whatever
pass

(Bukkit) (Java) Is there a way to spawn random mobs within a range, for example 32 blocks from the player with a little delay?

I want to make a way to summon mobs at a rando location within a range (32 blocks from the player location) every 5 seconds for example.
And if its possible, will it cause too much lagg?
And will it be always active?
Yes, you can get their Location get their X and Z and increase by a random amount with a random, then spawn the mob. Make this in a new thread or in a bukkit runnable since otherwise yes it may cause lag (not sure about that part)
example code:
new Thread(() -> {
int newX = p.getLocation().getX() + new Random().nextInt(32)+1;
int newZ = p.getLocation().getZ() + new Random().nextInt(32)+1;
int newY = /* find out the y value of the area */
Location spawnLoc = new Location(Bukkit.getWorld("world_name"), newX, newY, newZ);
spawnMob(spawnLoc);
}).start();

velocity of a joint between two frames using kinect sdk

I'm stack for along time in this problem and i will really appreciate if any one could help me in that.
I asked many times in many forums, i've searched alot but no answer that really helped me.
i'm developping an application where i have to calculate the velocity of a joint of skeleton body using vs c# 2012 and kinect sdk 1.7
i have first to be sure of the logic of things before asking this question so,
if I understood correctly, the delta_time i'm looking for to calculate velocity, is not the duration of one frame (1/30s) but it must be calculated from two instants:
1- the instant when detecting and saving the "joint point" in the first frame
2- the instant when detecting and saving the same "joint point" in the next frame
if it's not true, thank you for clarifying things.
starting from this hypothesis, i wrote a code to :
detectiong a person
tracking the spine joint ==> if it's is tracked then saving its coordinates into a list (I reduced the work for the moment on the Y axis to simplify)
pick up the time when saving the coordinates
increment the framecounter (initially equal to zero)
if the frame counter is > 1 calculate velocity ( x2 - x1)/(T2 - T1) and save it
here is a piece of the code:
System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
double msNow;
double msPast;
double diff;
TimeSpan currentTime;
TimeSpan lastTime = new TimeSpan(0);
List<double> Sylist = new List<double>();
private int framecounter = 0;
private void KinectSensorOnAllFramesReady(object sender, AllFramesReadyEventArgs allFramesReadyEventArgs)
{
Skeleton first = GetFirstSkeleton(allFramesReadyEventArgs);
if (first == null) // if there is no skeleton
{
txtP.Text = "No person detected"; // (Idle mode)
return;
}
else
{
txtP.Text = "A person is detected";
skeletonDetected = true;
/// look if the person is totally detected
find_coordinates(first);
/*******************************
* time computing *
/*******************************/
currentTime = stopWatch.Elapsed;
msNow = currentTime.Seconds * 1000 + currentTime.Milliseconds;
if (lastTime.Ticks != 0)
{
msPast = lastTime.Seconds * 1000 + lastTime.Milliseconds;
diff = msNow - msPast;
}
lastTime = currentTime;
}
//framecounter++;
}
void find_coordinates(Skeleton first)
{
//*modification 07052014 *****/
Joint Spine = first.Joints[JointType.Spine];
if (Spine.TrackingState == JointTrackingState.Tracked)
{
double Sy = Spine.Position.Y;
/*******************************
* time starting *
/*******************************/
stopWatch.Start();
Sylist.Add(Sy);
framecounter++;
}
else
return;
if (framecounter > 1)
{
double delta_Distance = Sylist[Sylist.Count] - Sylist[Sylist.Count - 1];
}
}
to be honnest, i dont really know how ti use timespan and stopwatch in this context ( i mean when there are frames to process many times/s)
i will be thankfull for any help !
First:
The SkeletonFrame has a property called Timespamp that you can use. It's better to use that one than to create your own timesystem because the timestamp is directly generated by the Kinect.
Second:
Keep track of the previous Timestamp and location.
Then it's just a matter of calculation.
(CurrentLocation - PreviousLocation) = Distance difference
(CurrentTimestamp - PreviousTimestamp) = Time taken to travel the distance.
For example you would get 0.1 meter per 33 miliseconds.
So you can get the meters per seconds like this = (1 second / time taken to travel) * distance difference. In the example this is = (1000/33)*0.1 = 3.03 meter per second.

Accelerometer with BounceEase

I have a Rectangle on my Windows Phone page. When the user tilts their phone, the position of the Rectangle is changed (I use a TranslateTransform) based on the tilt. It works fine.
Like this:
void CurrentValueChanged(object sender,
SensorReadingEventArgs<AccelerometerReading> e)
{
// respond to the accelerometer on the UI thread
Dispatcher.BeginInvoke(new Action(() =>
{
// left, right
var _LeftDelta = e.SensorReading.Acceleration.X * 5d;
var _NewLeft = m_Transform.X + _LeftDelta;
var _PanelWidth = ContentPanel.RenderSize.Width;
var _RectangleWidth = m_Rectangle.RenderSize.Width;
if (_NewLeft > 0 && _NewLeft < _PanelWidth - _RectangleWidth)
m_Transform.X = _NewLeft;
// up, down
var _RightDelta = e.SensorReading.Acceleration.Y * -5d;
var _NewTop = m_Transform.Y + _RightDelta;
var _PanelHeight = ContentPanel.RenderSize.Height;
var _RectangleHeight = m_Rectangle.RenderSize.Height;
if (_NewTop > 0 && _NewTop < _PanelHeight - _RectangleHeight)
m_Transform.Y = _NewTop;
}));
}
What I would like to do, though, is add a bounce when the user hits the side of the page.
Anyone know how?
Your current code does not have acceleration separated from velocity.
the velocity should be updated based on the acceleration, rather than updating locations based on the acceleration.
http://en.wikipedia.org/wiki/Acceleration
Your value 5d takes the place of the mass. it tells you how much is happening for a given force.
You need to keep variables for location
x,y
and velocity
v_x , v_y
then update the locations with
x <- x+ v_x* step_size
y <- y+ v_y* step_size
and update the velocity:
v_x <- v_x + acceletation_x* 5d * step_size
v_y <- v_y + acceletation_y* 5d * step_size
Now, a bounce is trivial. When you reach an upper or lower edge, just flip the sign of the velocity: v_y -> -v_y, and for hitting a side, v_x -> -v_x.
You can make the bounce-back slower than the original velocity by multiplying with a constant when bouncing, for example v_x -> -v_x*0.7
will make the bounce velocity 70% of the initial speed.
You may also require some friction or things will just bounce around forever. Either you learn and implement some real model for that or just use some dummy way to slightly reduce the velocity in each step. The simplest thing that could give something like this is, in each step:
v_x <- v_x * 0.95
v_y <- v_y * 0.95