Administration tools: commands and non gameplay server configuration
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
4.1 KiB

/**
* 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.Group(P("debug"));
builder.Summary(P("Spawns new entity on the map."));
builder.ParamText(P("template"),, P("entity"));
builder.Describe(P("Spawns new entity based on the given template at the point"
@ "player is currently looking at."));
builder.SubCommand(P("at"));
builder.ParamText(P("template"),, P("entity"));
builder.ParamNumber(P("x"));
builder.ParamNumber(P("y"));
builder.ParamNumber(P("z"));
builder.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,
CommandPermissions permissions
) {
local HashTable value;
local Vector spawnLocation;
announcer.Setup(none, instigator, othersConsole);
value = arguments.parameters.GetHashTable(P("template"));
if (arguments.subCommandName.IsEmpty()) {
SpawnInInstigatorSight(instigator, value);
} 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, value, spawnLocation);
}
_.memory.Free(value);
}
private final function SpawnAt(
EPlayer instigator,
HashTable value,
Vector spawnLocation
) {
local Text humanReadable, template;
local EPlaceable result;
humanReadable = value.GetText(P("alias"));
template = value.GetText(P("value"));
result = _server.kf.world.Spawn(template, spawnLocation);
if (result != none) {
announcer.AnnounceSpawned(humanReadable);
} else {
announcer.AnnounceSpawningFailed(humanReadable);
}
_.memory.Free2(humanReadable, result);
}
private final function SpawnInInstigatorSight(
EPlayer instigator,
HashTable value
) {
local EPlaceable result;
local Vector spawnLocation;
local TracingIterator iter;
local Text humanReadable, template;
humanReadable = value.GetText(P("alias"));
template = value.GetText(P("value"));
iter = _server.kf.world.TracePlayerSight(instigator);
iter.LeaveOnlyVisible();
if (iter.HasFinished()) {
announcer.AnnounceFailedTrace();
return;
}
spawnLocation = iter.GetHitLocation();
result = _server.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 = _server.kf.world.Spawn(template, spawnLocation);
}
if (result != none) {
announcer.AnnounceSpawned(humanReadable);
} else {
announcer.AnnounceSpawningFailed(humanReadable);
}
_.memory.Free4(result, iter, humanReadable, result);
}
defaultproperties {
preferredName = "spawn"
}