private void PerformHits() { Console.WriteLine($"Performing {_hits.Count} melee hits"); TouchData touch = new TouchData(); touch.damage = _damage; touch.teamId = _source.team; touch.touchType = TouchType.Melee; for (int i = 0; i < _hits.Count; ++i) { IActor a = _hits[i]; Vector3 origin = _source.ignoreBody.GlobalTransform.origin; Vector3 dest = a.GetTransformForTarget().origin; Godot.Collections.Dictionary hit = ZqfGodotUtils.CastRay(this, origin, dest, uint.MaxValue, _source.ignoreBody); if (hit.Keys.Count == 0) { continue; } touch.hitPos = (Vector3)hit["position"]; touch.hitNormal = (Vector3)hit["normal"]; Console.WriteLine($"Hitting actor {a.actorId}"); TouchResponseData response = Game.TouchGameObject(touch, hit["collider"]); //a.ActorTouch(touch); } _hits.Clear(); }
private void MoveAsRay(float delta) { Transform t = GlobalTransform; Vector3 origin = t.origin; Vector3 forward = -t.basis.z; Vector3 dest = origin; dest += (forward * _def.launchSpeed) * delta; uint mask = uint.MaxValue; PhysicsDirectSpaceState space = GetWorld().DirectSpaceState; Godot.Collections.Array arr = null; if (_ignoreBody != null) { arr = new Godot.Collections.Array(); arr.Add(_ignoreBody); } Dictionary hitResult = space.IntersectRay(origin, dest, arr, mask); if (hitResult.Keys.Count > 0) { _touch.damage = _def.damage; _touch.teamId = 0; _touch.touchType = TouchType.Bullet; IActorProvider actorProvider = hitResult["collider"] as IActorProvider; if (actorProvider != null) { IActor actor = actorProvider.GetActor(); if (actor != null) { TouchResponseData response = actor.ActorTouch(_touch); Console.WriteLine($"Prj hit actor for {response.damageTaken}"); } else { Console.WriteLine($"Prj hit provider but actor is null!"); } } else { //Node hitObj = (hitResult["collider"] as Node); //Console.WriteLine($"Prj hit non-actor node {hitObj.Name}"); } Vector3 gfxOrigin = (Vector3)hitResult["position"]; GFXQuick gfx = Main.i.factory.SpawnGFX(GameFactory.Path_GFXImpact); gfx.Spawn(gfxOrigin); Die(); return; } t.origin = dest; GlobalTransform = t; }
private void MoveAsRay(float delta) { Transform t = GlobalTransform; // apply move effects if (_def.speedMode == ProjectileDef.SpeedMode.Accel) { _speed += _def.accelPerSecond * delta; _speed = ZqfGodotUtils .Capf(_speed, _def.minSpeed, _def.maxSpeed); } if (_def.guideMode == ProjectileDef.GuideMode.Turn && _targetActorId != Game.NullActorId) { IActor actor = Main.i.game.GetActor(_targetActorId); // TODO lerp rotation toward target Transform turnTarget = actor.GetTransformForTarget(); } Vector3 origin = t.origin; Vector3 forward = -t.basis.z; Vector3 dest = origin; dest += (forward * _speed) * delta; // Set origin back slightly as otherwise rays seem to tunnel // (perhaps due to ray starting inside collider...?) origin -= (forward * 0.25f); uint mask = uint.MaxValue; Dictionary hitResult = ZqfGodotUtils.CastRay(this, origin, dest, mask, _ignoreBody); bool spawnGFX = true; // no hits, just move and leave if (hitResult.Keys.Count <= 0) { t.origin = dest; GlobalTransform = t; return; } _touch.hitPos = (Vector3)hitResult["position"]; _touch.hitNormal = (Vector3)hitResult["normal"]; _touch.damage = _def.damage; _touch.teamId = _team; _touch.touchType = TouchType.Projectile; _touch.damageType = _def.damageType; object obj = hitResult["collider"]; /* * IActor actor = Game.ExtractActor(obj); * //ITouchable actor = Game.ExtractTouchable(obj); * if (actor != null) * { * TouchResponseData response = actor.ActorTouch(_touch); * if (response.responseType != TouchResponseType.None) * { * // leave spawning particles to the victim * spawnGFX = false; * } * } */ TouchResponseData response = Game.TouchGameObject(_touch, obj); if (response.responseType == TouchResponseType.None) { t.origin = dest; GlobalTransform = t; return; } if (response.responseType != TouchResponseType.None) { // leave spawning particles to the victim spawnGFX = false; } if (spawnGFX) { GFXQuick gfx = Main.i.factory.SpawnGFX(impactGFX); gfx.Spawn(_touch.hitPos, _touch.hitNormal); } if (_def.impactDef != null) { RunImpactDef(_touch.hitPos, _def.impactDef); } if (_def.destroyMode == ProjectileDef.DestroyMode.Embed) { _state = State.Embedded; t.origin = _touch.hitPos; _tick = 3; GlobalTransform = t; } else { Die(); } return; }