forked from Mirrors/openclonk
Sequence: Add more triggers.
* Player enters circular region * Game starts (after player joins) * Player joins * Player removed * All goals fulfilled * Clonk death * Construction of structure * Production of itemqteditor
parent
14d01cd5cd
commit
58faf41068
|
@ -46,16 +46,44 @@ public func Start(string name, int progress, ...)
|
|||
|
||||
protected func InitializePlayer(int plr)
|
||||
{
|
||||
JoinPlayer(plr);
|
||||
if (seq_name)
|
||||
{
|
||||
// Scripted sequence
|
||||
JoinPlayer(plr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Editor-made sequence
|
||||
if (trigger && trigger.Trigger == "player_join") OnTrigger(nil, plr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected func InitializePlayers(int plr)
|
||||
{
|
||||
if (!seq_name)
|
||||
{
|
||||
// Editor-made sequence
|
||||
if (trigger && trigger.Trigger == "game_start") OnTrigger();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public func RemovePlayer(int plr)
|
||||
{
|
||||
// Called by sequence if it ends and by engine if player leaves.
|
||||
var fn_remove = Format("~%s_RemovePlayer", seq_name);
|
||||
if (!Call(fn_remove, plr))
|
||||
GameCall(fn_remove, this, plr);
|
||||
if (seq_name)
|
||||
{
|
||||
// Scripted sequence
|
||||
// Called by sequence if it ends and by engine if player leaves.
|
||||
var fn_remove = Format("~%s_RemovePlayer", seq_name);
|
||||
if (!Call(fn_remove, plr))
|
||||
GameCall(fn_remove, this, plr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Editor-made sequence
|
||||
if (trigger && trigger.Trigger == "player_remove") OnTrigger(nil, plr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -300,6 +328,8 @@ global func GetActiveSequence()
|
|||
|
||||
/* User-made sequences from the editor */
|
||||
|
||||
local Name="$Name$";
|
||||
local Description="$Description$";
|
||||
local trigger, condition, action, action_progress_mode, action_allow_parallel;
|
||||
local active=true;
|
||||
local check_interval=12;
|
||||
|
@ -311,14 +341,27 @@ local finished;
|
|||
|
||||
public func Definition(def)
|
||||
{
|
||||
// EditorActions
|
||||
if (!def.EditorActions) def.EditorActions = {};
|
||||
def.EditorActions.Test = { Name="$Test$", Command="OnTrigger(nil, nil, true)" };
|
||||
// EditorProps
|
||||
if (!def.EditorProps) def.EditorProps = {};
|
||||
def.EditorProps.active = { Name="$Active$", Type="bool", Set="SetActive" };
|
||||
def.EditorProps.finished = { Name="$Finished$", Type="bool", Set="SetFinished" };
|
||||
def.EditorProps.trigger = { Name="$Trigger$", Type="enum", OptionKey="Trigger", Options = [
|
||||
{ Name="$None$" },
|
||||
{ Name="$EnterRegionRect$", Value={ Trigger="enter_region_rect", Rect=[-20, -20, 40, 40] }, ValueKey="Rect", Delegate={ Type="rect", Relative=true, Set="SetTriggerRect", SetRoot=true } } // TODO: Allow runtime update of search fn
|
||||
{ Name="$EnterRegionRect$", Value={ Trigger="enter_region_rect", Rect=[-20, -20, 40, 40] }, ValueKey="Rect", Delegate={ Type="rect", Color=0xff8000, Relative=true, Set="SetTriggerRect", SetRoot=true } },
|
||||
{ Name="$EnterRegionCircle$", Value={ Trigger="enter_region_circle", Radius=25 }, ValueKey="Radius", Delegate={ Type="circle", Color=0xff8000, Relative=true, Set="SetTriggerRadius", SetRoot=true } },
|
||||
{ Name="$GameStart$", Value={ Trigger="game_start" } },
|
||||
{ Name="$PlayerJoin$", Value={ Trigger="player_join" } },
|
||||
{ Name="$PlayerRemove$", Value={ Trigger="player_remove" } },
|
||||
{ Name="$GoalsFulfilled$", Value={ Trigger="goals_fulfilled" } },
|
||||
{ Group="$ClonkDeath$", Name="$AnyClonkDeath$", Value={ Trigger="any_clonk_death" } },
|
||||
{ Group="$ClonkDeath$", Name="$PlayerClonkDeath$", Value={ Trigger="player_clonk_death" } },
|
||||
{ Group="$ClonkDeath$", Name="$NeutralClonkDeath$", Value={ Trigger="neutral_clonk_death" } },
|
||||
{ Group="$ClonkDeath$", Name="$SpecificClonkDeath$", Value={ Trigger="specific_clonk_death" }, ValueKey="Object", Delegate={ Type="object", Filter="IsClonk" } },
|
||||
{ Name="$Construction$", Value={ Trigger="construction" }, ValueKey="ID", Delegate={ Type="def", Filter="IsStructure", EmptyName="$Anything$" } },
|
||||
{ Name="$Production$", Value={ Trigger="production" }, ValueKey="ID", Delegate={ Type="def", EmptyName="$Anything$" } },
|
||||
] };
|
||||
def.EditorProps.condition = UserAction.Evaluator.Condition;
|
||||
def.EditorProps.action = UserAction.Prop;
|
||||
|
@ -327,7 +370,7 @@ public func Definition(def)
|
|||
def.EditorProps.deactivate_after_action = { Name="$DeactivateAfterAction$", Type="bool" };
|
||||
}
|
||||
|
||||
public func SetTrigger(new_trigger)
|
||||
public func SetTrigger(proplist new_trigger)
|
||||
{
|
||||
trigger = new_trigger;
|
||||
// Set trigger: Restart any specific trigger timers
|
||||
|
@ -339,13 +382,24 @@ public func SetTrigger(new_trigger)
|
|||
return true;
|
||||
}
|
||||
|
||||
public func SetTriggerRect(new_trigger_rect)
|
||||
public func SetTriggerRect(array new_trigger_rect)
|
||||
{
|
||||
if (trigger && trigger.Rect)
|
||||
{
|
||||
trigger.Rect = new_trigger_rect;
|
||||
SetTrigger(trigger); // restart trigger
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public func SetTriggerRadius(int new_trigger_radius)
|
||||
{
|
||||
if (trigger)
|
||||
{
|
||||
trigger.Radius = new_trigger_radius;
|
||||
SetTrigger(trigger); // restart trigger
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public func SetAction(new_action, new_action_progress_mode, new_action_allow_parallel)
|
||||
|
@ -394,6 +448,11 @@ public func StartTrigger()
|
|||
this.search_mask = Find_And(Find_InRect(trigger.Rect[0], trigger.Rect[1], trigger.Rect[2], trigger.Rect[3]), Find_OCF(OCF_Alive), Find_Func("IsClonk"), Find_Not(Find_Owner(NO_OWNER)));
|
||||
AddTimer(this.EnterRegionTimer, check_interval);
|
||||
}
|
||||
else if (fn == "enter_region_circle")
|
||||
{
|
||||
this.search_mask = Find_And(Find_Distance(trigger.Radius), Find_OCF(OCF_Alive), Find_Func("IsClonk"), Find_Not(Find_Owner(NO_OWNER)));
|
||||
AddTimer(this.EnterRegionTimer, check_interval);
|
||||
}
|
||||
else return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -440,6 +499,57 @@ private func OnActionFinished(context)
|
|||
return true;
|
||||
}
|
||||
|
||||
public func OnClonkDeath(object clonk, int killer)
|
||||
{
|
||||
// Is this a clonk death trigger?
|
||||
if (!trigger || !clonk) return false;
|
||||
var t = trigger.Trigger;
|
||||
if (!WildcardMatch(t, "*_clonk_death")) return false;
|
||||
// Specific trigger check
|
||||
if (t == "player_clonk_death")
|
||||
{
|
||||
if (clonk->GetOwner() == NO_OWNER) return false;
|
||||
}
|
||||
else if (t == "neutral_clonk_death")
|
||||
{
|
||||
if (clonk->GetOwner() != NO_OWNER) return false;
|
||||
}
|
||||
else if (t == "specific_clonk_death")
|
||||
{
|
||||
if (trigger.Object != clonk) return false;
|
||||
}
|
||||
// OK, trigger it!
|
||||
return OnTrigger(clonk, killer);
|
||||
}
|
||||
|
||||
public func OnConstructionFinished(object structure, int constructing_player)
|
||||
{
|
||||
// Is this a structure finished trigger?
|
||||
if (!trigger || !structure) return false;
|
||||
if (trigger.Trigger != "construction") return false;
|
||||
if (trigger.ID) if (structure->GetID() != trigger.ID) return false;
|
||||
// OK, trigger it!
|
||||
return OnTrigger(structure, constructing_player);
|
||||
}
|
||||
|
||||
public func OnProductionFinished(object product, int producing_player)
|
||||
{
|
||||
// Is this a structure finished trigger?
|
||||
if (!trigger || !product) return false;
|
||||
if (trigger.Trigger != "production") return false;
|
||||
if (trigger.ID) if (product->GetID() != trigger.ID) return false;
|
||||
// OK, trigger it!
|
||||
return OnTrigger(product, producing_player);
|
||||
}
|
||||
|
||||
public func OnGoalsFulfilled()
|
||||
{
|
||||
// All goals fulfilled: Return true if any action is executed (stops regular GameOver)
|
||||
if (!trigger) return false;
|
||||
if (trigger.Trigger != "goals_fulfilled") return false;
|
||||
return OnTrigger();
|
||||
}
|
||||
|
||||
/*-- Saving --*/
|
||||
|
||||
// No scenario saving.
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
Name=Sequenz
|
||||
Description=Erlaubt das Erstellen von Intros, Zwischensequenzen oder sonstigen Ereignissen.
|
||||
Test=Testen
|
||||
Active=Aktiv
|
||||
Finished=Sequenz beendet
|
||||
Trigger=Ausloeser
|
||||
None=Nichts
|
||||
EnterRegionRect=Spieler betritt Bereich (Rechteck)
|
||||
EnterRegionCircle=Spieler betritt Bereich (Radius)
|
||||
DeactivateAfterAction=Nur einmal ausfuehren
|
||||
GameStart=Spielstart
|
||||
PlayerJoin=Spielerbeitritt
|
||||
PlayerRemove=Spieler geloescht
|
||||
GoalsFulfilled=Alle Spielziele erfuellt
|
||||
ClonkDeath=Ein Clonk stirbt
|
||||
Construction=Konstruktion Gebaeude
|
||||
Anything=Beliebig
|
||||
Production=Produktion Objekt
|
||||
AnyClonkDeath=Beliebiger Clonk stirbt
|
||||
PlayerClonkDeath=Spielerclonk stirbt
|
||||
NeutralClonkDeath=Neutraler Clonk stirbt
|
||||
SpecificClonkDeath=Bestimmer Clonk stirbt...
|
|
@ -1,7 +1,22 @@
|
|||
Name=Sequence
|
||||
Description=Allows creation of intros, cutscenes or other events bound to triggers such as player joins, players entering regions or finished productions.
|
||||
Test=Test
|
||||
Active=Active
|
||||
Finished=Finished
|
||||
Trigger=Trigger
|
||||
None=None
|
||||
EnterRegionRect=Player enters region (rect)
|
||||
EnterRegionRect=Player enters region (rectangle)
|
||||
EnterRegionCircle=Player enters region (radius)
|
||||
DeactivateAfterAction=Run once only
|
||||
GameStart=Game start
|
||||
PlayerJoin=Player join
|
||||
PlayerRemove=Player deleted
|
||||
GoalsFulfilled=All goals fulfilled
|
||||
ClonkDeath=A clonk dies
|
||||
Construction=Construction of structure
|
||||
Anything=Anything
|
||||
Production=Production of item
|
||||
AnyClonkDeath=Any clonk dies
|
||||
PlayerClonkDeath=Player clonk dies
|
||||
NeutralClonkDeath=Neutral clonk dies
|
||||
SpecificClonkDeath=Specific clonk dies...
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
Test=Testen
|
||||
Active=Aktiv
|
||||
Finished=Sequenz beendet
|
||||
Trigger=Ausloeser
|
||||
None=Nichts
|
||||
EnterRegionRect=Spieler betritt Bereich
|
||||
DeactivateAfterAction=Nur einmal ausfuehren
|
|
@ -157,12 +157,13 @@ public func EvaluateAction(proplist props, object action_object, object triggeri
|
|||
context.temp = true;
|
||||
}
|
||||
// Prevent duplicate parallel execution
|
||||
if (!allow_parallel && (context.hold && !context.suspended)) return nil;
|
||||
if (!allow_parallel && (context.hold && !context.suspended)) return false;
|
||||
// Init context settings
|
||||
context->InitContext(action_object, triggering_player, triggering_object, props);
|
||||
// Execute action
|
||||
EvaluateValue("Action", props, context);
|
||||
FinishAction(context);
|
||||
return true;
|
||||
}
|
||||
|
||||
public func EvaluateCondition(proplist props, object action_object, object triggering_object, int triggering_player)
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include Library_PowerConsumer
|
||||
|
||||
// Production queue, a list of items to be produced.
|
||||
// Contains proplists of format {Product = <objid>, Amount = <int>, Infinite = (optional)<bool>}. /Infinite/ == true -> infinite production.
|
||||
// Contains proplists of format {Product = <objid>, Amount = <int>, Infinite = (optional)<bool>, ProducingPlayer = (optional)<int>}. /Infinite/ == true -> infinite production.
|
||||
local queue;
|
||||
|
||||
|
||||
|
@ -364,7 +364,7 @@ public func ModifyQueueIndex(int position, int amount, bool infinite_production)
|
|||
@param amount the amount of items of \c item_id which should be produced. Amount must not be negative.
|
||||
@paramt infinite whether to enable infinite production.
|
||||
*/
|
||||
public func AddToQueue(id product_id, int amount, bool infinite)
|
||||
public func AddToQueue(id product_id, int amount, bool infinite, int producing_player)
|
||||
{
|
||||
// Check if this producer can produce the requested item.
|
||||
if (!IsProduct(product_id))
|
||||
|
@ -384,7 +384,7 @@ public func AddToQueue(id product_id, int amount, bool infinite)
|
|||
|
||||
// Otherwise create a new entry in the queue.
|
||||
if (!found)
|
||||
PushBack(queue, { Product = product_id, Amount = amount, Infinite = infinite});
|
||||
PushBack(queue, { Product = product_id, Amount = amount, Infinite = infinite, ProducingPlayer=producing_player });
|
||||
// Notify all production menus open for this producer.
|
||||
UpdateInteractionMenus(this.GetProductionMenuEntries);
|
||||
}
|
||||
|
@ -429,7 +429,7 @@ private func ModifyProduction(proplist info, int player)
|
|||
|
||||
if (index == nil && (amount > 0 || infinite))
|
||||
{
|
||||
AddToQueue(product, amount, infinite);
|
||||
AddToQueue(product, amount, infinite, player);
|
||||
}
|
||||
else if (index != nil)
|
||||
{
|
||||
|
@ -471,8 +471,9 @@ private func ProcessQueue()
|
|||
|
||||
// Produce first item in the queue.
|
||||
var product_id = queue[0].Product;
|
||||
var producing_player = queue[0].ProducingPlayer;
|
||||
// Check raw material need.
|
||||
if (!Produce(product_id))
|
||||
if (!Produce(product_id, producing_player))
|
||||
{
|
||||
// No material available? request from cable network.
|
||||
RequestAllMissingComponents(product_id);
|
||||
|
@ -504,7 +505,7 @@ public func PowerNeed() { return 80; }
|
|||
public func GetConsumerPriority() { return 50; }
|
||||
|
||||
|
||||
private func Produce(id product)
|
||||
private func Produce(id product, producing_player)
|
||||
{
|
||||
// Already producing? Wait a little.
|
||||
if (IsProducing())
|
||||
|
@ -527,7 +528,7 @@ private func Produce(id product)
|
|||
CheckFuel(product, true);
|
||||
|
||||
// Add production effect.
|
||||
AddEffect("ProcessProduction", this, 100, 2, this, nil, product);
|
||||
AddEffect("ProcessProduction", this, 100, 2, this, nil, product, producing_player);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -636,13 +637,14 @@ private func IsProducing()
|
|||
}
|
||||
|
||||
|
||||
protected func FxProcessProductionStart(object target, proplist effect, int temporary, id product)
|
||||
protected func FxProcessProductionStart(object target, proplist effect, int temporary, id product, int producing_player)
|
||||
{
|
||||
if (temporary)
|
||||
return FX_OK;
|
||||
|
||||
// Set product.
|
||||
// Set product information
|
||||
effect.Product = product;
|
||||
effect.producing_player = producing_player;
|
||||
|
||||
// Set production duration to zero.
|
||||
effect.Duration = 0;
|
||||
|
@ -729,6 +731,8 @@ protected func FxProcessProductionStop(object target, proplist effect, int reaso
|
|||
// Create product.
|
||||
var product = CreateObject(effect.Product);
|
||||
OnProductEjection(product);
|
||||
// Global callback
|
||||
if (product) GameCallEx("OnProductionFinished", product, effect.producing_player);
|
||||
return FX_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -208,7 +208,7 @@ public func Collection2(object obj)
|
|||
|
||||
// check if we're done?
|
||||
if(full_material)
|
||||
StartConstructing();
|
||||
StartConstructing(obj->GetController());
|
||||
}
|
||||
|
||||
// component removed (e.g.: Contained wood burned down or some externel scripts went havoc)
|
||||
|
@ -267,7 +267,7 @@ private func GetMissingComponents()
|
|||
return missing_material;
|
||||
}
|
||||
|
||||
private func StartConstructing()
|
||||
private func StartConstructing(int by_player)
|
||||
{
|
||||
if(!definition)
|
||||
return;
|
||||
|
@ -308,6 +308,7 @@ private func StartConstructing()
|
|||
// If not: Autoconstruct 2.0!
|
||||
Schedule(site, "DoCon(2)",1,50);
|
||||
Schedule(this,"RemoveObject()",1);
|
||||
Global->ScheduleCall(nil, Global.GameCallEx, 51, 1, "OnConstructionFinished", site, by_player);
|
||||
site->Sound("Structures::FinishBuilding");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue