added smaller variation of the piranha (new Piranha texture by Matthi)

shapetextures
David Dormagen 2015-10-22 10:57:14 +02:00
parent c7a0f2b580
commit 08c51288ad
12 changed files with 203 additions and 58 deletions

View File

@ -3,10 +3,10 @@
Author: Zapper
*/
static const FISH_SWIM_MAX_ANGLE = 15;
static const FISH_SWIM_MAX_SPEED = 30;
static const FISH_VISION_MAX_ANGLE = 140;
static const FISH_VISION_MAX_RANGE = 200;
local SwimMaxAngle = 15;
local SwimMaxSpeed = 30;
local VisionMaxAngle = 140;
local VisionMaxRange = 200;
local walking, swimming;
local current_angle, current_speed, current_direction;
@ -42,6 +42,7 @@ func Place(int amount, proplist rectangle, proplist settings)
else if (!Random(3))
f->SetYZScale(400+Random(600));
}
if (f->Stuck())
{
f->RemoveObject();
@ -57,7 +58,7 @@ func Construction()
// general stuff
StartGrowth(15);
current_angle = Random(360);
current_speed = RandomX(FISH_SWIM_MAX_SPEED/5, FISH_SWIM_MAX_SPEED);
current_speed = RandomX(SwimMaxSpeed/5, SwimMaxSpeed);
var len = GetAnimationLength("Swim");
swim_animation = PlayAnimation("Swim", 5, Anim_Linear(0, 0, len, 100, ANIM_Loop), Anim_Const(500));
@ -119,36 +120,36 @@ func InitFuzzyRules()
brain = FuzzyLogic->Init();
// ACTION SETS
brain->AddSet("swim", "left", [[-FISH_SWIM_MAX_ANGLE, 1], [-FISH_SWIM_MAX_ANGLE/2, 0], [FISH_SWIM_MAX_ANGLE, 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", [[-FISH_SWIM_MAX_ANGLE, 0], [FISH_SWIM_MAX_ANGLE/2, 0], [FISH_SWIM_MAX_ANGLE, 1]]);
brain->AddSet("swim", "right", [[-SwimMaxAngle, 0], [SwimMaxAngle/2, 0], [SwimMaxAngle, 1]]);
brain->AddSet("speed", "slow", [[0, 1], [FISH_SWIM_MAX_SPEED/2, 0], [FISH_SWIM_MAX_SPEED, 0]]);
brain->AddSet("speed", "fast", [[0, 0], [FISH_SWIM_MAX_SPEED/2, 0], [FISH_SWIM_MAX_SPEED, 1]]);
brain->AddSet("speed", "slow", [[0, 1], [SwimMaxSpeed/2, 0], [SwimMaxSpeed, 0]]);
brain->AddSet("speed", "fast", [[0, 0], [SwimMaxSpeed/2, 0], [SwimMaxSpeed, 1]]);
// RULE SETS
var directional_sets = ["friend", "enemy", "food", "wall"];
for (var set in directional_sets)
{
brain->AddSet(set, "left", [[-FISH_VISION_MAX_ANGLE, 1], [0, 0], [FISH_VISION_MAX_ANGLE, 0]]);
brain->AddSet(set, "left", [[-VisionMaxAngle, 1], [0, 0], [VisionMaxAngle, 0]]);
brain->AddSet(set, "straight", [[-5, 0], [0, 1], [5, 0]]);
brain->AddSet(set, "right", [[-FISH_VISION_MAX_ANGLE, 0], [0, 0], [FISH_VISION_MAX_ANGLE, 1]]);
brain->AddSet(set, "right", [[-VisionMaxAngle, 0], [0, 0], [VisionMaxAngle, 1]]);
}
var proximity_sets = ["friend_range", "enemy_range", "food_range"];
var middle = FISH_VISION_MAX_RANGE / 2;
var quarter = FISH_VISION_MAX_RANGE / 4;
var middle = VisionMaxRange / 2;
var quarter = VisionMaxRange / 4;
for (var set in proximity_sets)
{
brain->AddSet(set, "far", [[middle, 0], [FISH_VISION_MAX_RANGE, 1], [FISH_VISION_MAX_RANGE, 1]]);
brain->AddSet(set, "medium", [[0, 0], [middle, 1], [FISH_VISION_MAX_RANGE, 0]]);
brain->AddSet(set, "far", [[middle, 0], [VisionMaxRange, 1], [VisionMaxRange, 1]]);
brain->AddSet(set, "medium", [[0, 0], [middle, 1], [VisionMaxRange, 0]]);
brain->AddSet(set, "close", [[0, 1], [0, 1], [middle, 0]]);
}
brain->AddSet("wall_range", "far", [[middle, 0], [FISH_VISION_MAX_RANGE, 1], [FISH_VISION_MAX_RANGE, 1]]);
brain->AddSet("wall_range", "medium", [[0, 0], [middle, 1], [FISH_VISION_MAX_RANGE, 0]]);
brain->AddSet("wall_range", "far", [[middle, 0], [VisionMaxRange, 1], [VisionMaxRange, 1]]);
brain->AddSet("wall_range", "medium", [[0, 0], [middle, 1], [VisionMaxRange, 0]]);
brain->AddSet("wall_range", "close", [[0, 1], [0, 1], [quarter, 0]]);
// RULES
@ -210,9 +211,9 @@ func Activity()
func UpdateVision()
{
UpdateVisionFor("enemy", "enemy_range", FindObjects(Find_Distance(FISH_VISION_MAX_RANGE), Find_OCF(OCF_Alive), Find_Or(Find_Func("IsPredator"), Find_Func("IsClonk")), Find_NoContainer(), Sort_Distance()));
UpdateVisionFor("friend", "friend_range", FindObjects(Find_Distance(FISH_VISION_MAX_RANGE), Find_ID(GetID()), Find_Exclude(this), Find_NoContainer(), Sort_Distance()));
UpdateVisionFor("food", "food_range", FindObjects(Find_Distance(FISH_VISION_MAX_RANGE), Find_Func("NutritionalValue"), Find_NoContainer(), Sort_Distance()), true);
UpdateVisionFor("enemy", "enemy_range", FindObjects(Find_Distance(VisionMaxRange), Find_OCF(OCF_Alive), Find_Or(Find_Func("IsPredator"), Find_Func("IsClonk")), Find_NoContainer(), Sort_Distance()));
UpdateVisionFor("friend", "friend_range", FindObjects(Find_Distance(VisionMaxRange), Find_ID(GetID()), Find_Exclude(this), Find_NoContainer(), Sort_Distance()));
UpdateVisionFor("food", "food_range", FindObjects(Find_Distance(VisionMaxRange), Find_Func("NutritionalValue"), Find_NoContainer(), Sort_Distance()), true);
UpdateWallVision();
}
@ -224,7 +225,7 @@ func UpdateVisionFor(string set, string range_set, array objects, bool is_food)
if (!PathFree(GetX(), GetY(), obj->GetX(), obj->GetY())) continue;
var angle = Angle(GetX(), GetY(), obj->GetX(), obj->GetY());
var d = GetTurnDirection(current_angle, angle);
if (!Inside(d, -FISH_VISION_MAX_ANGLE, FISH_VISION_MAX_ANGLE)) continue;
if (!Inside(d, -VisionMaxAngle, VisionMaxAngle)) continue;
// prevent piranhas to jump out of the water to eat unsuspecting Clonks
if (is_food && (obj->GetMaterial() != GetMaterial())) continue;
@ -233,7 +234,8 @@ func UpdateVisionFor(string set, string range_set, array objects, bool is_food)
//this->Message("%s@%d (me %d, it %d)", obj->GetName(), d, current_angle, angle);
var distance = ObjectDistance(this, obj);
brain->Fuzzify(set, d);
brain->Fuzzify(range_set, distance);
if (range_set != nil)
brain->Fuzzify(range_set, distance);
// now that we fuzzified our food - can we actually eat it, too???
if (is_food && distance < GetCon()/10)
@ -243,7 +245,8 @@ func UpdateVisionFor(string set, string range_set, array objects, bool is_food)
}
brain->Fuzzify(set, 0);
brain->Fuzzify(range_set, FISH_VISION_MAX_RANGE + 1);
if (range_set != nil)
brain->Fuzzify(range_set, VisionMaxRange + 1);
return false;
}
@ -253,14 +256,14 @@ func UpdateWallVision()
// asses direction of wall
var closest = 0;
var closest_distance = FISH_VISION_MAX_RANGE;
//for (var angle = -FISH_VISION_MAX_ANGLE/3; angle <= FISH_VISION_MAX_ANGLE; angle += FISH_VISION_MAX_ANGLE/3)
var closest_distance = VisionMaxRange;
//for (var angle = -VisionMaxAngle/3; angle <= VisionMaxAngle; angle += VisionMaxAngle/3)
var angle = -FISH_VISION_MAX_ANGLE/5;
var angle = -VisionMaxAngle/5;
do
{
// quickly check solid point
var max = FISH_VISION_MAX_RANGE/3;
var max = VisionMaxRange/3;
var px, py;
for (var d = 5; d <= max; d += 20)
{
@ -275,8 +278,8 @@ func UpdateWallVision()
break;
}
/*var px = Sin(current_angle + angle, FISH_VISION_MAX_RANGE);
var py = -Cos(current_angle + angle, FISH_VISION_MAX_RANGE);
/*var px = Sin(current_angle + angle, VisionMaxRange);
var py = -Cos(current_angle + angle, VisionMaxRange);
var point = PathFree2(GetX(), GetY(), GetX() + px, GetY() + py);
*/
if (!px && !py) { angle *= -1; continue; }
@ -290,7 +293,7 @@ func UpdateWallVision()
}
while (angle > 0);
if (closest_distance == FISH_VISION_MAX_RANGE)
if (closest_distance == VisionMaxRange)
{
// check for material in front, happens occasionally
var d = 5;
@ -321,7 +324,7 @@ func UpdateSwim()
var len = GetAnimationLength("Swim");
var pos = GetAnimationPosition(swim_animation);
SetAnimationPosition(swim_animation, Anim_Linear(pos, 0, len, FISH_SWIM_MAX_SPEED - current_speed + 1, ANIM_Loop));
SetAnimationPosition(swim_animation, Anim_Linear(pos, 0, len, SwimMaxSpeed - current_speed + 1, ANIM_Loop));
var t = current_angle - 270;
var t2 = Cos(t, 90) - 90; // Expand the areas around 0deg and 180deg a bit so you see fish from the side more

View File

@ -3,14 +3,14 @@ id=Piranha
Version=6,0
Category=C4D_Living
ContactCalls=1
Width=6
Height=4
Offset=-3,-2
Width=8
Height=6
Offset=-4,-3
Value=1
Mass=1
Vertices=4
VertexX=0,0,-3,3
VertexY=-2,2,0,0
VertexX=0,0,-4,4
VertexY=-3,3,0,0
VertexCNAT=4,8,1,2
VertexFriction=100,100,100,100,100,100
BorderBound=7

View File

@ -1,5 +1,3 @@
// PiranhaMaterial genrated by blender2ogre 0.6.0
material PiranhaMaterial
{
receive_shadows on
@ -21,7 +19,7 @@ material PiranhaMaterial
texture_unit
{
texture piranha_color.png
texture piranha_color.jpg
tex_address_mode wrap
scale 1.0 1.0
colour_op modulate
@ -29,3 +27,17 @@ material PiranhaMaterial
}
}
}
material PiranhaSmall : PiranhaMaterial
{
technique 0
{
pass PiranhaMaterial
{
texture_unit 0
{
texture piranha_small_color.png
}
}
}
}

View File

@ -5,12 +5,19 @@
#include Fish
// Default additional scaling for the mesh.
local BaseScale = +200;
// Damage per bite.
local BiteStrength = 10;
local hunger;
func Construction()
{
hunger = 0;
AddTimer("MoreHunger", 80);
// Set base transform (can be overwritten by e.g. Place()).
SetYZScale(1000);
_inherited(...);
}
@ -25,36 +32,36 @@ func InitFuzzyRules()
brain = FuzzyLogic->Init();
// ACTION SETS
brain->AddSet("swim", "left", [[-FISH_SWIM_MAX_ANGLE, 1], [-FISH_SWIM_MAX_ANGLE/2, 0], [FISH_SWIM_MAX_ANGLE, 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", [[-FISH_SWIM_MAX_ANGLE, 0], [FISH_SWIM_MAX_ANGLE/2, 0], [FISH_SWIM_MAX_ANGLE, 1]]);
brain->AddSet("swim", "right", [[-SwimMaxAngle, 0], [SwimMaxAngle/2, 0], [SwimMaxAngle, 1]]);
brain->AddSet("speed", "slow", [[0, 1], [FISH_SWIM_MAX_SPEED/2, 0], [FISH_SWIM_MAX_SPEED, 0]]);
brain->AddSet("speed", "fast", [[0, 0], [FISH_SWIM_MAX_SPEED/2, 0], [FISH_SWIM_MAX_SPEED, 1]]);
brain->AddSet("speed", "slow", [[0, 1], [SwimMaxSpeed/2, 0], [SwimMaxSpeed, 0]]);
brain->AddSet("speed", "fast", [[0, 0], [SwimMaxSpeed/2, 0], [SwimMaxSpeed, 1]]);
// RULE SETS
var directional_sets = ["food", "wall"];
for (var set in directional_sets)
{
brain->AddSet(set, "left", [[-FISH_VISION_MAX_ANGLE, 1], [0, 0], [FISH_VISION_MAX_ANGLE, 0]]);
brain->AddSet(set, "left", [[-VisionMaxAngle, 1], [0, 0], [VisionMaxAngle, 0]]);
brain->AddSet(set, "straight", [[-5, 0], [0, 1], [5, 0]]);
brain->AddSet(set, "right", [[-FISH_VISION_MAX_ANGLE, 0], [0, 0], [FISH_VISION_MAX_ANGLE, 1]]);
brain->AddSet(set, "right", [[-VisionMaxAngle, 0], [0, 0], [VisionMaxAngle, 1]]);
}
var proximity_sets = ["food_range"];
var middle = FISH_VISION_MAX_RANGE / 2;
var quarter = FISH_VISION_MAX_RANGE / 4;
var middle = VisionMaxRange / 2;
var quarter = VisionMaxRange / 4;
for (var set in proximity_sets)
{
brain->AddSet(set, "far", [[middle, 0], [FISH_VISION_MAX_RANGE, 1], [FISH_VISION_MAX_RANGE, 1]]);
brain->AddSet(set, "medium", [[0, 0], [middle, 1], [FISH_VISION_MAX_RANGE, 0]]);
brain->AddSet(set, "far", [[middle, 0], [VisionMaxRange, 1], [VisionMaxRange, 1]]);
brain->AddSet(set, "medium", [[0, 0], [middle, 1], [VisionMaxRange, 0]]);
brain->AddSet(set, "close", [[0, 1], [0, 1], [middle, 0]]);
}
brain->AddSet("wall_range", "far", [[middle, 0], [FISH_VISION_MAX_RANGE, 1], [FISH_VISION_MAX_RANGE, 1]]);
brain->AddSet("wall_range", "medium", [[0, 0], [middle, 1], [FISH_VISION_MAX_RANGE, 0]]);
brain->AddSet("wall_range", "far", [[middle, 0], [VisionMaxRange, 1], [VisionMaxRange, 1]]);
brain->AddSet("wall_range", "medium", [[0, 0], [middle, 1], [VisionMaxRange, 0]]);
brain->AddSet("wall_range", "close", [[0, 1], [0, 1], [quarter, 0]]);
@ -73,22 +80,34 @@ func InitFuzzyRules()
func UpdateVision()
{
brain->Fuzzify("hunger", hunger);
UpdateVisionFor("food", "food_range", FindObjects(Find_Distance(FISH_VISION_MAX_RANGE), Find_OCF(OCF_Alive), Find_Func("IsPrey"), Find_NoContainer(), Sort_Distance()), true);
UpdateVisionFor("food", "food_range", FindObjects(Find_Distance(VisionMaxRange), Find_OCF(OCF_Alive), Find_Func("IsPrey"), Find_NoContainer(), Sort_Distance()), true);
UpdateWallVision();
}
func DoEat(object obj)
{
Sound("FishMunch*");
BiteEffect();
var len = GetAnimationLength("Bite");
PlayAnimation("Bite", 5, Anim_Linear(0, 0, len, 36, ANIM_Remove), Anim_Const(1000));
if (obj->GetAlive())
obj->DoEnergy(-5);
hunger -= 10;
obj->DoEnergy(-BiteStrength);
hunger -= 20;
if (hunger < 0) hunger = 0;
//CastParticles("MaterialParticle", 10, 10, 0, 0, 10, 20, RGB(200, 5, 5), RGB(200, 5, 5));
DoEnergy(5);
DoEnergy(BiteStrength);
}
private func BiteEffect()
{
Sound("FishMunch*");
}
// Make this piranha a little larger than the mesh.
func SetYZScale(int new_scale)
{
base_transform = Trans_Scale(1000 + BaseScale, new_scale + BaseScale, new_scale + BaseScale);
return true;
}
local Name = "$Name$";

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,20 @@
[DefCore]
id=PiranhaSmall
Version=6,0
Category=C4D_Living
ContactCalls=1
Width=4
Height=2
Offset=-2,-1
Value=1
Mass=1
Vertices=4
VertexX=0,0,-2,2
VertexY=-1,1,0,0
VertexCNAT=4,8,1,2
VertexFriction=100,100,100,100,100,100
BorderBound=7
StretchGrowth=1
IncompleteActivity=1
Oversize=1
Float=1

View File

@ -0,0 +1,86 @@
/*
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", "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("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", "wall"];
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("wall_range", "close", [[0, 1], [0, 1], [far, 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("wall_range=close", "wall=left"), brain->And("hunger=high", "food=right"), brain->And("food_range=far", "friend=right")), "swim=right");
brain->AddRule(brain->Or(brain->And("wall_range=close", "wall=right"), 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");
}
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("FishMunch*", 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);
}

View File

@ -0,0 +1,2 @@
Name=Kleiner Piranha
Description=Durch die kleinere Größe jagt dieser Piranha lieber in Schwärmen.

View File

@ -0,0 +1,2 @@
Name=Small Piranha
Description=Due to the smaller size, this piranha hunts in swarms.

View File

@ -3,8 +3,9 @@ func Initialize()
{
Fish->Place(20, Shape->Rectangle(0, 0, LandscapeWidth() / 2 - 50, LandscapeHeight()));
Squid->Place(10, Shape->Rectangle(0, 0, LandscapeWidth() / 2 - 50, LandscapeHeight()));
Piranha->Place(20, Shape->Rectangle(LandscapeWidth() / 2 + 50, 0, LandscapeWidth(), LandscapeHeight()));
Squid->Place(10, Shape->Rectangle(LandscapeWidth() / 2 + 50, 0, LandscapeWidth(), LandscapeHeight()), {friendly = false});
Piranha->Place(10, Shape->Rectangle(LandscapeWidth() / 2 + 50, 0, LandscapeWidth(), LandscapeHeight()));
PiranhaSmall->Place(20, Shape->Rectangle(LandscapeWidth() / 2 + 50, 0, LandscapeWidth(), LandscapeHeight()));
Squid->Place(5, Shape->Rectangle(LandscapeWidth() / 2 + 50, 0, LandscapeWidth(), LandscapeHeight()), {friendly = false});
Seaweed->Place(20);
Coral->Place(30);