Clonk Forge Hazard update

Hey :slight_smile:

ich hab schon im CMC Forum geschrieben, aber vllt ists nicht der richtige bereich, weshalb keiner antwortet. Deswegen copy paste ich meinen post mal hierher:

Muss ich mich auf clonkforge regisitrieren, oder kann ich auch hier meine Verbesserungen vorstellen?  (edit: merke gerade ich kann mich garnicht auf ClonkForge registrieren, da ich weder das spiel gekauft habe (freeware), noch ein Hauptarchiv oderso habe.)

Habe im Zuge meines Packs auch so einige Dinge für das Hazardpack gemacht, z.b dass Munition teilweise aufgenommen werden kann (also nicht nur immer ganze 50er packs oderso) und man die munition auch wieder ablegen kann.
Und auch die “Bewachen” funktion habe ich deutlich verbessert, sodass nun wirklich vernünftig automatisch auf Feinde geschossen wird, mit einstellung des suchradius (es gibt ja noch weitere Funktionen, die eigentlich dann auch noch automatisch waffen besorgen sollten usw, die habe ich aber nicht weiter ausgebaut)

Ist schon nen Jahr her, weiß also grad nicht mehr alle verbesserungen ausm kopf… Aber wenn ich was zu beitragen kann, würde ich mich nochmal durchwühlen und schauen, was ich alles gemacht hab ^^

Hier mal die Threads die ich zu Hazard gemacht hatte:
https://clonkspot.org/forum/topic_show.pl?tid=348 (bewachen befehl)
https://clonkspot.org/forum/topic_show.pl?tid=420  (aliens sterben zu schnell durch melee schaden)
https://clonkspot.org/forum/topic_show.pl?tid=333   (ein Waffengürtel gebastelt, welcher es einzelnen clonks ermöglicht mehr von einer bestimmten munition zu tragen)
https://clonkspot.org/forum/topic_show.pl?tid=316  (weniger für typische hazardszenarien, aber: teleporter, segu und controller sind im normalen spiel baubar und funktionieren)

PN an Newton am besten.

Moin Serpens

Sehr schön zu lesen dass jemand gemerkt hat dass ich ein Hazard update rausbringen möchte und Bugfixes sammle. Schreib ruhig alles hier rein, ich lese hier mit.

Welches Pack ist das denn von dem du sprichst? Dann würde ich einfach mal selbst durchgucken und schauen ob ich Patches finde die in das Originalpack wandern könnten. Die Sache mit Bewachen und den Aliens hört sich gut an. bei den beiden letzteren Sachen bin ich mir nicht sicher. Die Strukturelemente in Hazard sind nicht darauf ausgelegt gebaut zu werden.

Hast du die Endlosschleife, wenn man die Lasergranate in eine Ecke schmeisst, schon gefixt?

Ah, freut mich wenn ich was beitragen kann :slight_smile:

Hast du dir eine Deadline gesetzt, bis wann du fertig sein willst? Heute schaffe ich es nicht mehr, mein Pack durchzugehen und die Woche geht ja wieder los… vllt schaff ichs in der woche, aber eventuell erst nächstes wochenende.

Mein Pack habe ich noch nicht veröffentlicht, weil es noch nicht fertig ist.  Fehlen noch ein paar kleine Dinge und es alleine zu balancen schaffe ich vermutlich auch nicht… falls ich endlich mal wieder etwas mehr zeit habe (spätestens im winter), werde ich alles soweit fertigstellen, es hochladen und dann mit eurer Hilfe (alle aus dem forum), balancen.
Das Pack ist quasi ein Zusammenschluss aus allen Paketen die mir so ganz gut gefallen haben und ich gerne in Kombination spielen würde. Leider sind die vielen Pakete ja in der Regel nicht untereinander kompatibel und ich hab dafür dann halt gesorgt und hier und da Bugfixes und Verbesserungen eingebaut.  Es ist dazu gedacht ein normales Clonk Siedelspiel zu haben, wo man sich durch die Zeitalter forschen kann, bis hin zu Hazard und den Hazard Ships.   Dummerweise ist das Pack meine erste Programmierarbeit überhaupt gewesen :smiley: Mittlerweile kann ich denke ich ganz gut programmieren (auch Python), aber mein Pack ist leider extremst durcheinander und verdammt unübersichtlich. D.h. selbst wenn ich es dir geben würde, würdest du Wochen brauchen, um dich darin zurechtzufinden :smiley:

Also ich werd die Tage dann mal mein Pack durchstöbern und schauen, was ich noch so habe und den Code dazu auch raussuchen und hier posten :slight_smile:

Ja

So in den nächsten zwei Wochen wollte ich mit allem fertig sein. Inklusive playtesting allerdings.

Wenn du ansonsten noch helfen willst, oder auch jemand anders. Ich hätte da noch einige kleinere Bugs:

* an der Sentry Gun fliegen manchmal? irgendwie Raketen vorbei anstatt zu explodieren wenn ich nicht die Wand treffe. Fehlt da vielleicht eine Hitbox, IsBulletTarget oder sowas?
* Die No-Camping Regel scheint irgendwie kaputt zu sein. Die meldet jedenfalls viel zu häufig dass man campt
* Manchmal spawnt man immer oben links (position 0,0), keine Ahnung wieso

zur Segu:
Offensichtlich ist ja nur das Gestell ein Target und das scheint auch zu funktionieren (jedenfalls in meiner Version… weiß nicht ob ich da bezüglich bullettarget was verändert habe :D)

Wie möchtest du es gelöst haben? Soll das Waffenteil, z.b MG, auch ein Bullettarget sein? Und dann eben einzeln zerstörbar sein, während das Gestell an sich intakt bleibt? Oder soll das Waffenteil den Schaden ans Gestell weiterleiten?

Hmm, das ist das Problem? Ach, dann mach ich einfach die Hitbox des Gestelles größer. (Mit gedrehter Waffe wäre es wohl zu groß, da die Hitbox von gedrehten Objekten ja sehr groß ist) Vielen Dank für die Problemsuche!

Ich hoffe es wird hier alles korrekt angezeigt… ich speicher den text aber vorher auch nochmal in einer txt datei ab… und kann die hochladen oderso…

Zum Skript der hazardclonks:

Die readytofire function im Hazardclonk sollte so aussehen (so werden auch Waffen wie Bazooka berücksichtigt):

public func ReadyToFire() {     // nur aus bestimmten Aktionen feuern

   var a = GetAction();

   // In Gebäude
   if(Contained()) return(Contained()->~ReadyToFire());
   // Reitet
   if(IsRiding()) return(GetActionTarget()->~ReadyToFire());
   // Schiebt
   if(a S= "Push")
     if(GetActionTarget()->~IsWeapon())
       return(true);

   // Nur beim Laufen, Schwimmen oder Springen
   if(a eq "WalkArmed"
   || a eq "SwimArmed"
   || a eq "JumpArmed")
    return(true);

   // wenn Waffe die nur im Zielen abgefeuert werden kann, ist die Aktion ohne "armed" und daher bisher unberücksichtigt
   if(Contents()->~IsWeapon())
     if(Contents()->GetFMData(FM_Aim)>0)
       if(a eq "Walk" || a eq "None")    // nicht wenn waffe zum zielen aber schwimmend oder springend
       return(true);
  
   // JetpackFlight fehlt noch, sowie Aim*… das steht in den Funktionalitäten
   return(_inherited());
}


In der UpdateCharge Funktion habe ich kurz vrom return noch zugefügt:
// prüfen ob Waffe in Hand
  CheckArmed();

Ohne dies, wird CheckArmed meiner meinung nach viel zu selten gecheckt. (ich glaube nur wenn clonk sich bewegt?) Das hat zumindest in meiner Version zu problemen geführt.

Die funktion Incineration sollte angepasst werden, ob nun so wie ich es gemacht habe, oder ob du ne bessere Idee hast, bleibt dir überlassen :wink: . So wie sie bisher ist, sterben hazardclonk in Flammen sehr schnell (z.b brandbomben)

public func Incineration() {
  // Hazardclonks brennen ncht wirklich :wink:
  Extinguish();
if(!brennt)
  { // damit bei Brandbomben nicht sofort tot
  Schedule("DoDmg(5,DMG_Fire,0,1)",1,20,this());
  AddFireEffect(this(),30,FIRE_Red,1);
  brennt=1;
  ScheduleCall(0,"Feueristaus",20,0,0);
  }
}
func Feueristaus()
{brennt=0;}


Vor die Funktioin FXAggroTimer sollte noch ein Start zugefügt werden:
public func FxAggroStart()
{
    // -> Waffen durchchecken, weil wenn nie zuvor geladene Waffe, dann funzt bewachen nicht.
    CheckIdleWeapon();
    return(1);
}


FxAggroTimer selbst sieht bei mir so aus:

public func FxAggroTimer(object pTarget, int no)
{
  // keine Waffe geladen? Dann waffen durchchecken 
// Waffenstatus durchgehen, vorher zählen
  var waffenanzahl = CustomContentsCount("IsWeapon");
   var o = 0;
   for(var u = 0; u < ContentsCount(); u++)
       if(Contents(u)->~IsWeapon())
      {
       if(!Contents(u)->~GetCharge()) ++o;
       if(Contents(u)->~GetCharge()) break;
      }
  // wenn o nun gleich waffenanzahl, dann heißt das, dass alle Waffen leer sind, dann nachladen.
   if(o == waffenanzahl)
   return(CheckIdleWeapon());

  // Wir haben ein Ziel?
  if(EffectVar(1, this(), no)) { EffectCall(this(), no, "Fire"); return(1); }
  // Zielen beenden
  if(IsAiming()) StopAiming();
//  Message("@No target", this());
  // Ziel suchen
  var dist = EffectVar(2, this(), no);
  var dir = GetDir()2-1;
  // Vorne
  var target = GetTarget(90
dir, 90,dist);
  // Hinten
  if(!target)
    if((!GetCommand() && !GetMacroCommand()) || EffectVar(0, this(), no) != 1)
      target = GetTarget(-90dir, 90,dist);
  // Gefunden?
  if(!target)
  {
    //Log("kein Ziel gefunden");
    // Nichts gefunden :frowning:
    // -> Bescheid geben!
    if(EffectVar(99, this(), no))
    {
      if(Contained())
        Contained()->~HandleAggroFinished(this());
      else if(IsRiding())
        GetActionTarget()->~HandleAggroFinished(this());
     
      EffectVar(99, this(), no);
    }
    // -> Waffen durchchecken
    CheckIdleWeapon();
    return();
  }
  // Super
  EffectVar(1, this(), no) = target;
  EffectVar(99,this(), no) = true; // wir haben ein Ziel \o/
}


FXAggroFire hat hier und da einige Verbessserungen, ich denke mal du kannst deine funktion mit dieser hier vergleichen und die unterscheide feststellen:
public func FxAggroFire(object pTarget, int no)
{

  // Zusatzhack: BR-Bombe!
  if(GetID(Contents()) == GBRB)
    // Nichts tun :C
    return();
  var y = EffectVar(4, this(), no);
  var x = EffectVar(3, this(), no);
  var dist = EffectVar(2, this(), no);
  var target = EffectVar(1, this(), no);
  var level = EffectVar(0, this(), no);
  var pathfree = true;
 
  // Nichts tun, wenn gerade verhindert
  if(ReadyToFire())
{

  // Fahrzeugsteuerung
  if(Contained())
  {
    if(Contained()->~HandleAggro(this(), level, target, dist, x, y))
      return(1);
    else
      return(AddCommand(this(), "Exit", 0,0,0,0,0,0,0, C4CMD_SilentSub));
  }
  if(IsRiding())
  {
    if(GetActionTarget()->~HandleAggro(this(), level, target, dist, x, y))
      return(1);
    else
      return(SetAction("Walk"));
  }
}
 
  // Zu weit von der Wachposition entfernt?
  if(level == 3) {
    if(Distance(GetX(), GetY(), x, y) > dist)
    {
      if(GetMacroCommand(1, 1) == target)
      {
        FinishMacroCommand(1,0,1);
        FinishMacroCommand(1);
      }
       // Log("zu weit von Wachposition entfernt");
      AddMacroCommand(0, "MoveTo", 0, x,y, 0, level);
      EffectVar(1, this(), no) = 0;
    //      Message("@Returning to guarded position", this());
      return();
    }
  }
 
  var maxdist = dist;
  if(!PathFree(GetX(), GetY(), target->GetX(), target->GetY()))
  {
    if(level == 1) maxdist = 0;
    if(level >= 2) maxdist = dist/2;
    pathfree = false;
  }
  //Log("kurz vor ziel weg");
  // Ziel irgendwie weg?
  // (Pathfree wurde schon gecheckt)…  reicht nicht, da zielen und schießen nicht aufhört, wenn was zwischen gegner, aber noch in Radius, und daher wird auch nicht nachgeladen -.-
  if(!CheckTarget(target,this,maxdist,0,0,true) || !PathFree(GetX(), GetY(), target->GetX(), target->GetY()))
    {
      EffectVar(1, this(), no) = 0;
      if(EffectVar(0, this(), no) == 2)
        ClearMacroCommands();
      if(!IsAiming()) if(Contents(0)) Contents(0)->~AimStop(); // damit auch das Autofeuer aufhört
      if(IsAiming())
        StopAiming();    
        //Log("Ziel iwie weg");
      return();
    }
  // Ich hab nix? °-°
  if(!Contents()) return(); // Lauf, Forest, lauf!
  //Log("nach ich hab nix");
  // Waffe in die Hand nehmen
  if(!SelectWeapon(level, target, false))
    // Evtl. Feuermodus wechseln (dann muss erst nachgeladen werden, aber besser als nichts)
    if(!SelectWeapon(level, target, true))
    {
      // Bei Aggro_Follow können wir von unserem Pfade weg. D.h. eine Waffe und/oder Munition muss her
      if(GetAggroLevel() == Aggro_Follow)
      {
//      Message("@Searching for weapons / ammo", this());
        // Waffen auffrischen?
        if(CustomContentsCount("IsWeapon") <= 1)
          return(SearchWeapon(Aggro_Shoot));
        // Munition auffrischen
        return(SearchAmmo(Aggro_Shoot));
      }
      // ein Balrog, ein Feind gegen den ihr nichts ausrichten könnt…lauft!
        //Log("Balrog?");
        return();
    }
  // Stufe 1 - nur in die grobe Richtung ballern, lieber nicht anhalten oder sowas

  if(!ReadyToFire()) return();

  // Schaue ich in die richtige Richtung?
  if(GetX() < target->GetX())
  {
    if(GetDir() != DIR_Right)
      SetDir(DIR_Right);
  }
  else
  {
    if(GetDir() != DIR_Left)
      SetDir(DIR_Left);
  }
     //Log("kurz vor zielen muss auch mal sein");
  // Zielen, muss auch mal sein
if((!GetCommand() && !GetMacroCommand()) || level != 1 || IsAiming())
{
  if(pathfree && Contents()->GetBotData(BOT_Range) > 30) // Weg frei und keine Nahkampfwaffe?
  {
    var angle = Angle(GetX(), GetY(), target->GetX(), target->GetY());
    if(((!Inside(angle, 70, 120) && !Inside(angle, 250, 290)) || Contents()->GetFMData(FM_Aim)>0)
       //  && maxdist != 300 && ObjectDistance(target) < 300
)
    {
      if(!IsAiming()) StartSquatAiming();
      if(IsAiming())
      {
      //Log("zielen > 0 wird ausgeführt");
      var tx = target->GetX();
    var ty = target->GetY();
   
        if(Contents()->GetBotData(BOT_Ballistic))
          ty -= 15;
   
    DoMouseAiming(tx, ty);
      }
    }
    else
      if(IsAiming())
        StopAiming();
  }
  if(IsAiming() && !CheckAmmo(Contents()->GetFMData(FM_AmmoID), Contents()->GetFMData(FM_AmmoLoad), Contents(), this()))
     StopAiming();
}

   // Gut. Feuern wir bereits?
  if(Contents()->IsRecharging() || Contents()->IsShooting()) return();

  // Feuer!
  if(maxdist != 300 && pathfree) Control2Contents("ControlThrow");
//  Message("@My target: %s @%d/%d with level %d", this(), target->GetName(), target->GetX(), target->GetY(), level);
  // Stufe 2 - verfolgen!
  if(EffectVar(0, this(), no) >= 2)
    if(GetMacroCommand(1) ne "Follow" || GetMacroCommand(1, 1) != target)
      if(GetMacroCommand(0) ne "Follow" || GetMacroCommand(0,1) != target)
      {
        DebugLog("FxAggroFire - Adding Follow command","aggro");
        AddMacroCommand(0, "MoveTo", 0, GetX(),GetY(), 0, level);
        AddMacroCommand(0, "Follow", target, 0, 0, 0, level);
      }
  //Log("sollte gefeuert haben?");
}


Die funktion selectweapon braucht nur eine kleine Anpassung. hier mal die Funktion bis zur anpassung. Das was in der funktion danach folgt habe ich nicht verändert:
public func SelectWeapon(int iLevel, object pTarget, bool fFireModes)
{
  //Log("Selectweapon wird geprüft");
  // Entfernung zum Ziel
  var dist = ObjectDistance(pTarget);
  // Keine Waffen in Inventar?
  if(!CustomContentsCount("IsWeapon")) return();
  // Bevorzugten Schadenstyp bestimmen
  var preftype = GetPrefDmgType(pTarget), type;
  // Alle durchgehen und passende prüfen
  for(var i=0,obj,fav,mode,favmode ; obj = Contents(i) ; mode++)
  {
    // Nix Waffe
    if(!(obj->~IsWeapon())) { i++; mode = -1; continue; }
    // Feuermodus
    if(mode && !fFireModes) { i++; mode = -1; continue; }
    if(!(obj->GetFMData(FM_Name, mode))) { i++; mode = -1; continue; }
    if(mode == obj->GetFireMode() && mode) continue;
    // Nix gut… Hier wird jetzt auch die Aim Action von Bazooka und Co erkannt, weil damit sonst nicht geschossen wird -.-
    if(obj->GetFMData(FM_Aim, mode)>0)
      if(iLevel == 1 || (!WildcardMatch(GetAction(), "Walk") && !WildcardMatch(GetAction(), "Aim")))
        continue;


Ja ich glaube das wars an Änderungen im Hazradclonk skript :slight_smile:

Ein Hazard appendto in strict im Hazard Ships pack, sorgt dafür, dass Hazardclonks die Munition wieder ablegen können. Ich glaub ich habs für meine Zwecke noch ein wenig angepasst… mindestens neue Munitionsarten hab ich zugefügt.

Falls du das reinnehmen willst ins hazardpack… muss man natürlich iwie drauf achten, dass es trotzdem noch kompatibel zu den ganzen Packs ist, die drauf aufbauen… also z.b auch für das Hazard Ships pack… naja, du wirst schon wissen, was okay ist und was nicht :slight_smile:

local ammobag;

protected func ContextAmmobag(object pCaller)
{
  [$AmmoBag$|Image=STAP|Condition=AmmoBagContextCheck]
  var ammo, x;
  //Menü erzeugen
  CreateMenu(STAP,this(),0,0,GetName(0,ABAG),0,1,1);
  //Munition finden und hinzufügen
  while(ammo = Contents(x,ammobag))
  {
    // nur Ammo
    if(!(ammo ->~IsAmmo())) continue;
    //hinzufügen
    AddMenuItem(GetName(ammo),Format("PackAmmo(%i);",GetID(ammo)), GetID(ammo), this(), GetAmmo(GetID(ammo)),0,GetDesc(ammo));
    //Zählervariable erhöhen
    x++;
  }
  return(1);
}

protected func PackAmmo(ammo)
{
  var packed,pack_id,in_ammobag;
  if(ammo==STAM){ pack_id=STAP; packed=pack_id->AmmoCount();}
  if(ammo==ENAM){ pack_id=ENAP; packed=pack_id->AmmoCount();}
  if(ammo==GRAM){ pack_id=GRAP; packed=pack_id->AmmoCount();}
  if(ammo==GSAM){ pack_id=GSAP; packed=pack_id->AmmoCount();}
  if(ammo==MIAM){ pack_id=MIAP; packed=pack_id->AmmoCount();}
  if(ammo==SSTM){ pack_id=STLM; packed=pack_id->AmmoCount();}
  if(ammo==SHTM){ pack_id=SHMU; packed=pack_id->AmmoCount();}
  if(ammo==SPBT){ pack_id=SNI_; packed=pack_id->AmmoCount();}
  if(ammo==PTAM){ pack_id=PTAP; packed=pack_id->AmmoCount();}
  in_ammobag=GetAmmo(ammo);
  if(packed<=in_ammobag)
  {
    Sound("Click");
    DoAmmo(ammo,-packed);
    CreateObject(pack_id,AbsX(GetX()),AbsY(GetY()),GetOwner());
    ContextAmmobag(this());
    return(1);
  }
        if(packed>in_ammobag && 0<in_ammobag)
        {
  var muni=CreateObject(pack_id,AbsX(GetX()),AbsY(GetY()),GetOwner());
        muni ->~ RestAmmoreduzieren(packed-in_ammobag); // muni im paket wird um diese Zahl reduziert
  Sound("Click");
        DoAmmo(ammo,-in_ammobag);
        ContextAmmobag(this());
  return(1);
        }
  Sound("CommandFailure1");
  return(0);
}


Und das Skript für das Munitionspaket in strict sieht wie folgt aus. Es sorgt halt dafür, dass man die munition teilweise aufnehmen kann und der Restwert im pack gespeichert wird und der Geldwert entsprechend berechnet wird. Zusätzlich noch ein paar kleinigkeiten wie einen Sound wenn es aufkommt und die möglichkeit, dass es explodiert. (übernimm, was du übernehmem möchtest :slight_smile: ) :


local verbraucht, value, restmunition, faktor;

public func IsAmmoPacket() { return(true); }
public func AmmoID()       { return(STAM); }
public func AmmoCount()    { return(50); }
public func AmmoCountRest() {return(AmmoCount()-verbraucht); }

// Damit eine variable Menge ausgegeben wird:
/* Initialisierung /

protected func Initialize()
{
  restmunition=AmmoCount();
  value = GetDefCoreVal("Value", "DefCore");
  faktor = (value
100)/restmunition;
}

/* Wert & Verkauf /

protected func CalcValue()
{
  var lastvalue = value;
  value = (restmunition
faktor)/100;
  return(lastvalue);
}

public HasAdditionalDesc: return(1);

public GiveAdditionalDesc:
  return(Format("Inhalt: %d Munition",restmunition));

func RestAmmoreduzieren(zahl)
{
verbraucht+=zahl;
//Log("Ammo reduziert");
restmunition=AmmoCountRest();
if(restmunition<=0) RemoveObject();
return(1);
}

protected func Hit()
{
Sound("RockHit*");
return (1);
}

private func OnTransfer() {}

protected func Activate(object pObj) {    // Doppelgraben
  return(TransferAmmo(pObj));
}

public func MayTransfer(object pObj)
{
  if(!pObj) return(false);
  var MaxAmmo;
  MaxAmmo = AmmoID()->~MaxAmmo(pObj);
  if(MaxAmmo)
// geändert, weil durch variable werte immer das maximum erreicht werden kann
    if(GetAmmo(AmmoID(),pObj) == MaxAmmo)
      return(false);
  return(true);
}

public func TransferAmmo(object pObj)    // Ammo dem Clonk geben
{
if(GetID(pObj)!=HZCK) {PlayerMessage(GetOwner(pObj),"Nur Hazardclonks können Munition aufnehmen",pObj); return(0);}

  var MaxAmmo;
  MaxAmmo = AmmoID()->~MaxAmmo(pObj);

  if(!pObj) return(false);
  if(NoAmmo()) return(false);
 
  // nicht wenn er schon zu viel hat
  if(!MayTransfer(pObj)) {
    PlayerMessage(GetOwner(pObj),"$NotMoreAmmo$",pObj,AmmoID());
    return();
  }

    if(GetAmmo(AmmoID(),pObj) + AmmoCountRest() <= MaxAmmo)
{
  // Nachricht ausgeben
  HelpMessage(GetOwner(pObj),"$Collected$",pObj,AmmoCountRest(),AmmoID());
  DoAmmo(AmmoID(),AmmoCountRest(),pObj);
  pObj->~AmmoTransferred();
  if(!OnTransfer()) RemoveObject();
  return(true);}

// wird auf MaxAmmo aufgestockt und die Restmunition im Pack reduziert
    if(GetAmmo(AmmoID(),pObj) + AmmoCountRest() > MaxAmmo)
{
var zahl=(MaxAmmo-GetAmmo(AmmoID(),pObj));
  // Nachricht ausgeben
  HelpMessage(GetOwner(pObj),"$Collected$",pObj,(MaxAmmo-GetAmmo(AmmoID(),pObj)),AmmoID());
  DoAmmo(AmmoID(),(MaxAmmo-GetAmmo(AmmoID(),pObj)),pObj);
  pObj->~AmmoTransferred();
  if(!OnTransfer()) {RestAmmoreduzieren(zahl);}

  return(true);}

}

protected func Damage()
{
  // Explodiert nicht, wenn er von einem Clonk getragen wird (Sonderregel gegen T-Flint-Superjumps)
  if (Contained())
    if (Contained()->~IsClonk())
    {
      Extinguish();
      return(0);
    }
  // Explosion - verzögert, um Endlosrekursion zu verhindern
  Schedule("Explode(20)", 1);
  return(1);
}

// Entzündet sich bei Explosionstreffer
public func OnShockwaveHit(level, x, y)
{
Incinerate();
}

public func IsRefineryProduct() { return(1); }

Hier mal ne kleine Liste, von der dich vllt was interessieren könnte, vllt auch nicht ^^ :

Was hälst du von einer Möglichkeit die Zündzeit von Granaten aus dem Granatwerfer einstellen zu können?
Ich hab dazu ein Clonk append geschrieben, um ein Menü aufrufen zu können. Wenn man nen Granatwerfer trägt, kann man damit dann halt die Zündzeit einstellen, wann die Granate explodieren soll (bisher hat ja jede granate eingestellte standardwerte… bei manchen sind diese meiner meinung nach aber oft zu kurz, oder auch mal zu lang, weshalb ich das eben eingebaut hab.

Ansonsten hab ich vom Flammernwerfer den Flammenball wieder aktiviert (warum war der deaktivert, ist er zu stark?) und hab die möglichkeit zugefügt auch pflanzen in Brand zu stecken und Eis zu schmelzen… aber ich glaub das brauchste fürs hazardpack nicht ^^

Außerdem hab ich für jede Waffe einen “nur Gebäude” Modus eingebaut. Man macht dann entweder nur clonks schaden, oder nur gebäuden. Ist für hazard vermutlich aber auch nicht wichtig ^^

Bei den Minen habe ich Fake-Minen zugefügt. Sind im prinzip dieselben Minen, nur dass sie nicht explodieren bzw. eine FakeExplosion verwenden und keinen schaden machen. Ist ganz nett um Gegner zu täuschen.

Achso bezüglich der Aliens, die zu schnell sterben: Ich denke dazu testest du selbst mal, wie schnell die Aliens sterben, wenn du ihnen Dinge gegen den Kopf schmeißt :wink: Ich glaub Jumper sterben sofort und Berserker nach 2-3 Treffern oderso… Also gegebenenfalls die Melee Resistenz erhöhen.  Ach und vllt noch zufügen, dass Leichen von Berserken und Co verroten (also kleiner werden und verschwinden). 

Da du ja vermutlich der hauptentwickler von Hazard bist: Ich finde euer Pack super toll! :D  Besonders die Lichteffekte gefallen mir, da es in meinem Pack auch Tag und dunkle nacht mit wechselndem Kriegsnebel usw gibt :slight_smile: Leider leider sorgen viele lichtkegel für starken Lag, was ich hier schon angesprochen hatte: https://clonkspot.org/forum/topic_show.pl?tid=402  (da siehst du auch einen Screenshot von meinem Pack)  Vllt kannst du ja zu den bisherigen Antworten noch was dazu zu sagen :)   Ich hab übrigens auch in mein Pack eingebaut, dass man die Farbe/intensität jedes einzelnen Lichtes während des Spiels beliebig verändern kann :smiley: eig nutzlos, aber ich fands lustig xD

Nochmal zu Aliens: Die Würmer sollten noch gefixt werden. Und zwar, wenn man sie zu nah am Kartenrand platziert, wandert ihr Kopf außerhalb der Karte und wird quasi abgetrennt :D  Ich find die Stelle im Skript grad nicht mehr, aber ich hab glaub ich einfach dafür gesorgt, dass sie ihren Kopf niemals zu nah an den Kartenrand bewegen dürfen.

Die Drohne braucht glaube ich auch einen kleinen Fix. Wenn man ihr einen Clonk zum bewachen zugeteilt hat, folgt sie diesem ja. Aber wenn der Clonk ein Gebäude oder Fahrzeug betritt, dreht die Drohne durch :smiley: Sie fliegt dann einfach steil nach oben in die Unendlichkeit und wird iwann wieder zurück geportet ^^  Habe das bisher noch nicht gefixt.

Die Fahrzeuge Shuttle und Panzer: Die verschiedenen Einzelteile sollten in der DefCore einen NoGet und NoSell Eintrag haben. Sonst machen sie Probleme, wenn sie in einem Gebäude sind. Zwar nicht so wichtig für Hazard, aber ich denke das sollte man trotzdem richten.
Achja, wo wir bei NoGet und NoSell sind: das gilt auch für das Lichtobjekt :wink: Wenn man ein leuchtendes objekt in ein Gebäude bringt, kann man sonst das Licht einzeln auswählen ^^

Die Munitionsgürtel
, welche dafür sorgen, dass ein Clonk mehr von einer bestimmmten Munition tragen kann, wolltest du nicht aufnehmen oder? Dachte eig schon, dass die ganz gut ins Pack passen würden. Aber muss ja nicht sein :slight_smile:

Fürs bewachen habe ich unterschiedliche Radien wählbar gemacht. Welchen man wählen sollte hängt dann hauptsächlich von der Reichweite der getragenen waffe ab. Ich denke man kann das menü auch noch schöner gestalten als ich es jetzt gemacht habe (feste wählbare werte), z.b frei einstellbare Werte zwischen 0 und 1000.
Möchtest du das aufnehmen?

Ach und ich habe einen Menüpunkt im Clonk bzw CanAim zugefügt, wenn er eine Waffe dabei hat, kann man einstellen wie präzise man zielen möchte.
Mit der normalen Clonksteuerung sind die Steps ja leider ziemlich groß, sodass ein präzises zielen (besonders bei hohen entfernungen wichtig) fast nicht möglich ist. Bei Jump&Run ist das deutlich einfacher. Deswegen kann man im Menü nun hin und herschalten, ob man die standard großen sprünge haben will, mit denen man relativ schnell anvisieren kann, oder ob man kleine steps haben will, mit denen man präziser zielen kann, was aber dafür etwas länger dauert, weil halt kleine steps ^^
Möchtest du das aufnehmen?

1. Wozu ist das? Den Raketenwerfer soll man ja gerade nicht abfeuern ohne zu zielen

2. Der Check gehört da aber nicht hin. Ich habe stattdessen ein CheckArmed in Collection2, Grab und ControlSpecial hinzugefügt

3. Check! Per Effekt gelöst, danke!


public func Incineration(int iPlr) {
  // Hazardclonks brennen ncht wirklich :wink:
  Extinguish();
  AddFireEffect(this(),30,FIRE_Red,1);
  AddEffect("FireDamage",this,100,1,this,0,30,5,iPlr);
}

protected func FxFireDamageStart(object pTarget, int iEffectNumber, int iTemp, int iDuration, int iDamage, int iPlr)
{
  if(iTemp) return;
  EffectVar(0,pTarget,iEffectNumber) = iDuration;
  EffectVar(1,pTarget,iEffectNumber) = iDamage;
  EffectVar(2,pTarget,iEffectNumber) = iPlr;
}

protected func FxFireDamageTimer(object pTarget, int iEffectNumber, int iEffectTime)
{
  DoDmg(EffectVar(1,pTarget,iEffectNumber), DMG_Fire, pTarget, 1, EffectVar(2,pTarget,iEffectNumber)+1);
 
  if(EffectVar(0,pTarget,iEffectNumber) < iEffectTime)
    return -1;
}

protected func FxFireDamageEffect(string szNewEffectName, object pTarget, int iEffectNumber, int iNewEffectNumber)
{
  if(szNewEffectName S= "FireDamage") return -2;
}

protected func FxFireDamageAdd(object pTarget, int iEffectNumber, string szNewEffectName, int iNewEffectTimer, int iDuration, int iDamage, int iPlr)
{
  EffectVar(0,pTarget,iEffectNumber) = iDuration;
  EffectVar(1,pTarget,iEffectNumber) = iDamage;
  EffectVar(2,pTarget,iEffectNumber) = iPlr;
}


4. Wozu, das macht er doch schon in 5.

5. Check! Funktional gleich eingebaut.
  var hasWeapons = false;
  var hasLoadedWeapon = false;
  for(var i = 0; i < ContentsCount(); i++)
  {
    if(Contents(i)->~IsWeapon())
    {
      hasWeapons = true;
      if(Contents(i)->~GetCharge() > 0)
      {
        hasLoadedWeapon = true;
        break;
      }
    }
  }
   
  if(hasWeapons && !hasLoadedWeapon)
  {
    CheckIdleWeapon();
    return;
  }


6. Ein paar Sachen dazu:

* Du hast //  && maxdist != 300 && ObjectDistance(target) < 300 auskommentiert. Die Stelle liest sich so dass die KI nur auf Targets zielt die näher als 300 px dran sind, wie verstehst du die Zeile? Und warum hast du sie auskommentiert?
* Der Rest hört sich sinnvoll an, übernommen. Kannst Du mir sagen was das genau fixt? (Du hast statt bei !ReadyToFire() direkt gleich am Anfang abzubrechen noch eine ganze Reihe von Dingen ausgeführt)

7. Check. (!WildcardMatch(GetAction(), "Walk") && !WildcardMatch(GetAction(), "Aim*")) durch !(ReadyToAim() || IsAiming()) ersetzt, ansonsten deinen Fix übernommen

> Was hälst du von einer Möglichkeit die Zündzeit von Granaten aus dem Granatwerfer einstellen zu können?


Ne, das möchte ich nicht übernehmen, das wird zu komplex.

>Ansonsten hab ich vom Flammernwerfer den Flammenball wieder aktiviert (warum war der deaktivert, ist er zu stark?) und hab die möglichkeit zugefügt auch pflanzen in Brand zu stecken und Eis zu schmelzen.. aber ich glaub das brauchste fürs hazardpack nicht ^^


Steckt der Flammenwerfer in Hazard keine Pflanzen in Brand? Das wäre schade. Den Flammenball hatten wir glaube ich deaktiviert weil er entweder buggy war und/oder scheiße aussah und niemand den noch polishen wollte. Wie sieht deiner denn aus?

> Außerdem hab ich für jede Waffe einen "nur Gebäude" Modus eingebaut. Man macht dann entweder nur clonks schaden, oder nur gebäuden. Ist für hazard vermutlich aber auch nicht wichtig ^^


Ja.

> Bei den Minen habe ich Fake-Minen zugefügt. Sind im prinzip dieselben Minen, nur dass sie nicht explodieren bzw. eine FakeExplosion verwenden und keinen schaden machen. Ist ganz nett um Gegner zu täuschen.


Nette Idee, passt aber nicht so recht ins Hauptpack.

> Achso bezüglich der Aliens, die zu schnell sterben: Ich denke dazu testest du selbst mal, wie schnell die Aliens sterben, wenn du ihnen Dinge gegen den Kopf schmeißt ;) Ich glaub Jumper sterben sofort und Berserker nach 2-3 Treffern oderso... Also gegebenenfalls die Melee Resistenz erhöhen.  Ach und vllt noch zufügen, dass Leichen von Berserken und Co verroten (also kleiner werden und verschwinden). 


Werde ich untersuchen. Die Berserkerleiche fadet jetzt auch aus.

> Lichter


Siehe Zapper, Sven2 und Co. Da kann man leider nichts machen, außer die Lichter auszuschalten.

> Wurm


Ist notiert.

> Die Drohne


Die habe ich schon komplett überarbeitet. Mal die Betaversion auf Clonkforge angeguckt?

> NoGet und NoSell


Ist notiert.

> Die Munitionsgürtel


Naja, gibts denn da ne hübsche Grafik dazu? Hast du da dann 6 verschiedene Gürtel oder wie?

> Fürs bewachen habe ich unterschiedliche Radien


Eher nicht, aber ich meine man kann noch andere Parameter festlegen, e.g. wie aggressiv der Clonk sein soll. Ob er nur rumsteht und schießt oder ob er sich auch umherbewegt, habe ich das richtig in Erinnerung?
Dann könnte man einen zweiten Modus hiinzufügen, "Defend position" und "Look out for enemies" oder sowas.

> Menüpunkt im Clonk bzw CanAim zugefügt


Nein, gleiches Argument wie bei den einstellbaren Granaten. Ich will es simpel halten.

Das hört sich sinnvoll an. Ich werde es mir anschauen.

> Achja, wo wir bei NoGet und NoSell sind: das gilt auch für das Lichtobjekt ;) Wenn man ein leuchtendes objekt in ein Gebäude bringt, kann man sonst das Licht einzeln auswählen


Lichter haben schon NoGet und NoSell.

Ich antworte mal auf diesen Post, ohne die anderen antworten von dir gelesen zu haben.

>1. Wozu ist das? Den Raketenwerfer soll man ja gerade nicht abfeuern ohne zu zielen


Ich bin mir gerade nicht sicher, wie sich das auf die Möglichkeiten des Abfeuerns auswirkt… aber ich konnte mit meinen veränderungen die Bazooka nicht ohne zu zielen abfeuern. Der Sinn der Änderung ist, dass im FxAggroFire die funktion readytofire geprüft wird. Und mit einer Bazooka in der Hand wäre der Clonk dann niemals ready to fire (man kann ihn in den zielmodus versetzen, aber wenn man ihm dann den befehl zum bewachen gibt, beendet er den zielmodus -> ich glaube ohne diese anpassung gehts nicht)
edit2: wobei… ich erinnere mich, dass ich kurzzeitig tatsächlich probleme damit hatte, dass die bazooka ohne zu zielen während des laufens abfeuerbar war… ich weiß aber nicht mehr, was ich dagegen gemacht habe…

>2. Der Check gehört da aber nicht hin. Ich habe stattdessen ein CheckArmed in Collection2, Grab und ControlSpecial hinzugefügt


Ich hab ihn da eingefügt, weil die fkt ja durch einen timer alle x sekunden ausgeführt wird. Dadurch wäre es egal, was man drückt oder nicht drückt. Wird es bei deiner Umsetzung denn jetzt ausgeführt, wenn die Waffe gerade frisch aufgenommen wurde?  Ich bin mir wie gesagt nicht mehr sicher, aber ich glaube das Problem war halt, dass obwohl der Clonk eine Waffe dabei hatte, seine Action nicht Walkarmed war. Erst wenn er sich bewegt wird die action gesetzt. Dh. man brauch etwas, dass die action auch dann setzt, wenn man überhaupt nichts mit dem clonk macht. Ist das in deiner Lösung der Fall (bin mir grad nicht mehr sicher, wann collection2 und grab aufgerufen werden)

>4. Wozu, das macht er doch schon in 5.


Theoretisch gut denkbar, dass ich manches überflüssigerweise doppelt gemacht habe, nach dem motto doppelt hält besser :D
Habs grad getestet und ja, es funzt auch ohne :D

>6. Ein paar Sachen dazu:


    >Du hast //  && maxdist != 300 && ObjectDistance(target) < 300 auskommentiert. Die Stelle liest sich so dass die KI nur auf Targets zielt die näher als 300 px dran sind, wie verstehst du die Zeile? Und warum hast du sie auskommentiert?

Das hab ich quasi in einem späteren Post beantwortet. hatte erst nicht dran gedacht ^^ Und zwar soll die Distanz bei mir individuell einstellbar sein.

>Der Rest hört sich sinnvoll an, übernommen. Kannst Du mir sagen was das genau fixt? (Du hast statt bei !ReadyToFire() direkt gleich am Anfang abzubrechen noch eine ganze Reihe von Dingen ausgeführt)


ich weiß leider nicht mehr, warum ich das !ReadytoFire so weit nach unten verschoben habe und kann es gerade auch nicht ganz nachvollziehen… Zusätzlich hab ich ja einen if ReadytoFire Block um die Fahrzeugsteuerung gemacht. Auch das kann ich gerade nicht mehr nachvollziehen, warum ich das gemacht habe, denn in der RadytoFire funktion selbst, wird Contained() und Riding ja direkt berücksichtigt.
Das ist immer so eine Sache, mit der ich zu kämpfen habe, wenn ich mich länger nicht mehr mit meinem Geschreibsel beschäftigt habe :D Ich weiß dann nicht, ob ich damals mist gebaut habe, weils halt alles noch so neu für mich war, oder ob ich nur meine damaligen guten gründe nicht mehr weiß :D  Also würde ich sagen, schau du nochmal, was deiner Meinung nach mehr Sinn ergibt…
edit2:… ich glaube ich hatte die !readytofire funktion nach unten verschoben, bevor ich die funktion selbst für die bazooka angepasst hatte. Jetzt wo sie für bazooka angepasst ist, sollte die position weiter vorne wieder okay sein.

edit:
Um ganz sicher zu gehen, dass dir meine fixes nicht das Paket versauen, teste sie am besten alle erstmal in einer neuen Kopie :D