flag library: fix on owner change and clean up

issue1247
Maikel de Vries 2015-02-09 19:31:56 +01:00
parent b7b6b187f7
commit 7f79caade5
10 changed files with 102 additions and 119 deletions

View File

@ -84,10 +84,7 @@ protected func InitializePlayer(int plr)
// Claim ownership of unowned structures
for (var structure in FindObjects(Find_Or(Find_Category(C4D_Structure), Find_Func("IsFlagpole")), Find_Owner(NO_OWNER)))
{
structure->SetOwner(plr);
structure->~RefreshOwnershipOfSurrounding();
}
// Should be done in OnOwnerChanged? It doesn't happen ATM.
RedrawAllFlagRadiuses();

View File

@ -84,10 +84,7 @@ protected func InitializePlayer(int plr)
// Claim ownership of unowned structures
for (var structure in FindObjects(Find_Or(Find_Category(C4D_Structure), Find_Func("IsFlagpole")), Find_Owner(NO_OWNER)))
{
structure->SetOwner(plr);
structure->~RefreshOwnershipOfSurrounding();
}
// Should be done in OnOwnerChanged? It doesn't happen ATM.
RedrawAllFlagRadiuses();

View File

@ -1,17 +1,10 @@
/**
Flag Construction Preview Helper Arrow
Flag Library: Construction Preview Arrow
@author Sven
*/
protected func Initialize()
{
this.Visibility = VIS_Owner;
return;
}
/*-- Saving --*/
// The UI is not saved.
@ -20,6 +13,8 @@ public func SaveScenarioObject() { return false; }
/*-- Properties --*/
local Visibility = VIS_Owner;
local ActMap = {
Show = {
Prototype = Action,
@ -34,5 +29,3 @@ local ActMap = {
NextAction = "Show",
},
};
local Name = "$Name$";

View File

@ -1 +0,0 @@
Name=Benachbarte Flagge im Radius

View File

@ -1,5 +1,5 @@
/**
ConstructionPreviewer for Flag Library
Flag Library: Construction Previewer
Construction preview object for objects implementing flagpole behavior.
This object is used in the flag library
Shows helper arrows around the preview to tell the player which

View File

@ -1,6 +1,7 @@
/**
Flag Marker
A small marker object which indicates the ownership area of a flag. This is part of the flag library.
Flag Library: Marker
A small marker object which indicates the ownership area of a flag.
This is part of the flag library.
@author Zapper, Maikel
*/
@ -143,6 +144,4 @@ local ActMap = {
}
};
local Name = "$Name$";
local Description = "$Description$";
local Plane = 1545;

View File

@ -1,2 +0,0 @@
Name=Grenzpfosten
Description=Markiert dein Reich.

View File

@ -1,2 +0,0 @@
Name=Marker
Description=Marks your reign.

View File

@ -85,23 +85,18 @@ public func RedrawFlagRadius()
return;
}
//var flags = FindObjects(Find_ID(FlagPole),Find_Exclude(target), Find_Not(Find_Owner(GetOwner())), /*Find_Distance(FLAG_DISTANCE*2 + 10,0,0)*/Sort_Func("GetLifeTime"));
// Make a list of all other flags.
var other_flags = [];
var i = 0;
for (var flag in LIB_FLAG_FlagList)
if (flag)
{
//if(f->GetOwner() == GetOwner()) continue;
if (flag == this)
continue;
other_flags[i++] = flag;
}
{
if (!flag || flag == this)
continue;
PushBack(other_flags, flag);
}
// Draw the flag border.
var count = Max(5, lib_flag.radius / 10);
var marker_index = -1;
for (var i = 0; i < 360; i += 360 / count)
{
++marker_index;
@ -131,33 +126,35 @@ public func RedrawFlagRadius()
}
}
}
// If the marker should not be drawn: move to center and fade out.
var marker = lib_flag.range_markers[marker_index];
if (!draw)
{
if (marker_index < GetLength(lib_flag.range_markers))
if (lib_flag.range_markers[marker_index])
{
if (marker)
{
lib_flag.range_markers[marker_index]->FadeOut();
lib_flag.range_markers[marker_index]->MoveTo(GetX(), GetY(), -lib_flag.range_markers[marker_index]->GetR());
marker->FadeOut();
marker->MoveTo(GetX(), GetY(), -marker->GetR());
}
}
continue;
}
var marker = lib_flag.range_markers[marker_index];
if (!marker)
{
marker = CreateObject(GetFlagMarkerID(), 0, 0, GetOwner());
lib_flag.range_markers[marker_index] = marker;
marker->SetR(Angle(0, 0, x, y));
}
marker->FadeIn();
marker->MoveTo(GetX() + x, GetY() + y, Angle(0, 0, x, y));
lib_flag.range_markers[marker_index] = marker;
}
// there were unnecessary markers?
if(marker_index < GetLength(lib_flag.range_markers) - 1)
// Check whether there were any unnecessary markers.
if (marker_index < GetLength(lib_flag.range_markers) - 1)
{
var old = marker_index;
while(++marker_index < GetLength(lib_flag.range_markers))
while (++marker_index < GetLength(lib_flag.range_markers))
{
var marker = lib_flag.range_markers[marker_index];
marker->RemoveObject();
@ -165,32 +162,31 @@ public func RedrawFlagRadius()
}
SetLength(lib_flag.range_markers, old + 1);
}
return true;
return;
}
func RefreshOwnershipOfSurrounding()
// Changes the ownership of the structures within this flag's radius.
private func RefreshOwnershipOfSurrounding()
{
for(var obj in FindObjects(Find_Distance(lib_flag.radius), Find_Func("CanBeOwned")))
for (var obj in FindObjects(Find_Distance(lib_flag.radius), Find_Func("CanBeOwned")))
{
var o = GetOwnerOfPosition(AbsX(obj->GetX()), AbsY(obj->GetY()));
if(obj->GetOwner() == o) continue;
var old = obj->GetOwner();
obj->SetOwner(o);
var owner = GetOwnerOfPosition(AbsX(obj->GetX()), AbsY(obj->GetY()));
if (obj->GetOwner() == owner)
continue;
obj->SetOwner(owner);
}
return;
}
private func AddOwnership()
{
// Add this flag to the global list of flags.
if (GetIndexOf(LIB_FLAG_FlagList, this) == -1)
LIB_FLAG_FlagList[GetLength(LIB_FLAG_FlagList)] = this;
PushBack(LIB_FLAG_FlagList, this);
// Redraw radiuses of all flags.
RedrawAllFlagRadiuses();
// Refresh the ownership of the flag's surroundings.
RefreshOwnershipOfSurrounding();
// Linked flags - optimization for the power system.
RefreshAllFlagLinks();
return;
@ -198,26 +194,17 @@ private func AddOwnership()
private func RemoveOwnership()
{
// Remove all the flag markers.
ClearFlagMarkers();
// Remove the flag from the global flag list.
for (var i = 0; i < GetLength(LIB_FLAG_FlagList); ++i)
{
if (LIB_FLAG_FlagList[i] != this)
continue;
LIB_FLAG_FlagList[i] = LIB_FLAG_FlagList[GetLength(LIB_FLAG_FlagList)-1];
SetLength(LIB_FLAG_FlagList, GetLength(LIB_FLAG_FlagList)-1);
break;
}
RemoveArrayValue(LIB_FLAG_FlagList, this);
// Redraw radiuses of all flags.
RedrawAllFlagRadiuses();
// Refresh the ownership of the flag's surroundings.
RefreshOwnershipOfSurrounding();
// Linked flags - optimization for the power system.
RefreshAllFlagLinks();
return;
}
protected func FxIntFlagMovementCheckStart(object target, proplist effect, int temp)
@ -277,7 +264,7 @@ protected func FxRefreshLinkedFlagsTimer()
return -1;
}
// Returns all flags allied to owner of which the radius intersects the given circle
// Returns all flags allied to owner of which the radius intersects the given circle.
public func FindFlagsInRadius(object center_object, int radius, int owner)
{
var flag_list = [];
@ -291,7 +278,7 @@ public func FindFlagsInRadius(object center_object, int radius, int owner)
continue;
if (ObjectDistance(center_object, flag) > radius + flag->GetFlagRadius())
continue;
flag_list[GetLength(flag_list)] = flag;
PushBack(flag_list, flag);
}
}
return flag_list;
@ -299,73 +286,86 @@ public func FindFlagsInRadius(object center_object, int radius, int owner)
public func RefreshLinkedFlags()
{
// failsafe - the array should exist
if(GetType(LIB_FLAG_FlagList) != C4V_Array) return;
var current = [];
var new = [this];
var owner = GetOwner();
while (GetLength(new))
{
for (var f in new)
if(f != this)
current[GetLength(current)] = f;
var old = new;
new = [];
// Safety check: the global flag list should exist.
if (GetType(LIB_FLAG_FlagList) != C4V_Array)
return;
for (var oldflag in old)
// Construct a list fo currently linked flags (to this flag).
var current_linked_flags = [];
var owner = GetOwner();
// Do this by iterating over all directly linked flags and go outward from this flag.
var iterate_flags = [this];
// Once the list of iterated flags is empty we are done.
while (GetLength(iterate_flags))
{
// Store all the flags found in the last iteration which are not this flag.
for (var flag in iterate_flags)
if (flag != this)
PushBack(current_linked_flags, flag);
// Find the new iteration of flags which are connected to the flags in the previous iteration.
var previous_iterate_flags = iterate_flags;
iterate_flags = [];
for (var prev_flag in previous_iterate_flags)
{
for (var flag in LIB_FLAG_FlagList)
{
if(!IsAllied(flag->GetOwner(), owner)) continue;
if(GetIndexOf(current, flag) != -1) continue;
if(GetIndexOf(new, flag) != -1) continue;
if(flag == this) continue;
if(ObjectDistance(oldflag, flag) > oldflag->GetFlagRadius() + flag->GetFlagRadius()) continue;
new[GetLength(new)] = flag;
// A new connected flag must be allied.
if (!IsAllied(flag->GetOwner(), owner))
continue;
// And must not be an already found flag or this flag.
if (GetIndexOf(current_linked_flags, flag) != -1 || flag == this)
continue;
// Neither may it be an already found flag in this loop.
if (GetIndexOf(iterate_flags, flag) != -1)
continue;
// Last, check whether the new flag is really connected to the previous flag.
if (ObjectDistance(prev_flag, flag) > prev_flag->GetFlagRadius() + flag->GetFlagRadius())
continue;
PushBack(iterate_flags, flag);
}
}
}
lib_flag.linked_flags = current;
// Update the linked flags of this flag.
lib_flag.linked_flags = current_linked_flags;
// update flag links for all linked flags - no need for every flag to do that
// meanwhile, adjust power helper. Merge if necessary
// since we don't know whether flag links have been lost we will create a new power helper and possibly remove old ones
Library_Power->Init(); // make sure the power system is set up
var old = lib_flag.power_helper;
lib_flag.power_helper = CreateObject(Library_Power, 0, 0, NO_OWNER);
LIB_POWR_Networks[GetLength(LIB_POWR_Networks)] = lib_flag.power_helper;
// list of helpers yet to merge
var to_merge = [old];
// copy from me
lib_flag.linked_flags = current;
// Update the linked flags for all other linked flags as well.
for (var other in lib_flag.linked_flags)
{
other->CopyLinkedFlags(this, lib_flag.linked_flags);
if (GetIndexOf(to_merge, other.lib_flag.power_helper) == -1)
to_merge[GetLength(to_merge)] = other.lib_flag.power_helper;
other.lib_flag.power_helper = lib_flag.power_helper;
}
// for every object in to_merge check if it actually (still) belongs to the group
// Since the connected flags have been updated it is necessary to update the power helper as well.
// First make sure the power system is initialized.
Library_Power->Init();
// Get the old power network for this flag.
var old_network = lib_flag.power_helper;
// Create a new power network for ths flag since we don't know whether flag links have been lost.
// We then just possibly remove the old ones if they exist.
lib_flag.power_hhelper = CreateObject(Library_Power, 0, 0, NO_OWNER);
PushBack(LIB_POWR_Networks, lib_flag.power_helper);
// Make a list of the power networks which need to be merged into the new one.
var to_merge = [old_network];
for (var linked_flag in lib_flag.linked_flags)
{
// Add old network of this flag to merge list and reset to new network.
if (GetIndexOf(to_merge, linked_flag.lib_flag.power_helper) == -1)
PushBack(to_merge, linked_flag.lib_flag.power_helper);
linked_flag->SetPowerHelper(lib_flag.power_helper);
}
// Now merge all networks into the newly created network.
for (var network in to_merge)
{
if (network == nil)
continue;
RefreshPowerNetwork(network);
}
return;
}
// Copy the linked flags from another flag (from) and its flaglist.
public func CopyLinkedFlags(object from, array flaglist)
{
lib_flag.linked_flags = flaglist[:];
for (var i = GetLength(lib_flag.linked_flags)-1; i >= 0; --i)
for (var i = GetLength(lib_flag.linked_flags) - 1; i >= 0; --i)
if (lib_flag.linked_flags[i] == this)
lib_flag.linked_flags[i] = from;
StopRefreshLinkedFlags();
@ -379,9 +379,10 @@ private func ClearFlagMarkers()
lib_flag.range_markers = [];
}
// Engine callback: reassign owner of flag markers for correct color.
// Engine callback: owner of the flag has changed.
protected func OnOwnerChanged(int new_owner, int old_owner)
{
// Reassign owner of flag markers for correct color.
for (var marker in lib_flag.range_markers)
{
if (!marker)
@ -389,6 +390,8 @@ protected func OnOwnerChanged(int new_owner, int old_owner)
marker->SetOwner(new_owner);
marker->ResetColor();
}
// Also change the ownership of the surrounding buildings.
RefreshOwnershipOfSurrounding();
return _inherited(new_owner, old_owner, ...);
}