Add EditorProps for EnemyAI effect

Also remove old object-based editor controls.
qteditor
Sven Eberhardt 2016-06-18 10:45:06 -04:00
parent 08b7980d69
commit af3e3bb6c8
9 changed files with 21 additions and 256 deletions

View File

@ -823,40 +823,6 @@ func SaveScenarioObject(props)
return true;
}
/* AI editor helper */
func EditCursorSelection(...)
{
var ai = AI->GetAI(this);
if (ai) Call(AI.EditCursorSelection, ai, ...);
return _inherited(...);
}
func EditCursorDeselection(...)
{
var ai = AI->GetAI(this);
if (ai) Call(AI.EditCursorDeselection, ai, ...);
return _inherited(...);
}
func AI_Add()
{
// Create AI and re-select
AI->AddAI(this);
EditCursorDeselection();
EditCursorSelection();
return true;
}
func FlipDir()
{
// Look the other way. If an AI is attached, also update its home position.
var new_dir = 1-GetDir();
if (this.ai) this.ai.home_dir = new_dir;
return SetDir(new_dir);
}
local EditCursorCommands = ["AI_Add()", "FlipDir()"];
/* Act Map */

View File

@ -1,6 +0,0 @@
[DefCore]
id=DebugLine
Version=6,0
Category=C4D_StaticBack
Vertices=2
Line=1

View File

@ -1,31 +0,0 @@
/*-- Debug dusplay line --*/
// definition call: create line
func Create(int x1,int y1,int x2,int y2,int clr)
{
var obj = CreateObject(DebugLine);
obj->Set(x1,y1,x2,y2,clr);
return obj;
}
func Set(int x1,int y1,int x2,int y2,int clr)
{
//SetAction("Connect");
SetVertexXY(0, x1,y1);
SetVertexXY(1, x2,y2);
this.LineColors = [clr, clr];
return;
}
// Will be recreated when needed.
func SaveScenarioObject() { return false; }
local ActMap = {
Connect = {
Prototype = Action,
Name = "Connect",
Procedure = DFA_CONNECT,
NextAction = "Connect"
}
};

View File

@ -1,8 +0,0 @@
[DefCore]
id=RangeMarker
Version=6,0
Category=C4D_StaticBack
Width=8
Height=8
Offset=0,0
Rotate=1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -1,51 +0,0 @@
/*-- Editor corner for dragging --*/
// Usage:
// RangeMarker->Create(int x, int y, int rotation, proplist callback_obj, callback_function, callback_param)
// Creates a range marker at the given position and rotation (top left: r=0, top right: r=90, etc.)
// When the marker is moved in editor mode, it will call callback_obj->callback_function(callback_param, new_x, new_y)
local cb_obj, cb_fn, cb_par; // callback object and function if self is moved
local lx,ly; // last x/y coordinates
local EditCursorCommands = ["OnMoved()"];
// definition call: create range marker
func Create(int x, int y, int rotation, proplist callback_obj, callback_function, callback_param)
{
var obj = CreateObject(RangeMarker, x, y);
obj->Init(rotation, callback_obj, callback_function, callback_param);
return obj;
}
func Init(int r, proplist callback_obj, callback_function, callback_param)
{
SetR(r);
cb_obj = callback_obj;
cb_fn = callback_function;
cb_par = callback_param;
lx = GetX();
ly = GetY();
return true;
}
func OnMoved()
{
lx = GetX(); ly = GetY();
if (!cb_obj) return RemoveObject();
return cb_obj->Call(cb_fn, cb_par, lx, ly);
}
func EditCursorDeselection(object new_selection)
{
// If new selection is neither this nor the taget object, ensure target removes any editor markers
if (cb_obj && new_selection != cb_obj) cb_obj->EditCursorDeselection(new_selection);
return true;
}
func EditCursorMoved(int old_x, int old_y)
{
return OnMoved();
}
// Will be recreated when needed.
func SaveScenarioObject() { return false; }

View File

@ -16,6 +16,15 @@ static const AI_DefMaxAggroDistance = 200, // lose sight to target if it is this
AI_AlertTime = 800; // number of frames after alert after which AI no longer checks for projectiles
/* Public interface */
// Change whether target Clonk has an AI (used by editor)
func SetAI(object clonk, bool has_ai)
{
if (has_ai)
return AddAI(clonk);
else
return RemoveEffect("AI", clonk);
}
// Add AI execution timer to target Clonk
func AddAI(object clonk)
{
@ -30,19 +39,10 @@ func AddAI(object clonk)
SetHome(clonk);
SetGuardRange(clonk, fx.home_x-AI_DefGuardRangeX, fx.home_y-AI_DefGuardRangeY, AI_DefGuardRangeX*2, AI_DefGuardRangeY*2);
SetMaxAggroDistance(clonk, AI_DefMaxAggroDistance);
// AI editor commands
if (!clonk.EditCursorCommands)
clonk.EditCursorCommands = [];
else if (clonk.EditCursorCommands == clonk.Prototype.EditCursorCommands)
clonk.EditCursorCommands = clonk.EditCursorCommands[:];
var idx;
if ((idx=GetIndexOf(clonk.EditCursorCommands, "AI_Add()"))>=0) clonk.EditCursorCommands[idx] = nil;
if (GetIndexOf(clonk.EditCursorCommands, AI.AI_SetHome)<0)
{
var l = GetLength(clonk.EditCursorCommands);
clonk.EditCursorCommands[l++] = clonk.AI_SetHome = AI.AI_SetHome;
clonk.EditCursorCommands[l++] = clonk.AI_BindInventory = AI.AI_BindInventory;
}
// AI editor stuff
fx.EditorProp_guard_range = { Name="$GuardRange$", Type="rect", Storage="proplist", Color=0xff00, Relative=false };
fx.EditorProp_ignore_allies = { Name="$IgnoreAllies$", Type="bool" };
fx.EditorProp_max_aggro_distance = { Name="$MaxAggroDistance$", Type="circle", Color=0x808080 };
return fx;
}
@ -55,7 +55,6 @@ func BindInventory(object clonk)
var cnt = clonk->ContentsCount();
fx.bound_weapons = CreateArray(cnt);
for (var i=0; i<cnt; ++i) fx.bound_weapons[i] = clonk->Contents(i);
clonk->Call(fx.ai.UpdateDebugDisplay, fx);
return true;
}
@ -87,7 +86,6 @@ func SetGuardRange(object clonk, int x, int y, int wdt, int hgt)
wdt = Min(wdt, LandscapeWidth() - x);
hgt = Min(hgt, LandscapeHeight() - y);
fx.guard_range = {x=x, y=y, wdt=wdt, hgt=hgt};
clonk->Call(fx.ai.UpdateDebugDisplay, fx);
return true;
}
@ -104,7 +102,6 @@ func SetAllyAlertRange(object clonk, int new_range)
{
if (!clonk) return false; var fx = clonk.ai; if (!fx) return false;
fx.ally_alert_range = new_range;
clonk->Call(fx.ai.UpdateDebugDisplay, fx);
return true;
}
@ -115,7 +112,6 @@ func SetEncounterCB(object clonk, string cb_fn)
{
if (!clonk) return false; var fx = clonk.ai; if (!fx) return false;
fx.encounter_cb = cb_fn;
clonk->Call(fx.ai.UpdateDebugDisplay, fx);
return true;
}
@ -144,8 +140,6 @@ protected func FxAITimer(clonk, fx, int time) { clonk->ExecuteAI(fx, time); retu
protected func FxAIStop(clonk, fx, int reason)
{
// remove debug display
if (fx.debug) clonk->Call(fx.ai.EditCursorDeselection, fx);
// remove weapons on death
if (reason == FX_Call_RemoveDeath)
{
@ -153,13 +147,6 @@ protected func FxAIStop(clonk, fx, int reason)
}
// remove AI reference
if (clonk && clonk.ai == fx) clonk.ai = nil;
// remove edit cursor commands
if (clonk && clonk.EditCursorCommands)
{
var idx;
if ((idx=GetIndexOf(clonk.EditCursorCommands, AI.AI_SetHome))>=0) clonk.EditCursorCommands[idx] = nil;
if ((idx=GetIndexOf(clonk.EditCursorCommands, AI.AI_BindInventory))>=0) clonk.EditCursorCommands[idx] = nil;
}
return FX_OK;
}
@ -764,105 +751,7 @@ private func GetBallisticAngle(int dx, int dy, int v, int max_angle)
}
/* Editor display */
// called in clonk context
func UpdateDebugDisplay(fx, int ignore_range_marker)
func Definition(def)
{
if (fx.debug) CreateDebugDisplay(fx, ignore_range_marker);
return true;
}
func EditCursorSelection(fx)
{
// Object selected in editor. Show markers!
return CreateDebugDisplay(fx);
}
func EditCursorDeselection(fx, object next_target)
{
// Is the user manipulating markers? Then don't remove them!
if (next_target && next_target->GetID() == RangeMarker) return true;
// Otherwise, clear markers
return RemoveDebugDisplay(fx);
}
// called in clonk context
func CreateDebugDisplay(fx, int ignore_range_marker)
{
// clear previous
if (fx.debug) RemoveDebugDisplay(fx, ignore_range_marker);
// encounter message
var msg = "";
if (fx.encounter_cb) msg = Format("%s%v", msg, fx.encounter_cb);
// contents message
for (var i=0; i<ContentsCount(); ++i)
msg = Format("%s{{%i}}", msg, Contents(i)->GetID());
Message("@AI %s", msg);
// draw ally alert range. draw as square, although a circle would be more appropriate
if (!fx.debug) fx.debug = {};
var clr;
var x=GetX(), y=GetY();
if (fx.ally_alert_range)
{
clr = 0xffffff00;
fx.debug.a1 = DebugLine->Create(x,y-fx.ally_alert_range,x+fx.ally_alert_range,y,clr);
fx.debug.a2 = DebugLine->Create(x+fx.ally_alert_range,y,x,y+fx.ally_alert_range,clr);
fx.debug.a3 = DebugLine->Create(x,y+fx.ally_alert_range,x-fx.ally_alert_range,y,clr);
fx.debug.a4 = DebugLine->Create(x-fx.ally_alert_range,y,x,y-fx.ally_alert_range,clr);
}
// draw guard range
if (fx.guard_range.wdt && fx.guard_range.hgt)
{
clr = 0xffff0000;
fx.debug.r1 = DebugLine->Create(fx.guard_range.x,fx.guard_range.y,fx.guard_range.x+fx.guard_range.wdt,fx.guard_range.y,clr);
fx.debug.r2 = DebugLine->Create(fx.guard_range.x+fx.guard_range.wdt,fx.guard_range.y,fx.guard_range.x+fx.guard_range.wdt,fx.guard_range.y+fx.guard_range.hgt,clr);
fx.debug.r3 = DebugLine->Create(fx.guard_range.x+fx.guard_range.wdt,fx.guard_range.y+fx.guard_range.hgt,fx.guard_range.x,fx.guard_range.y+fx.guard_range.hgt,clr);
fx.debug.r4 = DebugLine->Create(fx.guard_range.x,fx.guard_range.y+fx.guard_range.hgt,fx.guard_range.x,fx.guard_range.y,clr);
if (!fx.debug.rm1) fx.debug.rm1 = RangeMarker->Create(fx.guard_range.x , fx.guard_range.y , 0, this, AI.ChangeGuardRange, 0);
if (!fx.debug.rm2) fx.debug.rm2 = RangeMarker->Create(fx.guard_range.x+fx.guard_range.wdt, fx.guard_range.y , 90, this, AI.ChangeGuardRange, 1);
if (!fx.debug.rm3) fx.debug.rm3 = RangeMarker->Create(fx.guard_range.x+fx.guard_range.wdt, fx.guard_range.y+fx.guard_range.hgt,180, this, AI.ChangeGuardRange, 2);
if (!fx.debug.rm4) fx.debug.rm4 = RangeMarker->Create(fx.guard_range.x , fx.guard_range.y+fx.guard_range.hgt,270, this, AI.ChangeGuardRange, 3);
}
return true;
}
func ChangeGuardRange(int corner_idx, int x, int y)
{
var fx = this.ai;
if (!fx) return false;
if (corner_idx == 0 || corner_idx == 3)
{ fx.guard_range.wdt += fx.guard_range.x - x; fx.guard_range.x = x; }
else
{ fx.guard_range.wdt = x - fx.guard_range.x; }
if (corner_idx < 2)
{ fx.guard_range.hgt += fx.guard_range.y - y; fx.guard_range.y = y; }
else
{ fx.guard_range.hgt = y - fx.guard_range.y; }
Call(fx.ai.UpdateDebugDisplay, fx, corner_idx+1);
return true;
}
// called in clonk context
func RemoveDebugDisplay(fx, int ignore_range_marker)
{
// Remove any marker objects
if (fx.debug)
{
if (fx.debug.r1) fx.debug.r1->RemoveObject();
if (fx.debug.r2) fx.debug.r2->RemoveObject();
if (fx.debug.r3) fx.debug.r3->RemoveObject();
if (fx.debug.r4) fx.debug.r4->RemoveObject();
if (ignore_range_marker != 1 && fx.debug.rm1) fx.debug.rm1->RemoveObject();
if (ignore_range_marker != 2 && fx.debug.rm2) fx.debug.rm2->RemoveObject();
if (ignore_range_marker != 3 && fx.debug.rm3) fx.debug.rm3->RemoveObject();
if (ignore_range_marker != 4 && fx.debug.rm4) fx.debug.rm4->RemoveObject();
if (fx.debug.a1) fx.debug.a1->RemoveObject();
if (fx.debug.a2) fx.debug.a2->RemoveObject();
if (fx.debug.a3) fx.debug.a3->RemoveObject();
if (fx.debug.a4) fx.debug.a4->RemoveObject();
Message("");
}
if (!ignore_range_marker) fx.debug = nil;
return true;
Clonk.EditorProp_AI = { Type = "has_effect", Effect = "AI", Set = "AI->SetAI", Global = true };
}

View File

@ -0,0 +1,3 @@
GuardRange=Bewachter Bereich
MaxAggroDistance=Angriffsradius
IgnoreAllies=Mitspieler ignorieren

View File

@ -0,0 +1,3 @@
GuardRange=Guarded area
MaxAggroDistance=Attack radius
IgnoreAllies=Ignore allies