openclonk/planet/Objects.ocd/Animals.ocd/Butterfly.ocd/Script.c

224 lines
5.0 KiB
C
Raw Normal View History

2010-03-01 22:16:53 +00:00
/*
Butterfly
2015-07-23 11:31:23 +00:00
Author: Randrian, Ringwaul, Clonkonaut
2010-03-01 22:16:53 +00:00
A small fluttering being.
*/
2015-07-23 11:31:23 +00:00
#include Library_Insect
2016-01-27 04:14:17 +00:00
local fly_anim, fly_anim_len;
2011-05-31 18:36:01 +00:00
2016-01-27 04:14:17 +00:00
public func Construction(...)
2010-03-01 22:16:53 +00:00
{
2016-01-27 04:14:17 +00:00
StartGrowth(15);
fly_anim_len = GetAnimationLength("Fly");
fly_anim = PlayAnimation("Fly", 1, Anim_Linear(0,0, fly_anim_len, 10, ANIM_Loop));
2015-07-23 11:31:23 +00:00
this.MeshTransformation = Trans_Rotate(270,1,1,1);
SetAction("Fly");
2015-07-23 11:31:23 +00:00
// Make butterflies a bit more colorful.
SetClrModulation(HSL(Random(256), 255, 100 + Random(60)));
2015-07-23 11:31:23 +00:00
lib_insect_max_dist = 300;
lib_insect_shy = true;
2016-01-27 04:14:17 +00:00
return _inherited(...);
2010-03-01 22:16:53 +00:00
}
2011-05-31 18:36:01 +00:00
2015-07-23 11:31:23 +00:00
/* Insect library */
local attraction;
private func GetAttraction(proplist coordinates)
2011-05-31 18:36:01 +00:00
{
2015-07-23 11:31:23 +00:00
// Sometimes I don't want to fly to a plant
if (!Random(7)) return false;
for (var plant in FindObjects(Find_Distance(150), Find_Or(Find_Func("IsPlant"), Find_ID(Grass)), Sort_Distance()))
{
if (!Random(4))
continue;
if (ObjectDistance(plant) < 20) // Too close
continue;
if (plant->GetCon() < 30) // Too small
continue;
if (plant->GBackSemiSolid()) // Under water or covered with solid material
continue;
2015-07-23 11:31:23 +00:00
var width = plant->GetObjWidth();
var height = plant->GetObjHeight();
coordinates.x = plant->GetX() + Random(width) - width / 2;
// The butterfly assumes that the main part of a plant is in the upper half (below could just be the trunk)
coordinates.y = plant->GetY() - Random(height)/2;
attraction = plant;
return true;
}
return false;
2011-05-31 18:36:01 +00:00
}
2015-07-23 11:31:23 +00:00
private func MissionComplete()
2010-03-01 22:16:53 +00:00
{
if (!attraction) return _inherited(...);
2015-07-23 11:31:23 +00:00
var wait = 20 + Random(80);
// Slow animation speed
fly_anim = PlayAnimation("Fly", 1, Anim_Linear(GetAnimationPosition(fly_anim), 0, fly_anim_len, 20, ANIM_Loop));
2015-07-23 11:31:23 +00:00
ScheduleCall(this, "RegularSpeed", wait);
SetCommand("Wait", nil,nil,nil,nil, wait);
2010-03-01 22:16:53 +00:00
}
2015-07-23 11:31:23 +00:00
private func MissionCompleteFailed()
{
attraction = nil;
}
2010-03-01 22:16:53 +00:00
2015-07-23 11:31:23 +00:00
private func RegularSpeed()
2011-05-31 18:36:01 +00:00
{
fly_anim = PlayAnimation("Fly", 1, Anim_Linear(GetAnimationPosition(fly_anim), 0, fly_anim_len, 10, ANIM_Loop));
2011-05-31 18:36:01 +00:00
}
2015-07-23 11:31:23 +00:00
// Hold the animation
private func SleepComplete()
2010-03-01 22:16:53 +00:00
{
fly_anim = PlayAnimation("Fly", 1, Anim_Linear(GetAnimationPosition(fly_anim), 0, fly_anim_len/2, 10, ANIM_Hold));
_inherited(...);
2010-03-01 22:16:53 +00:00
}
2015-07-23 11:31:23 +00:00
// Restart the animation
private func WakeUp()
2010-03-01 22:16:53 +00:00
{
fly_anim = PlayAnimation("Fly", 1, Anim_Linear(GetAnimationPosition(fly_anim), 0, fly_anim_len, 10, ANIM_Loop));
_inherited(...);
2010-03-01 22:16:53 +00:00
}
2015-07-23 11:31:23 +00:00
private func GetRestingPlace(proplist coordinates)
2010-03-01 22:16:53 +00:00
{
2015-07-23 11:31:23 +00:00
// Try to rest in nearby grass
for (var grass in FindObjects(Find_Distance(150), Find_ID(Grass), Sort_Distance()))
{
if (!Random(2))
{
coordinates.x = grass->GetX() + Random(4) - 2;
coordinates.y = grass->GetY() + 2;
return true;
}
2015-07-23 11:31:23 +00:00
}
return false;
2010-03-01 22:16:53 +00:00
}
2016-01-27 04:14:17 +00:00
private func Death(...)
2015-07-23 16:18:52 +00:00
{
2016-01-27 04:14:17 +00:00
_inherited(...);
fly_anim = PlayAnimation("Fly", 1, Anim_Linear(GetAnimationPosition(fly_anim), 0, fly_anim_len/2, 10, ANIM_Hold));
2015-07-23 16:18:52 +00:00
SetAction("Dead");
}
2015-07-23 11:31:23 +00:00
/* Movement */
private func CheckTurn()
2010-03-01 22:16:53 +00:00
{
2015-07-23 11:31:23 +00:00
if (GetEffect("Turning", this)) return;
if (GetDir() == DIR_Left && GetXDir() > 0)
AddEffect("Turning", this, 100, 1, this);
if (GetDir() == DIR_Right && GetXDir() < 0)
AddEffect("Turning", this, 100, 1, this);
2010-03-01 22:16:53 +00:00
}
2015-07-23 11:31:23 +00:00
private func FxTurningStart(object target, proplist effect, int temp)
2010-03-01 22:16:53 +00:00
{
2015-07-23 11:31:23 +00:00
if (temp) return;
effect.turn = 15;
effect.step = 0;
if (GetDir() == DIR_Right)
{
effect.turn = -15;
effect.step = 360;
}
SetAction("SlowFly");
2010-03-01 22:16:53 +00:00
}
2015-07-23 11:31:23 +00:00
private func FxTurningTimer(object target, proplist effect)
2010-03-01 22:16:53 +00:00
{
2015-07-23 11:31:23 +00:00
effect.step += effect.turn;
if (effect.step == 0 || effect.step == 360) return FX_Execute_Kill;
if (effect.step == 90)
{
effect.step = 285;
SetDir(DIR_Right);
}
if (effect.step == 270)
{
effect.step = 75;
SetDir(DIR_Left);
}
this.MeshTransformation = Trans_Mul(Trans_Rotate(270,1,1,1), Trans_Rotate(effect.step,0,0,1));
return FX_OK;
2010-03-01 22:16:53 +00:00
}
2015-07-23 11:31:23 +00:00
private func FxTurningStop(object target, proplist effect, int reason, bool temp)
2010-03-01 22:16:53 +00:00
{
2015-07-23 11:31:23 +00:00
if (temp) return;
this.MeshTransformation = Trans_Rotate(270,1,1,1);
SetAction("Fly");
2010-03-01 22:16:53 +00:00
}
2015-07-23 11:31:23 +00:00
/* Definition */
func SaveScenarioObject(props)
{
if (!inherited(props, ...)) return false;
props->Remove("ClrModulation"); // randomized in Initialize
SaveScenarioObjectAction(props);
return true;
}
local ActMap = {
2015-07-23 11:31:23 +00:00
Fly = {
Prototype = Action,
Name = "Fly",
Procedure = DFA_FLOAT,
Speed = 100,
Accel = 16,
Decel = 16,
Directions = 2,
FlipDir = 1,
Length = 1,
Delay = 1,
NextAction = "Fly",
StartCall = "CheckTurn",
},
SlowFly = {
Prototype = Action,
Name = "SlowFly",
Procedure = DFA_FLOAT,
Speed = 30,
Accel = 6,
Decel = 6,
Directions = 2,
FlipDir = 1,
Length = 1,
Delay = 1,
NextAction = "SlowFly",
},
2015-07-23 16:18:52 +00:00
Dead = {
Prototype = Action,
Name = "Dead",
Directions = 2,
FlipDir = 1,
Length = 1,
Delay = 1,
NoOtherAction = 1,
},
};
2015-07-23 11:31:23 +00:00
local Name = "Butterfly";
local MaxEnergy = 40000;
local MaxBreath = 125;
local Placement = 2;
2017-11-11 08:49:52 +00:00
local NoBurnDecay = true;
local BorderBound = C4D_Border_Sides | C4D_Border_Top | C4D_Border_Bottom;
local ContactCalls = true;
2010-03-01 22:16:53 +00:00
2016-10-01 11:26:41 +00:00
public func Definition(proplist def)
{
def.PictureTransformation = Trans_Mul(Trans_Translate(400, 600, 0), Trans_Scale(1400), Trans_Rotate(20, 1, 0, 0), Trans_Rotate(40, 0, 1, 0));
2010-03-27 10:55:26 +00:00
}