Esempio n. 1
0
func FindTarget(fx)
{
	// Attack doors and statue unless an enemy clonk is closer than these objectives
	var objective;
	     if (g_doorleft  && GetX()<=g_doorleft ->GetX()+5) objective = g_doorleft;
	else if (g_doorright && GetX()>=g_doorright->GetX()-5) objective = g_doorright;
	else objective = g_statue;
	var target = inherited(fx, ...);
	if (objective)
		if (fx.is_siege || !target || ObjectDistance(target) > ObjectDistance(objective))
			target = objective;
	return target;
}
Esempio n. 2
0
global func FireBreathDamage(proplist fx, int angle, int max_reach, int x, int y)
{
	var reach = Min(fx.spray_cur.reach, max_reach * CYCLOPS_FireBreath_Precision);
	var dx = +Sin(angle, reach) / CYCLOPS_FireBreath_Precision;
	var dy = -Cos(angle, reach) / CYCLOPS_FireBreath_Precision;

	if (false)
	{
		if (!fx.rock) fx.rock = CreateObject(Rock);
		fx.rock->SetPosition(x + dx, y + dy);
		fx.rock->SetXDir();
		fx.rock->SetYDir();
	}

	// damage the clonk
	reach /= CYCLOPS_FireBreath_Precision;
	reach += 5; // the fuzzy part of the flames
	if (ObjectDistance(fx.cyclops, fx.target) < reach)
	{
		if (cyclops_dangerous)
		{
			var damage=1000;
			fx.target->DoEnergy(-damage, true, FX_Call_EngGetPunched, NO_OWNER);
		}
		else
		{
			fx.target.hurt_by_cyclops = true;
		}
	}
}
Esempio n. 3
0
global func FxIntCyclopsAITimer(object cyclops, proplist fx, int time)
{
	if (!fx.cyclops)
	{
		fx.cyclops = cyclops;
		fx.weapon = cyclops->FindContents(Club);
	}
	if (!fx.eye) fx.eye = FindObject(Find_ID(CyclopsEye));

	fx.time = time;
	
	// do not idle
	var effect = GetEffect("IntWalk", fx.cyclops);
	if (effect) effect.idle_time = 0;
	
	fx.eye->SetPosition(fx.cyclops->GetX() -4 + fx.cyclops->GetDir() * 8, fx.cyclops->GetY() - 19);

	// Find an enemy
	if (fx.target) if (!fx.target->GetAlive() || (!fx.ranged && ObjectDistance(fx.target) >= fx.max_aggro_distance)) fx.target = nil;
	if (!fx.target)
	{
		if (!(fx.target = CyclopsFindTarget(fx))) return CyclopsExecuteIdle(fx);
	}

	// Attack it!
	return CyclopsExecuteMelee(fx, time);
}
Esempio n. 4
0
func CatchBlow(int iLevel, object pObj) {
	if (GetCategory(pObj) & C4D_Object && GetOCF(pObj) & OCF_Collectible && ObjectDistance(pObj)*10 < 8*Sqrt(GetDefWidth(GetID())*GetDefHeight(GetID())) ) {
		pObj->~Hit();
		// Reduces object speed by 90%
		if (pObj) {
			pObj->SetXDir(GetXDir()*5, 0, 100);
			pObj->SetYDir(GetYDir()*5, 0, 100);
		}
	}
	return _inherited(iLevel, pObj);
}
Esempio n. 5
0
func FxComebackTimer(object target, proplist effect, int time)
{
	if(!this)
		return;
	
	if(!shooter)
		return RemoveObject();

	if(ObjectDistance(this, shooter) < Size)
		return RemoveObject();

	var angle = Angle(GetX(), GetY(), shooter->GetX(), shooter->GetY(), 10);
	
	SetVelocity(angle, Speed + 40, 10);
}
Esempio n. 6
0
func Timer()
{
	if(pBeamer && GetCursor(GetOwner()) != this()) return RemoveObject();
	Frame++;
	if(Frame > 10)
	{
		Frame = 0;
		if(GetAction() eq "1")
		{
			SetAction("2");
		}
		else
		{
			SetAction("1");
		}
	}
	/*if(GetR() < 360)
	{
		SetR(GetR() + 1);
	}
	else
	{
		SetR(0);
	}*/
	if(ObjectDistance(pBeamer) > LandscapeWidth() / 2 && !FindObject(ENRG)) 
	{
		if(GetX() > GetX(pBeamer))
		{
			SetXDir(-30);
		}
		else
		{
			SetXDir(30);
		}
		if(GetY() > GetY(pBeamer))
		{
			SetYDir(-30);
		}
		else
		{
			SetYDir(30);
		}
	}
	SetRDir(3);
}	
Esempio n. 7
0
public func Activate(oCaller, oClonk)
{                            
  if(!oClonk) oClonk = oCaller;
  // Effekt prüfen
  var iChkEff;
  if (iChkEff = CheckEffect("ExtinguishPSpell", oExtiObj, 180)) return(iChkEff!=-1 && RemoveObject());
  // Lavafässer zu Granit werden lassen
  var obj;
  if (obj = FindContents(LBRL, oClonk))
    if (!CheckEffect("ExtinguishPSpell", obj, 180))
    {
      var mat = "Granite";
      // Granit nicht geladen -> Stein casten
      if (!MaterialLoaded(Material(mat))) mat = "Rock";
      // Stein nicht geladen -> Kohle casten
      if (!MaterialLoaded(Material(mat))) mat = "Coal";
      // Material schleudern
      var amount = Min(400, obj->GetAmount()*3);
      CastPXS(mat, amount, 40, AbsX(GetX(oClonk)), AbsY(GetY(oClonk)));
      // Objekt entfernen
      RemoveObject(obj);
    }
  // Nächstes brennendes Objekt finden
  var oExtiObj, iExtiCount;
  // Den Clonk selbst?
  if(OnFire(oClonk)) 
    iExtiCount += DoExtinguish(oClonk, oCaller);
  // Nächstliegende Objekte
  SetPosition(GetX(oCaller), GetY(oCaller));
  // Suchradius ist abhängig von Höhe des Aufrufenden - ein Zauberturm hat einen größeren Radius
  var iSearchRadius = GetObjHeight(oCaller) * 3;
  while(oExtiObj = FindObject(0, 0, 0, -1, -1, 0, 0, 0, 0, oExtiObj))
    if(ObjectDistance(oCaller, oExtiObj) > iSearchRadius)
      break;
    else if(OnFire(oExtiObj))
      iExtiCount += DoExtinguish(oExtiObj, oCaller);
    else if (oExtiObj->~MagicExtinguish(oCaller))
      iExtiCount += DoExtinguish(oExtiObj, oCaller);
  // Irgendwas gelöscht?
  if (!iExtiCount) return(0, Message("$NoExtinguish$", oClonk), RemoveObject());
  // Einmaliger Effekt pro Zauber
  Sound("Splash1");
  return(true);
}
Esempio n. 8
0
bool kexWorldObject::RangeDamage(const char *damageDef,
                                 const float dmgRadius,
                                 const kexVec3 &dmgOrigin) {
    if(areaLink.node) {
        float dist;
        kexSDNodeObj<kexWorldObject> *areaNode = areaLink.node;

        while(1) {
            for(kexWorldObject *obj = areaNode->objects.Next(); obj != NULL;
                obj = obj->areaLink.link.Next()) {
                    if(obj == this || !obj->bCollision) {
                        continue;
                    }
                    if(target && obj != target) {
                        continue;
                    }

                    dist = ObjectDistance(obj, dmgOrigin);

                    if(kexMath::Sqrt(dist) * 0.5f < radius + dmgRadius) {
                        InflictDamage(obj, defManager.FindDefEntry(damageDef));
                        return true;
                    }
            }

            if(areaNode->axis == -1) {
                break;
            }

            if(bbox.min[areaNode->axis] > areaNode->dist) {
                areaNode = areaNode->children[NODE_FRONT];
            }
            else if(bbox.max[areaNode->axis] < areaNode->dist) {
                areaNode = areaNode->children[NODE_BACK];
            }
            else {
                break;
            }
        }
    }

    return false;
}
Esempio n. 9
0
public func Activate(oCaller, oClonk)
{                            
  if(!oClonk) oClonk = oCaller;
  // Effekt prüfen
  var iChkEff;
  if (iChkEff = CheckEffect("WarmPSpell", oExtiObj, 180)) return(iChkEff!=-1 && RemoveObject());
  // Nächstes gerforenes Objekt finden
  var oExtiObj, iExtiCount, pObj;
  // Den Clonk selbst?
  if(Frozen(oClonk)) 
    iExtiCount += DoUnfreeze(oClonk, oCaller);
  else if(oClonk->~MagicWarm(1800))
    iExtiCount += DoUnfreeze(oClonk, oCaller);
  else if(pObj = Contents(0,oClonk))
    if(GetID(pObj)==METL) if(GetDefHeight(ANML))
    {
      RemoveObject(pObj);
      CreateContents(ANML, oClonk);
      return(RemoveObject());
    }
  // Nächstliegende Objekte
  SetPosition(GetX(oCaller), GetY(oCaller));
  // Suchradius ist abhängig von Höhe des Aufrufenden - ein Zauberturm hat einen größeren Radius
  var iSearchRadius = GetObjHeight(oCaller) * 3;
  while(oExtiObj = FindObject(0, 0, 0, -1, -1, 0, 0, 0, 0, oExtiObj))
    if(ObjectDistance(oCaller, oExtiObj) > iSearchRadius)
      break;
    else if(Frozen(oExtiObj))
      iExtiCount += DoUnfreeze(oExtiObj, oCaller);
    else if (oExtiObj->~MagicUnfreeze(oCaller))
      iExtiCount += DoUnfreeze(oExtiObj, oCaller);
  // Irgendwas erwärmt?
  if (!iExtiCount)
  {
    Message("$NoUnfreeze$", oClonk);
    RemoveObject();
    return 0;
  }
  // Einmaliger Effekt pro Zauber
  Sound("Inflame");
  return(true);
}
Esempio n. 10
0
//Such nach einem Objekt, dass ein Acquire-Command holen könnte
global func GetAvailableObject (def, xobj)
{
  var obj;
  // Next closest
  while (obj = FindObject (def, 0, 0, -1, -1, OCF_Available (), 0, 0, 0, obj))
  {
    if (ObjectDistance (obj) > 559) return (); 
    // Object is near enough
    if (!Inside (GetX () - GetX (obj), -500, +500)) continue;
    if (!Inside (GetY () - GetY (obj), -250, +250)) continue;
    // Object is not connected to a pipe (for line construction kits)
    if (FindObject (SPIP, 0, 0, 0, 0, 0, "Connect", obj)) continue;
    if (FindObject (DPIP, 0, 0, 0, 0, 0, "Connect", obj)) continue;
    // Must be complete
    if (~GetOCF (obj) & OCF_Fullcon ()) continue;
    // Doesn't burn
    if (OnFire( obj)) continue;
    // Not contained in xobj
    if (!(Contained (obj) == xobj) || !xobj)
      // We found one
      break;
  }
  return (obj);
}
Esempio n. 11
0
public func Activate(caster, real_caster) {
  // Zaubernden Clonk ermitteln
  var clonk = caster;
  if (real_caster) clonk = real_caster;

  // Richtungsvorzeichen ermitteln
  var dir_sign = -1;
  if (GetDir(caster) == DIR_Right()) dir_sign = +1;

  // Evtl. mit Flint kombinieren
  var obj;
  if (obj = FindContents(FLNT, clonk)) {
    // Holz erzeugen, anzünden und in Guckrichtung schleudern
    var wood = CreateObject(WOOD, 5*dir_sign, 0, -1);
    Incinerate(wood);
    // Richtigen Controller setzen
    SetController(GetController(clonk),wood);
    SetXDir(40*dir_sign, wood);
    SetYDir(-10, wood);
    // Flint verbrauchen
    RemoveObject(obj);
  }
  // Evtl. mit Pfeil kombinieren
  else
  {
    obj = FindContents(ARRW, clonk);
    if(!obj) if(FindContents(ARWP, clonk))
      obj = FindContents(ARWP, clonk)->GetItem();
    if(obj) {
      // Ein paar Objekte schleudern
      var fling_cnt = RandomX(4, 10);
      var fling_obj;
      while (fling_obj = FindObject(0, 0, 0, -1, -1, OCF_InFree(), 0, 0, NoContainer(), fling_obj)) {
        // Zu weit weg vom Clonk?
        if (ObjectDistance(clonk, fling_obj) > 5*GetDefCoreVal("Width", "DefCore", GetID(caster)))
          break;
        // Der Wolf konnte keine Steinhütten wegblasen - Clonks können keine Hütten mit Fundament wegblasen
        if (!LocalN("basement", fling_obj))
          {
          var pBasement = Local(9, fling_obj);
          if (GetType(pBasement) != C4V_C4Object()) pBasement=0;
          if (pBasement) if (!PrivateCall(pBasement, "BasementID")) pBasement=0;
          if (!pBasement)
            {
            SetXDir(dir_sign*Min(80, 80*350/GetMass(fling_obj)), fling_obj);
            SetYDir(-Min(20, 20/GetMass(fling_obj)), fling_obj);
            // Bei Objekten noch den Controller anpassen
            if(GetCategory(fling_obj) & C4D_Object())
              SetController(GetController(clonk),fling_obj);
            }
          }
        // Schon genügend Objekte geschleudert?
        if (!fling_cnt--) break;
      }
      if (!Contained(clonk)) {
        Fling(clonk, 8*dir_sign, -2);
      }
      // Pfeil verbrauchen
      RemoveObject(obj);
    }
    // Sonst normale Wirkung
    else {
      AddEffect("WindUSpell", 0, 104, 50, 0, GetID(), GetDir(caster));
      Sound("Wind2");
    }
  }
  
  RemoveObject();
  return(1);
}
Esempio n. 12
0
global func DoFireBreath(proplist fx, int x, int y, int tx, int ty, int timer)
{
	var anim_length = 12;

	var sx = x - 3 + 6 * fx.cyclops->GetDir();
	var sy = y - 15;	

	// effects
	if (fx.spraying_charge <= 0)
	{
		if (ObjectDistance(fx.cyclops, fx.target) < CYCLOPS_FireBreath_Reach && fx.spraying < CYCLOPS_FireBreath_Duration)
		{
			var action = "IdleLookAround";
			fx.cyclops->PlayAnimation(action, CLONK_ANIM_SLOT_Arms, Anim_Linear(0, 0, fx.cyclops->GetAnimationLength(action), anim_length, ANIM_Remove), Anim_Linear(0, 0, 1000, 5, ANIM_Remove));
			fx.spraying_charge = 1;
		}
	}
	else if (fx.spraying_charge < anim_length)
	{
		fx.spraying_charge++;
		
		if (fx.spraying_charge >= anim_length)
		{
			fx.cyclops->Sound("BalloonInflate");
		}
	}
	else if (fx.spraying < CYCLOPS_FireBreath_Duration)
	{
		var target_angle = Normalize(Angle(sx, sy, tx, ty), -180);
		var source_angle = -90 + fx.cyclops->GetDir() * 180;

		var a = Min(CYCLOPS_FireBreath_Duration, fx.spraying * 2);
		var b = CYCLOPS_FireBreath_Duration - a;
		var angle = (b * source_angle + a * target_angle) / CYCLOPS_FireBreath_Duration;
		angle = Normalize(angle, -180);
		var head_angle = Normalize(angle - source_angle, -180);

		// turn his head towards the clonk
		// somehow the turning head makes the cyclops invisible, though
		var transform = Trans_Rotate(10, 0, 0, 1);
		//var transform = Trans_Rotate(head_angle, 0, 0, 1);

		if (!fx.anim_nr)
		{
			fx.anim_nr = fx.cyclops->TransformBone("skeleton_head", transform, 5, Anim_Const(1000));
		}
		else
		{
			fx.cyclops->SetAnimationBoneTransform(fx.anim_nr, transform);
		}

		fx.spraying = Min(CYCLOPS_FireBreath_Duration, fx.spraying + 1);
		var distance = Min(CYCLOPS_FireBreath_Reach, ObjectDistance(fx.cyclops, fx.target));

		FireBreathEffect(fx, angle, distance, sx, sy, timer);
		FireBreathDamage(fx, angle, distance, sx, sy);
	}
	else
	{
		// cooldown and reset
		fx.spraying = Min(2 * CYCLOPS_FireBreath_Duration, Max(CYCLOPS_FireBreath_Duration + 1, fx.spraying + 1));
		if (fx.spraying == 2 * CYCLOPS_FireBreath_Duration)
		{
			fx.spraying = 0;
			fx.spraying_charge = 0;
			fx.spray_old = {time = 0, v0 = 0, v1 = 0, reach = 0};
			fx.spray_cur = {time = 0, v0 = 0, v1 = 0, reach = 0};
		}
	}
}