1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
/**
Item Spawn
If the clonk moves through the spawn it automatically gets the item.
@author Maikel, Sven2
*/
local Name="$Name$";
local Description="$Description$";
local spawn_id; // Item to be spawned
local team; // If assigned, spawner can only be used by specific team
local spawn_list; // List keeping track of collected objects to block spawning until used up
local Visibility; // Custom visibility
local spawn_particle; // prepared gfx proplist
/* Interface */
// Definition call: Create an item spawner and set its spawn def
public func Create(id def, int x, int y)
{
if (this != ItemSpawn)
return;
var spawn = CreateObject(ItemSpawn, x, y);
if (spawn) spawn->SetSpawnObject(def);
return spawn;
}
// Change object to be spawned by this
public func SetSpawnObject(id def)
{
spawn_id = def;
SetGraphics(nil, spawn_id, GFX_Overlay, GFXOV_MODE_Base);
// Changing the spawn id also resets all collected items to make the spawn available again
for (var plr in GetPlayers())
{
spawn_list[plr] = nil;
UpdateVisibility(plr);
}
return true;
}
// Re-enable spawning for given player
public func Reset(plr)
{
if (!GetType(plr)) plr = GetPlayers(); else plr = [plr];
for (var p in plr)
{
spawn_list[p] = nil;
UpdateVisibility(p);
}
return true;
}
// If called, items can only be collected by members of this team
public func SetTeam(int new_team)
{
team = new_team;
for (var plr in GetPlayers()) UpdateVisibility(plr);
return true;
}
/*-- Spawn Effect --*/
public func Construction()
{
spawn_list = [];
spawn_particle =
{
Size = PV_Linear(24, 36),
Alpha = PV_Linear(0, 255),
R = PV_Random(200, 255),
G = PV_Random(200, 255),
B = PV_Random(200, 255)
};
// Initial visibility for all players
Visibility = [VIS_Select | VIS_God, false,false,false,false];
for (var plr in GetPlayers()) UpdateVisibility(plr);
// Timer effect
AddEffect("Spawn", this, 1, 2, this);
return true;
}
private func UpdateVisibility(int plr)
{
// Spawn is visible if the item is currently not collected by the player
// In case a team is set, it also needs to match
Visibility[plr+1] = !spawn_list[plr] && (!team || team == GetPlayerTeam(plr));
return true;
}
private func FxSpawnTimer(object target, proplist effect, int time)
{
// Produce some particles for the spawn ring.
if (time % 30 == 0)
CreateParticle("MagicRing", 0, 0, 0, 0, 60, spawn_particle, 1);
// Update item availability for all active players.
if (time % 10 == 0)
for (var plr in GetPlayers()) UpdateVisibility(plr);
// Check for crew members near the item spawn and give the item.
for (var crew in FindObjects(Find_OCF(OCF_CrewMember), Find_Distance(20)))
{
var plr = crew->GetOwner();
if (!spawn_list[plr] && Visibility[plr+1] && spawn_id)
{
if ((!spawn_id->~IsCarryHeavy() && crew->ContentsCount() < crew.MaxContentsCount) || (spawn_id->~IsCarryHeavy() && !crew->IsCarryingHeavy()))
{
// Special way to pick up carry heavy objects instantly without animation.
if (spawn_id->~IsCarryHeavy())
spawn_list[plr] = crew->CreateCarryHeavyContents(spawn_id);
else
spawn_list[plr] = crew->CreateContents(spawn_id);
UpdateVisibility(plr);
crew->~Get(spawn_list[plr]); // for sound
}
}
}
return FX_OK;
}
/* Player/team changes */
public func InitializePlayer(int plr)
{
// Update visibility and clear spawned item for new player (so we don't need to handle RemovePlayer)
spawn_list[plr] = nil;
return UpdateVisibility(plr);
}
public func OnTeamSwitch(int plr, int new_team, int old_team)
{
// Broadcast on player team switch: Update visibility
return UpdateVisibility(plr);
}
public func OnClonkDeath(object clonk, int killed_by)
{
// Reset spawn on clonk death
// This is odd in multi-clonk rounds with spawn points, but the alternative
// of not resetting it is probably worse because the spawned item will
// usually lie around somewhere.
var plr = clonk->GetOwner();
if (plr >= 0) Reset(plr);
}
/* Scenario saving */
func SaveScenarioObject(props)
{
if (!inherited(props, ...)) return false;
// Visibility is handled by us
props->Remove("Visibility");
// Item spawner has its own creation procedure
if (spawn_id)
{
props->RemoveCreation();
props->Add(SAVEOBJ_Creation, "%i->Create(%i,%d,%d)", GetID() /* to allow overloads */, spawn_id, GetX(), GetY());
}
if (team) props->AddCall("Team", this, "SetTeam", team);
return true;
}
/* Editor props */
local EditorProps = { spawn_id = { Name = "$SpawnID$", EditorHelp = "$SpawnIDHelp$", Priority = 100, Type = "def", Filter = "Collectible", Set = "SetSpawnObject" } };
|