forked from Mirrors/openclonk
New swarming insect: Mosquito!
Purely for decoration (no stinging). Mosquitos are nocturnal if you ever wonder.Controls
parent
3ce3d3604d
commit
c813743018
|
@ -0,0 +1,2 @@
|
|||
MosquitoBuzz.ogg by Zywx, License: CC-0
|
||||
http://www.freesound.org/people/Zywx/sounds/188708/
|
|
@ -0,0 +1,16 @@
|
|||
[DefCore]
|
||||
id=Mosquito
|
||||
Version=6,1
|
||||
Category=C4D_Living
|
||||
ContactCalls=1
|
||||
Width=2
|
||||
Height=2
|
||||
Offset=-1,-1
|
||||
Mass=1
|
||||
Vertices=4
|
||||
VertexX=0,0,-1,1
|
||||
VertexY=-1,1,0,0
|
||||
VertexCNAT=4,8,1,2
|
||||
VertexFriction=100,100,100,100
|
||||
Float=1
|
||||
BorderBound=7
|
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
Binary file not shown.
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
Mosquito
|
||||
Author: Clonkonaut
|
||||
|
||||
A small annoying being.
|
||||
*/
|
||||
|
||||
#include Library_Insect
|
||||
#include Library_InsectSwarm
|
||||
|
||||
local lib_swarm_standard = 20;
|
||||
local lib_insect_max_dist = 50;
|
||||
local lib_insect_nocturnal = true;
|
||||
|
||||
protected func Initialize()
|
||||
{
|
||||
SetAction("Fly");
|
||||
SetPhase(Random(3));
|
||||
|
||||
_inherited();
|
||||
}
|
||||
|
||||
private func Death()
|
||||
{
|
||||
_inherited();
|
||||
RemoveObject();
|
||||
}
|
||||
|
||||
private func MissionComplete()
|
||||
{
|
||||
if (IsDay()) return;
|
||||
|
||||
// Mosquitos are very active
|
||||
MoveToTarget();
|
||||
// Little dipshits
|
||||
}
|
||||
|
||||
private func Sleep()
|
||||
{
|
||||
if (lib_insect_sleeping) return;
|
||||
|
||||
if (lib_insect_going2sleep)
|
||||
{
|
||||
SetAction("Sleep");
|
||||
lib_insect_sleeping = true;
|
||||
return;
|
||||
}
|
||||
// One last trip, then become invisible
|
||||
MoveToTarget();
|
||||
lib_insect_going2sleep = true;
|
||||
}
|
||||
|
||||
private func SleepComplete()
|
||||
{
|
||||
SetAction("Sleep");
|
||||
_inherited();
|
||||
}
|
||||
|
||||
private func WakeUp()
|
||||
{
|
||||
SetAction("Fly");
|
||||
_inherited();
|
||||
}
|
||||
|
||||
// Array: [object lovely_object, int x, int y]
|
||||
local lovely_place;
|
||||
// How many times I tried to get to the lovely place
|
||||
local lovely_tries = 0;
|
||||
|
||||
// Mosquitos always look for a lovely place to hang out
|
||||
private func GetAttraction(proplist coordinates)
|
||||
{
|
||||
// GetAttraction will only be called for the swarm master, perfect to have just one being make sound
|
||||
if(!Random(30))
|
||||
Sound("MosquitoBuzz", nil,nil,nil,nil, 200);
|
||||
|
||||
if (!lovely_place) lovely_place = CreateArray(3);
|
||||
if (!lovely_place[1])
|
||||
{
|
||||
if (lovely_tries < 35) lovely_tries++;
|
||||
if (lovely_tries > 15 + Random(30))
|
||||
// Should not be called too often.
|
||||
LookForLovelyPlace();
|
||||
}
|
||||
if (!lovely_place[1])
|
||||
return false; // No lovely place found. Default behaviour (just fly around)
|
||||
|
||||
// Occasionally check if lovely place still qualifies
|
||||
if (!Random(100) && !CheckLovelyPlace())
|
||||
return false;
|
||||
|
||||
// Lovely is an object (plant or corpse): Stay close
|
||||
if (lovely_place[0])
|
||||
{
|
||||
// Too far away from lovely place. Maybe I can't reach it?
|
||||
if (Distance(GetX(), GetY(), lovely_place[1], lovely_place[2]) > 50)
|
||||
lovely_tries++;
|
||||
coordinates.x = lovely_place[1] + Random(60) - 30;
|
||||
// This might fail with *very* high plants in respect of the next distance check. That's okay, I guess.
|
||||
coordinates.y = lovely_place[2] + Random(50) - 25;
|
||||
} else { // Lovely place is water: Fly around a bit
|
||||
// Too far away from lovely place. Maybe I can't reach it?
|
||||
if (Distance(GetX(), GetY(), lovely_place[1], lovely_place[2]) > 250)
|
||||
lovely_tries++;
|
||||
coordinates.x = lovely_place[1] + Random(300) - 150;
|
||||
coordinates.y = GetHorizonHeight(coordinates.x);
|
||||
if (!GBackLiquid(AbsX(coordinates.x), AbsY(coordinates.y))) // Stay on water
|
||||
{
|
||||
coordinates.x = lovely_place[1];
|
||||
coordinates.y = lovely_place[2];
|
||||
}
|
||||
coordinates.y -= 25 - Random(20);
|
||||
}
|
||||
|
||||
// Tried to reach that place for far too long
|
||||
// Or maybe I've got enough of that place!
|
||||
if (lovely_tries >= 10 || !Random(1000))
|
||||
return RemoveLovelyPlace();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private func LookForLovelyPlace()
|
||||
{
|
||||
lovely_tries = 0;
|
||||
// Corpses are first priority places
|
||||
var corpse = FindObject(Find_Distance(200), Find_NoContainer(), Find_Category(C4D_Living), Find_Not(Find_OCF(OCF_Alive)), Find_Exclude(lovely_place[0]));
|
||||
if (corpse && Random(15))
|
||||
{
|
||||
lovely_place[0] = corpse;
|
||||
lovely_place[1] = corpse->GetX();
|
||||
lovely_place[2] = GetHorizonHeight(corpse->GetY()) - 30;
|
||||
return;
|
||||
}
|
||||
// Water is second best place
|
||||
var water = FindLocation(Loc_InRect(-100,-50,200,100), Loc_Material("Water"), Loc_MaxTries(80));
|
||||
if (water)
|
||||
{
|
||||
// Try to find the surface
|
||||
while (!GBackSky(water.x, water.y) && AbsY(water.y) > 0)
|
||||
water.y--;
|
||||
if (water.y > 0)
|
||||
{
|
||||
lovely_place[0] = nil;
|
||||
lovely_place[1] = water.x;
|
||||
lovely_place[2] = water.y;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Dense vegetation is third best place
|
||||
var plants = FindObjects(Find_Distance(200), Find_NoContainer(), Find_Func("IsPlant"), Find_Exclude(lovely_place[0]));
|
||||
if (GetLength(plants) >= 10)
|
||||
{
|
||||
var plant = plants[Random(GetLength(plants))];
|
||||
lovely_place[0] = plant;
|
||||
lovely_place[1] = plant->GetX();
|
||||
lovely_place[2] = GetHorizonHeight(plant->GetY()) - 30;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private func CheckLovelyPlace()
|
||||
{
|
||||
if (lovely_place[0]) // Corpse or plant
|
||||
{
|
||||
if (lovely_place[0]->~IsPlant())
|
||||
// Vegetation is not so dense anymore?
|
||||
if (lovely_place[0]->ObjectCount(Find_Distance(200), Find_NoContainer(), Find_Func("IsPlant"), Find_Exclude(lovely_place[0])) < 5)
|
||||
return RemoveLovelyPlace();
|
||||
// Place has moved?
|
||||
if (Distance(lovely_place[0]->GetX(), lovely_place[0]->GetY(), lovely_place[1], lovely_place[2]) > 100)
|
||||
return RemoveLovelyPlace();
|
||||
} else {
|
||||
// Water is gone?
|
||||
if (!GBackLiquid(AbsX(lovely_place[1]), AbsY(lovely_place[2])))
|
||||
return RemoveLovelyPlace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private func RemoveLovelyPlace()
|
||||
{
|
||||
lovely_tries = 0;
|
||||
// Don't delete lovely_place[0]
|
||||
// It will be ignored in future searches
|
||||
lovely_place[1] = nil;
|
||||
lovely_place[2] = nil;
|
||||
return false;
|
||||
}
|
||||
|
||||
private func CheckTurn()
|
||||
{
|
||||
if (GetXDir() < 0)
|
||||
SetDir(DIR_Left);
|
||||
if (GetXDir() > 0)
|
||||
SetDir(DIR_Right);
|
||||
}
|
||||
|
||||
/* Definition */
|
||||
|
||||
local ActMap = {
|
||||
Fly = {
|
||||
Prototype = Action,
|
||||
Name = "Fly",
|
||||
Procedure = DFA_FLOAT,
|
||||
Speed = 200,
|
||||
Accel = 32,
|
||||
Decel = 32,
|
||||
Directions = 2,
|
||||
FlipDir = 1,
|
||||
Length = 3,
|
||||
Delay = 2,
|
||||
X = 0,
|
||||
Y = 0,
|
||||
Wdt = 2,
|
||||
Hgt = 2,
|
||||
NextAction = "Fly",
|
||||
EndCall = "CheckTurn",
|
||||
},
|
||||
Sleep = {
|
||||
Prototype = Action,
|
||||
Name = "Sleep",
|
||||
Procedure = DFA_FLOAT,
|
||||
Speed = 0,
|
||||
Directions = 2,
|
||||
FlipDir = 1,
|
||||
Length = 1,
|
||||
Delay = 1,
|
||||
X = 6,
|
||||
Y = 0,
|
||||
Wdt = 2,
|
||||
Hgt = 2,
|
||||
NextAction = "Hold",
|
||||
},
|
||||
};
|
||||
|
||||
local Name = "$Name$";
|
||||
local MaxEnergy = 20000;
|
||||
local MaxBreath = 250;
|
||||
local Placement = 2;
|
||||
local NoBurnDecay = 1;
|
|
@ -0,0 +1 @@
|
|||
Name=Mücke
|
|
@ -0,0 +1 @@
|
|||
Name=Mosquito
|
Loading…
Reference in New Issue