2017-03-25 12:41:09 +00:00
|
|
|
/**
|
2017-03-30 11:59:10 +00:00
|
|
|
Relaunch Rule
|
|
|
|
This rule enables and handles relaunches.
|
|
|
|
@author Maikel, Sven2, Fulgen
|
2017-03-25 12:41:09 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
// Determines whether the inventory of the crew member is transfered upon respawn.
|
|
|
|
local inventory_transfer = false;
|
|
|
|
|
|
|
|
// Determines whether a crew member needs to be bought.
|
2017-03-30 11:59:10 +00:00
|
|
|
local free_crew = true;
|
2017-03-25 12:41:09 +00:00
|
|
|
|
|
|
|
//Determines whether the clonk will be respawned at the base
|
|
|
|
local respawn_at_base = false;
|
2017-03-30 11:59:10 +00:00
|
|
|
//Determines whether only the last clonk gets respawned
|
2017-04-13 16:58:10 +00:00
|
|
|
local respawn_last_clonk = false;
|
2017-03-25 12:41:09 +00:00
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
local default_relaunch_count = nil;
|
|
|
|
local relaunches = [];
|
2017-03-25 12:41:09 +00:00
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
local clonk_type = Clonk;
|
2017-03-25 12:41:09 +00:00
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
local disable_last_weapon = false;
|
|
|
|
local last_used_player_weapons = [];
|
|
|
|
local relaunch_time = 36 * 10;
|
|
|
|
local hold = false;
|
|
|
|
local restart_player = false;
|
2017-03-30 11:59:10 +00:00
|
|
|
|
|
|
|
public func Activate(int plr)
|
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
if(!restart_player) return MessageWindow(this.Description, plr);
|
2017-03-30 11:59:10 +00:00
|
|
|
// Notify scenario.
|
2017-04-13 07:53:24 +00:00
|
|
|
if (GameCall("OnPlayerRestart", plr))
|
2017-03-30 11:59:10 +00:00
|
|
|
return;
|
|
|
|
// Remove the player's clonk, including contents.
|
|
|
|
var clonk = GetCrew(plr);
|
|
|
|
if (clonk && clonk->GetCrewEnabled())
|
|
|
|
{
|
|
|
|
clonk->Kill(clonk, true);
|
|
|
|
clonk->RemoveObject();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected func Initialize()
|
|
|
|
{
|
|
|
|
ScheduleCall(this, this.CheckDescription, 1, 1);
|
2017-04-13 16:58:10 +00:00
|
|
|
if(GetScenarioVal("Mode", "Game") == "Melee") default_relaunch_count = 5;
|
2017-03-30 11:59:10 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private func CheckDescription()
|
|
|
|
{
|
|
|
|
// If neutral flagpoles exist, update name and description.
|
|
|
|
if(respawn_at_base)
|
|
|
|
{
|
|
|
|
if(ObjectCount(Find_ID(Flagpole), Find_Func("IsNeutral")))
|
|
|
|
{
|
|
|
|
SetName("$Name2$");
|
|
|
|
this.Description = "$Description2$";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetName("$Name3$");
|
|
|
|
this.Description = "$Description3$";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetName("$Name$");
|
|
|
|
this.Description = "$Description$";
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2017-03-25 12:41:09 +00:00
|
|
|
|
|
|
|
public func SetInventoryTransfer(bool transfer)
|
|
|
|
{
|
2017-03-30 11:59:10 +00:00
|
|
|
inventory_transfer = transfer;
|
|
|
|
return true;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public func GetInventoryTransfer()
|
|
|
|
{
|
2017-03-30 11:59:10 +00:00
|
|
|
return inventory_transfer;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public func SetFreeCrew(bool free)
|
|
|
|
{
|
2017-03-30 11:59:10 +00:00
|
|
|
free_crew = free;
|
|
|
|
return true;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public func GetFreeCrew()
|
|
|
|
{
|
2017-03-30 11:59:10 +00:00
|
|
|
return free_crew;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
public func SetRespawnDelay(int delay)
|
2017-03-25 12:41:09 +00:00
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
relaunch_time = delay * 36;
|
2017-03-30 11:59:10 +00:00
|
|
|
return this;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public func GetRespawnDelay()
|
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
return relaunch_time / 36;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
public func SetHolding(bool b)
|
2017-03-25 12:41:09 +00:00
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
hold = b;
|
2017-03-30 11:59:10 +00:00
|
|
|
return this;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public func GetHolding()
|
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
return hold;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
public func SetLastWeaponUse(bool use)
|
2017-03-25 12:41:09 +00:00
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
this.disable_last_weapon = !use;
|
2017-03-30 11:59:10 +00:00
|
|
|
return this;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public func GetLastWeaponUse()
|
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
return disable_last_weapon;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
public func SetBaseRespawn(bool set)
|
2017-03-25 12:41:09 +00:00
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
respawn_at_base = set;
|
2017-03-30 11:59:10 +00:00
|
|
|
return this;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public func GetBaseRespawn()
|
|
|
|
{
|
2017-03-30 11:59:10 +00:00
|
|
|
return respawn_at_base;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
public func SetDefaultRelaunches(int r)
|
2017-03-25 12:41:09 +00:00
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
default_relaunch_count = r;
|
2017-03-30 11:59:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public func SetLastClonkRespawn(bool b)
|
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
respawn_last_clonk = b;
|
2017-03-30 11:59:10 +00:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public func EnablePlayerRestart()
|
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
restart_player = true;
|
2017-03-30 11:59:10 +00:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public func DisablePlayerRestart()
|
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
restart_player = false;
|
2017-03-30 11:59:10 +00:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public func GetLastClonkRespawn()
|
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
return respawn_last_clonk;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
public func InitializePlayer(int plr)
|
2017-03-25 12:41:09 +00:00
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
_inherited(plr, ...);
|
2017-03-30 11:59:10 +00:00
|
|
|
// Scenario script callback.
|
2017-04-13 16:58:10 +00:00
|
|
|
relaunches[plr] = default_relaunch_count;
|
|
|
|
GameCallEx("OnPlayerRelaunch", plr, false);
|
|
|
|
return DoRelaunch(plr, nil, nil, true);
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*public func OnClonkDeath(int plr, object pClonk, int iKiller)
|
|
|
|
{
|
2017-03-30 11:59:10 +00:00
|
|
|
return RelaunchPlayer(plr, iKiller, pClonk);
|
2017-03-25 12:41:09 +00:00
|
|
|
}*/
|
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
public func RelaunchPlayer(int plr, int killer, object clonk)
|
2017-03-25 12:41:09 +00:00
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
if(plr == nil || plr == NO_OWNER) return;
|
2017-03-30 11:59:10 +00:00
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
if(default_relaunch_count != nil)
|
2017-03-30 11:59:10 +00:00
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
relaunches[plr]--;
|
|
|
|
if(relaunches[plr] < 0)
|
2017-03-30 11:59:10 +00:00
|
|
|
{
|
|
|
|
EliminatePlayer(plr);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GameCall("OnPlayerRelaunch", plr, true);
|
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
return DoRelaunch(plr, clonk, nil);
|
2017-03-30 11:59:10 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
private func RespawnAtBase(object clonk)
|
2017-03-30 11:59:10 +00:00
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
var base = GetRelaunchBase(clonk);
|
2017-04-13 16:29:44 +00:00
|
|
|
if(base) return [base->GetX(), base->GetY() + base->GetDefHeight() / 2];
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private func TransferInventory(object from, object to)
|
|
|
|
{
|
2017-03-30 11:59:10 +00:00
|
|
|
if(!from || !to) return;
|
|
|
|
// Drop some items that cannot be transferred (such as connected pipes and dynamite igniters)
|
|
|
|
var i = from->ContentsCount(), contents;
|
|
|
|
while (i--)
|
|
|
|
if (contents = from->Contents(i))
|
|
|
|
if (contents->~IsDroppedOnDeath(from))
|
|
|
|
{
|
|
|
|
contents->Exit();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// The new clonk doesn't burn. To be consistent, also extinguish contents
|
|
|
|
contents->Extinguish();
|
|
|
|
}
|
|
|
|
return to->GrabContents(from);
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 16:29:44 +00:00
|
|
|
private func GetRelaunchBase(object clonk)
|
2017-03-25 12:41:09 +00:00
|
|
|
{
|
2017-03-30 11:59:10 +00:00
|
|
|
var plr = clonk->GetOwner();
|
|
|
|
// Neutral flagpoles are preferred respawn points, because they are used as the only respawn points in missions.
|
2017-04-13 16:29:44 +00:00
|
|
|
var base = clonk->FindObject2(Find_ID(Flagpole), Find_Func("IsNeutral"), clonk->Sort_Distance());
|
2017-03-30 11:59:10 +00:00
|
|
|
// If there are no neutral flagpoles, find closest base owned by the player (or team) and try to buy a clonk.
|
2017-04-13 16:29:44 +00:00
|
|
|
if (!base)
|
|
|
|
base = clonk->FindObject2(Find_Func("IsBaseBuilding"), Find_Allied(plr), clonk->Sort_Distance());
|
|
|
|
return base;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
public func DoRelaunch(int plr, object clonk, array position, bool no_creation)
|
2017-03-25 12:41:09 +00:00
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
if(!GetPlayerName(plr)) return;
|
|
|
|
if(respawn_last_clonk && GetCrewCount(plr) >= 1) return;
|
2017-03-30 11:59:10 +00:00
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
if(respawn_at_base) position = RespawnAtBase(clonk);
|
|
|
|
position = (position ?? GameCallEx("RelaunchPosition", plr, GetPlayerTeam(plr))) ?? FindRelaunchPos(plr);
|
2017-03-30 11:59:10 +00:00
|
|
|
|
|
|
|
var spawn;
|
|
|
|
|
|
|
|
|
|
|
|
// position array either has the form [x, y] or [[x, y], [x, y], ...]
|
|
|
|
if(GetType(position) == C4V_Array)
|
|
|
|
{
|
|
|
|
if(GetType(position[0]) == C4V_Array)
|
|
|
|
{
|
|
|
|
spawn = position[Random(GetLength(position))];
|
|
|
|
}
|
|
|
|
else spawn = position;
|
|
|
|
}
|
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
var new_clonk;
|
|
|
|
if(!no_creation)
|
2017-03-30 11:59:10 +00:00
|
|
|
{
|
|
|
|
if(free_crew)
|
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
new_clonk = CreateObjectAbove(clonk_type, spawn[0], spawn[1],plr);
|
|
|
|
if(!new_clonk) return;
|
|
|
|
new_clonk->MakeCrewMember(plr);
|
2017-03-30 11:59:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-04-13 16:29:44 +00:00
|
|
|
var base = GetRelaunchBase();
|
|
|
|
if(!base) return;
|
2017-03-30 11:59:10 +00:00
|
|
|
// Try to buy a crew member at the base.
|
|
|
|
var pay_plr = base->GetOwner();
|
|
|
|
// Payment in neutral bases by clonk owner.
|
|
|
|
if (pay_plr == NO_OWNER)
|
2017-04-13 16:58:10 +00:00
|
|
|
pay_plr = plr;
|
|
|
|
new_clonk = base->~DoBuy(clonk_type, plr, pay_plr, clonk);
|
|
|
|
if (new_clonk)
|
2017-03-30 11:59:10 +00:00
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
new_clonk->Exit();
|
2017-03-30 11:59:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
new_clonk = GetCrew(plr);
|
|
|
|
if(!new_clonk) return;
|
2017-03-30 11:59:10 +00:00
|
|
|
}
|
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
if (inventory_transfer) TransferInventory(clonk, new_clonk);
|
2017-03-30 11:59:10 +00:00
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
new_clonk->SetPosition(spawn[0], spawn[1], plr);
|
2017-03-30 11:59:10 +00:00
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
if(!GetCursor(plr) || GetCursor(plr) == clonk) SetCursor(plr, new_clonk);
|
|
|
|
new_clonk->DoEnergy(new_clonk.Energy || 100000);
|
2017-03-30 11:59:10 +00:00
|
|
|
|
2017-04-13 16:58:10 +00:00
|
|
|
if(relaunch_time)
|
2017-03-30 11:59:10 +00:00
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
new_clonk->CreateObject(RelaunchContainer,nil,nil,plr)->StartRelaunch(new_clonk);
|
2017-03-30 11:59:10 +00:00
|
|
|
}
|
|
|
|
return true;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected func FindRelaunchPos(int plr)
|
|
|
|
{
|
2017-03-30 11:59:10 +00:00
|
|
|
var tx, ty; // Test position.
|
|
|
|
for (var i = 0; i < 500; i++)
|
|
|
|
{
|
|
|
|
tx = Random(LandscapeWidth());
|
|
|
|
ty = Random(LandscapeHeight());
|
|
|
|
if (GBackSemiSolid(AbsX(tx), AbsY(ty)))
|
|
|
|
continue;
|
|
|
|
if (GBackSemiSolid(AbsX(tx+5), AbsY(ty+10)))
|
|
|
|
continue;
|
|
|
|
if (GBackSemiSolid(AbsX(tx+5), AbsY(ty-10)))
|
|
|
|
continue;
|
|
|
|
if (GBackSemiSolid(AbsX(tx-5), AbsY(ty+10)))
|
|
|
|
continue;
|
|
|
|
if (GBackSemiSolid(AbsX(tx-5), AbsY(ty-10)))
|
|
|
|
continue;
|
|
|
|
// Succes.
|
|
|
|
return [tx, ty];
|
|
|
|
}
|
|
|
|
return nil;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*-- Scenario saving --*/
|
|
|
|
|
|
|
|
public func SaveScenarioObject(props, ...)
|
|
|
|
{
|
2017-03-30 11:59:10 +00:00
|
|
|
if (!inherited(props, ...))
|
|
|
|
return false;
|
|
|
|
// Custom properties
|
|
|
|
props->Remove("Name"); // updated by initialization
|
|
|
|
props->Remove("Description"); // updated by initialization
|
|
|
|
if (inventory_transfer)
|
|
|
|
props->AddCall("InventoryTransfer", this, "SetInventoryTransfer", inventory_transfer);
|
|
|
|
if (free_crew)
|
|
|
|
props->AddCall("FreeCrew", this, "SetFreeCrew", free_crew);
|
|
|
|
if(respawn_at_base)
|
|
|
|
props->AddCall("BaseRespawn", this, "SetBaseRespawn", respawn_at_base);
|
|
|
|
return true;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
/*-- Globals --*/
|
|
|
|
|
|
|
|
global func SetRelaunchCount(int plr, int value)
|
|
|
|
{
|
2017-03-30 11:59:10 +00:00
|
|
|
if(UnlimitedRelaunches()) return;
|
2017-04-13 16:58:10 +00:00
|
|
|
GetRelaunchRule().relaunches[plr] = value;
|
|
|
|
Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule().relaunches[plr]);
|
2017-03-30 11:59:10 +00:00
|
|
|
return value;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
global func GetRelaunchCount(int plr)
|
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
return GetRelaunchRule().relaunches[plr];
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
global func DoRelaunchCount(int plr, int value)
|
|
|
|
{
|
2017-03-30 11:59:10 +00:00
|
|
|
if(UnlimitedRelaunches()) return;
|
2017-04-13 16:58:10 +00:00
|
|
|
GetRelaunchRule().relaunches[plr] += value;
|
|
|
|
Scoreboard->SetPlayerData(plr, "relaunches", GetRelaunchRule().relaunches[plr]);
|
2017-03-30 11:59:10 +00:00
|
|
|
return;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
global func UnlimitedRelaunches()
|
|
|
|
{
|
2017-04-13 16:58:10 +00:00
|
|
|
return GetRelaunchRule().default_relaunch_count == nil;
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
global func GetRelaunchRule()
|
|
|
|
{
|
2017-03-30 11:59:10 +00:00
|
|
|
return FindObject(Find_ID(Rule_Relaunch)) || CreateObject(Rule_Relaunch);
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Editor */
|
|
|
|
|
|
|
|
public func Definition(def)
|
|
|
|
{
|
2017-03-30 11:59:10 +00:00
|
|
|
if (!def.EditorProps) def.EditorProps = {};
|
|
|
|
def.EditorProps.inventory_transfer = { Name="$InventoryTransfer$", EditorHelp="$InventoryTransferHelp$", Type="bool", Set="SetInventoryTransfer" };
|
|
|
|
def.EditorProps.free_crew = { Name="$FreeCrew$", EditorHelp="$FreeCrewHelp$", Type="bool", Set="SetFreeCrew" };
|
|
|
|
def.EditorProps.respawn_at_base = {
|
|
|
|
Name = "$RespawnAtBase$",
|
|
|
|
EditorHelp = "$RespawnAtBaseHelp$",
|
|
|
|
Type = "bool",
|
|
|
|
Set = "SetBaseRespawn"
|
|
|
|
};
|
|
|
|
|
|
|
|
def.EditorProps.hold = {
|
2017-04-13 17:06:36 +00:00
|
|
|
Name = "$Holding$",
|
|
|
|
EditorHelp = "$HoldingHelp$",
|
2017-03-30 11:59:10 +00:00
|
|
|
Type = "bool",
|
2017-04-13 16:58:10 +00:00
|
|
|
Set = "Setholding"
|
2017-03-30 11:59:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
def.EditorProps.respawn_delay = {
|
|
|
|
Name = "$RespawnDelay$",
|
|
|
|
EditorHelp = "$RespawnDelayHelp$",
|
|
|
|
Type = "int",
|
|
|
|
Set = "SetRespawnDelay"
|
|
|
|
};
|
|
|
|
|
|
|
|
def.EditorProps.relaunch_count = {
|
|
|
|
Name = "$RelaunchCount$",
|
|
|
|
EditorHelp = "$RelaunchCountHelp$",
|
|
|
|
Type = "int",
|
|
|
|
Set = "SetDefaultRelaunches"
|
|
|
|
};
|
2017-03-25 12:41:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*-- Proplist --*/
|
|
|
|
|
|
|
|
local Name = "$Name$";
|
|
|
|
local Description = "$Description$";
|
|
|
|
local Visibility = VIS_Editor;
|
|
|
|
local EditorPlacementLimit = 1; // Rules are to be placed only once
|