Browse Source

Add `spawn` command

feature_improvement
Anton Tarasenko 2 years ago
parent
commit
b5c3e63cfc
  1. 130
      sources/Commands/ACommandSpawn.uc
  2. 90
      sources/Commands/ACommandSpawn_Announcer.uc
  3. 3
      sources/Futility_Feature.uc

130
sources/Commands/ACommandSpawn.uc

@ -0,0 +1,130 @@
/**
* Command for spawning new entities into the world.
* Copyright 2022 Anton Tarasenko
*------------------------------------------------------------------------------
* This file is part of Acedia.
*
* Acedia is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License, or
* (at your option) any later version.
*
* Acedia is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
*/
class ACommandSpawn extends Command;
// TODO: use spawned name for errors output?
var private ACommandSpawn_Announcer announcer;
protected function Finalizer()
{
_.memory.Free(announcer);
super.Finalizer();
}
protected function BuildData(CommandDataBuilder builder)
{
builder.Name(P("spawn")).Group(P("debug"))
.Summary(P("Spawns new entity on the map."));
builder.ParamText(P("template"))
.Describe(P("Spawns new entity based on the given template at the point"
@ "player is currently looking at."));
builder.SubCommand(P("at"))
.ParamText(P("template"))
.ParamNumber(P("x"))
.ParamNumber(P("y"))
.ParamNumber(P("z"))
.Describe(P("Spawns new entity based on the given template at"
@ "the point, given by the coordinates"));
announcer = ACommandSpawn_Announcer(
_.memory.Allocate(class'ACommandSpawn_Announcer'));
}
protected function Executed(
CallData arguments,
EPlayer instigator)
{
local Text givenTemplate, template;
local Vector spawnLocation;
announcer.Setup(none, instigator, othersConsole);
givenTemplate = arguments.parameters.GetText(P("template"));
if (givenTemplate.StartsWithS("$")) {
template = _.alias.ResolveEntity(givenTemplate, true);
}
else {
template = givenTemplate.Copy();
}
_.memory.Free(givenTemplate);
if (arguments.subCommandName.IsEmpty()) {
SpawnInInstigatorSight(instigator, template);
}
else if (arguments.subCommandName.Compare(P("at"), SCASE_INSENSITIVE))
{
spawnLocation.x = arguments.parameters.GetFloat(P("x"));
spawnLocation.y = arguments.parameters.GetFloat(P("y"));
spawnLocation.z = arguments.parameters.GetFloat(P("z"));
SpawnAt(instigator, template, spawnLocation);
}
_.memory.Free(template);
}
private final function SpawnAt(
EPlayer instigator,
BaseText template,
Vector spawnLocation)
{
local EPlaceable result;
result = _.kf.world.Spawn(template, spawnLocation);
if (result != none) {
announcer.AnnounceSpawned(template);
}
else {
announcer.AnnounceSpawningFailed(template);
}
_.memory.Free(result);
}
private final function SpawnInInstigatorSight(
EPlayer instigator,
BaseText template)
{
local EPlaceable result;
local Vector spawnLocation;
local TracingIterator iter;
iter = _.kf.world.TracePlayerSight(instigator).LeaveOnlyVisible();
if (iter.HasFinished())
{
announcer.AnnounceFailedTrace();
return;
}
spawnLocation = iter.GetHitLocation();
result = _.kf.world.Spawn(template, spawnLocation);
// Shift position back a little and try again;
// this should fix a ton of spawning failures
if (result == none)
{
spawnLocation = spawnLocation +
Normal(iter.GetTracingStart() - spawnLocation) * 100;
result = _.kf.world.Spawn(template, spawnLocation);
}
if (result != none) {
announcer.AnnounceSpawned(template);
}
else {
announcer.AnnounceSpawningFailed(template);
}
_.memory.Free(result);
}
defaultproperties
{
}

90
sources/Commands/ACommandSpawn_Announcer.uc

@ -0,0 +1,90 @@
/**
* Announcer for `ACommandSpawn`.
* Copyright 2022 Anton Tarasenko
*------------------------------------------------------------------------------
* This file is part of Acedia.
*
* Acedia is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License, or
* (at your option) any later version.
*
* Acedia is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
*/
class ACommandSpawn_Announcer extends CommandAnnouncer;
var private AnnouncementVariations spawned, spawningFailed, failedTrace;
protected function Finalizer()
{
FreeVariations(spawned);
FreeVariations(spawningFailed);
FreeVariations(failedTrace);
super.Finalizer();
}
public final function AnnounceSpawned(BaseText template)
{
local int i;
local array<TextTemplate> templates;
if (!spawned.initialized)
{
spawned.initialized = true;
spawned.toSelfReport = _.text.MakeTemplate_S(
"You {$TextPositive spawned} {$TextEmphasis %1}!");
spawned.toSelfPublic = _.text.MakeTemplate_S(
"%%instigator%% {$TextNeutral spawned} {$TextEmphasis %1}!");
}
templates = MakeArray(spawned);
for (i = 0; i < templates.length; i += 1) {
templates[i].Reset().Arg(template);
}
MakeAnnouncement(spawned);
}
public final function AnnounceSpawningFailed(BaseText template)
{
local int i;
local array<TextTemplate> templates;
if (!spawningFailed.initialized)
{
spawningFailed.initialized = true;
spawningFailed.toSelfReport = _.text.MakeTemplate_S(
"{$TextFailure Couldn't spawn} {$TextEmphasis %1}!");
}
templates = MakeArray(spawningFailed);
for (i = 0; i < templates.length; i += 1) {
templates[i].Reset().Arg(template);
}
MakeAnnouncement(spawningFailed);
}
public final function AnnounceFailedTrace()
{
local int i;
local array<TextTemplate> templates;
if (!failedTrace.initialized)
{
failedTrace.initialized = true;
failedTrace.toSelfReport = _.text.MakeTemplate_S(
"{$TextFailure Failed} to trace spawn point");
}
templates = MakeArray(failedTrace);
for (i = 0; i < templates.length; i += 1) {
templates[i].Reset();
}
MakeAnnouncement(failedTrace);
}
defaultproperties
{
}

3
sources/Futility_Feature.uc

@ -1,7 +1,7 @@
/** /**
* This is the Futility feature, whose main purpose is to register commands * This is the Futility feature, whose main purpose is to register commands
* from its package. * from its package.
* Copyright 2021 Anton Tarasenko * Copyright 2021-2022 Anton Tarasenko
*------------------------------------------------------------------------------ *------------------------------------------------------------------------------
* This file is part of Futility. * This file is part of Futility.
* *
@ -79,5 +79,6 @@ defaultproperties
allCommandClasses(4) = class'ACommandInventory' allCommandClasses(4) = class'ACommandInventory'
allCommandClasses(5) = class'ACommandFeature' allCommandClasses(5) = class'ACommandFeature'
allCommandClasses(6) = class'ACommandGod' allCommandClasses(6) = class'ACommandGod'
allCommandClasses(7) = class'ACommandSpawn'
errNoCommandsFeature = (l=LOG_Error,m="`Commands_Feature` is not detected, \"Futility\" will not be able to provide its functionality.") errNoCommandsFeature = (l=LOG_Error,m="`Commands_Feature` is not detected, \"Futility\" will not be able to provide its functionality.")
} }
Loading…
Cancel
Save