forked from Mirrors/openclonk
93 lines
3.3 KiB
C
93 lines
3.3 KiB
C
/*
|
|
Small Piranha
|
|
Author: Zapper
|
|
*/
|
|
|
|
#include Piranha
|
|
|
|
local SwimMaxAngle = 10;
|
|
local SwimMaxSpeed = 25;
|
|
local VisionMaxAngle = 140;
|
|
local VisionMaxRange = 100;
|
|
|
|
// Make this one a bit smaller than the original piranha.
|
|
local BaseScale = -200;
|
|
local BiteStrength = 5;
|
|
|
|
public func Construction()
|
|
{
|
|
inherited(...);
|
|
SetGraphics(nil, Piranha);
|
|
SetMeshMaterial("PiranhaSmall");
|
|
}
|
|
|
|
private func InitFuzzyRules()
|
|
{
|
|
brain = FuzzyLogic->Init();
|
|
|
|
// ACTION SETS
|
|
brain->AddSet("swim", "sharp_left", [[-2 * SwimMaxAngle, 1], [-SwimMaxAngle, 0], [SwimMaxAngle, 0]]);
|
|
brain->AddSet("swim", "left", [[-SwimMaxAngle, 1], [-SwimMaxAngle/2, 0], [SwimMaxAngle, 0]]);
|
|
brain->AddSet("swim", "straight", [[-5, 0], [0, 1], [5, 0]]);
|
|
brain->AddSet("swim", "right", [[-SwimMaxAngle, 0], [SwimMaxAngle/2, 0], [SwimMaxAngle, 1]]);
|
|
brain->AddSet("swim", "sharp_right", [[-SwimMaxAngle, 0], [SwimMaxAngle, 0], [2 * SwimMaxAngle, 1]]);
|
|
|
|
brain->AddSet("speed", "slow", [[0, 1], [2 * SwimMaxSpeed / 3, 0], [SwimMaxSpeed, 0]]);
|
|
brain->AddSet("speed", "fast", [[0, 0], [SwimMaxSpeed/2, 0], [SwimMaxSpeed, 1]]);
|
|
|
|
// RULE SETS
|
|
var directional_sets = ["friend", "food"];
|
|
|
|
for (var set in directional_sets)
|
|
{
|
|
brain->AddSet(set, "left", [[-VisionMaxAngle, 1], [0, 0], [VisionMaxAngle, 0]]);
|
|
brain->AddSet(set, "straight", [[-5, 0], [0, 1], [5, 0]]);
|
|
brain->AddSet(set, "right", [[-VisionMaxAngle, 0], [0, 0], [VisionMaxAngle, 1]]);
|
|
}
|
|
|
|
// For the food, we allow further vision.
|
|
var far = VisionMaxRange;
|
|
var middle = VisionMaxRange / 2;
|
|
brain->AddSet("food_range", "far", [[middle, 0], [far, 1], [far, 1]]);
|
|
brain->AddSet("food_range", "medium", [[0, 0], [middle, 1], [far, 0]]);
|
|
brain->AddSet("food_range", "close", [[0, 1], [0, 1], [middle, 0]]);
|
|
|
|
brain->AddSet("left_wall", "close", [[0, 1], [0, 1], [wall_vision_range/2, 0]]);
|
|
brain->AddSet("right_wall", "close", [[0, 1], [0, 1], [wall_vision_range/2, 0]]);
|
|
brain->AddSet("wall_range", "close", [[0, 1], [0, 1], [wall_vision_range, 0]]);
|
|
|
|
brain->AddSet("hunger", "low", [[0, 1], [0, 1], [75, 0]]);
|
|
brain->AddSet("hunger", "high", [[25, 0], [100, 1], [100, 1]]);
|
|
|
|
// RULES
|
|
brain->AddRule(brain->Or(brain->And("hunger=high", "food=right"), brain->And("food_range=far", "friend=right")), "swim=right");
|
|
brain->AddRule(brain->Or(brain->And("hunger=high", "food=left"), brain->And("food_range=far", "friend=left")), "swim=left");
|
|
brain->AddRule(brain->Not("food_range=far"), "speed=fast");
|
|
brain->AddRule(brain->Or("wall_range=close", "hunger=low"), "speed=slow");
|
|
brain->AddRule(brain->And("left_wall=close", brain->Not("right_wall=close")), "swim=sharp_right");
|
|
brain->AddRule("right_wall=close", "swim=sharp_left");
|
|
}
|
|
|
|
|
|
private func UpdateVision()
|
|
{
|
|
brain->Fuzzify("hunger", hunger);
|
|
UpdateVisionFor("food", "food_range", FindObjects(Find_Distance(VisionMaxRange), Find_OCF(OCF_Alive), Find_Func("IsPrey"), Find_NoContainer(), Sort_Distance()), true);
|
|
UpdateVisionFor("friend", nil, FindObjects(Find_Distance(VisionMaxRange), Find_ID(GetID()), Find_Exclude(this), Find_NoContainer(), Sort_Distance()));
|
|
UpdateWallVision();
|
|
}
|
|
|
|
private func BiteEffect()
|
|
{
|
|
Sound("Animals::Fish::Munch*", nil, nil, nil, nil, nil, 100);
|
|
}
|
|
|
|
local Name = "$Name$";
|
|
local Description = "$Description$";
|
|
local MaxEnergy = 25000;
|
|
|
|
public func Definition(def)
|
|
{
|
|
SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(20,1,0,0),Trans_Rotate(70,0,1,0)), def);
|
|
}
|