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; // 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; }
public void Tick(float delta, EquippableTickInfo info) { if (info.secondaryWasOn) { _mode++; if (_mode >= Mode.Last) { _mode = Mode.Deathray; } UpdateDisplayName(); } switch (_mode) { case Mode.Deathray: if (info.primaryOn) { FireDeathRayShot(info); } break; case Mode.Spawn: if (info.primaryWasOn) { if (_aimLaserNode == null) { Console.WriteLine($"Godhand has no aim laser for spawning"); break; } Vector3 pos = _aimLaserNode.GlobalTransform.origin; SpawnMob(pos); } break; case Mode.CycleSpawn: if (info.primaryWasOn) { _mobTypeIndex++; if (_mobTypeIndex >= _mobTypes.Length) { _mobTypeIndex = 0; } UpdateDisplayName(); } break; case Mode.DebugTag: //_aimActorId Transform t = _launchNode.GlobalTransform; Vector3 origin = t.origin; Vector3 dest = origin + (-t.basis.z * 1000); Godot.Collections.Dictionary hitDict = ZqfGodotUtils .CastRay(_launchNode, origin, dest, uint.MaxValue, info.src.ignoreBody); if (hitDict.Keys.Count == 0) { _aimActorId = Game.NullActorId; UpdateDisplayName(); break; } IActor actor = Game.ExtractActor(hitDict["collider"]); if (actor == null) { _aimActorId = Game.NullActorId; UpdateDisplayName(); break; } int newId = actor.actorId; // refresh actor Id if required if (_aimActorId != newId) { _aimActorId = newId; UpdateDisplayName(); } if (info.primaryWasOn) { Main.i.game.SetDebugActorId(_aimActorId); } break; } }