-
[Scripting] Eigenen TA schreiben
Hallo zusammen,
Ich würde gerne einen neuen TA schreiben, den ich in meinen Scipten einfach benutzen kann. Dabei soll die Animation abgespielt werden, die man beim Ausbuddeln von Piratenschätzen hat. Jetzt hab ich gehört, dass ich dafür vom Prinzip nur ein Script anlegen muss, was ja auch logisch klingt, ist ja im Endeffekt alles schon vorhanden.
Ich dachte mir, dass es am sinnvollsten wäre das ZS_Stand_Sweeping Script zu einem ZS_Stand_Digging Script umzubauen.
Code:
func void ZS_Stand_Sweeping ()
{
Perception_Set_Normal();
B_ResetAll (self);
AI_SetWalkmode (self,NPC_WALK);
if (Npc_GetDistToWP (self,self.wp) > TA_DIST_SELFWP_MAX)
{
AI_GotoWP (self, self.wp);
};
if (Npc_HasItems (self,ItMi_Broom) == 0)
{
CreateInvItem (self,ItMi_Broom);
};
self.aivar[AIV_TAPOSITION] = NOTINPOS;
};
func int ZS_Stand_Sweeping_Loop ()
{
if (Npc_IsOnFP (self, "SWEEP"))
{
AI_AlignToFP (self);
if (self.aivar[AIV_TAPOSITION] == NOTINPOS_WALK)
{
self.aivar[AIV_TAPOSITION] = NOTINPOS;
};
}
else if (Wld_IsFPAvailable(self,"SWEEP"))
{
AI_GotoFP (self, "SWEEP");
AI_StandUp (self);
AI_AlignToFP (self);
self.aivar[AIV_TAPOSITION] = NOTINPOS_WALK;
}
else
{
AI_AlignToWP (self);
if (self.aivar[AIV_TAPOSITION] == NOTINPOS_WALK)
{
self.aivar[AIV_TAPOSITION] = NOTINPOS;
};
};
if (self.aivar[AIV_TAPOSITION] == NOTINPOS)
{
AI_UseItemToState (self,ItMi_Broom,1);
self.aivar[AIV_TAPOSITION] = ISINPOS;
};
return LOOP_CONTINUE;
};
func void ZS_Stand_Sweeping_End ()
{
AI_UseItemToState (self, ItMi_Broom, -1);
};
Das Grundprinzip verstehe ich, ich ersetze den Besen durch eine Spitzhacke, blablabla.
Aber das Script benutzt ja einfach dieses "SWEEP" - woher weiß ich denn jetzt was ich da sinnvollerweise für meine gewünschte Animation eintrage?
Oder ist das der falsche Ansatz?
Liebe Grüße
"Es ist nicht schwer, von jedem ethischen Prinzip zu beweisen, dass es in der Praxis scheitern muss, wenn man zugleich voraussetzt, dass allgemeiner Schwachsinn herrscht."
- John Stuart Mill
-
Im Spacer sind für den Tagesablauf Freepoints gesetzt, welche im Namen SWEEP stehen haben, also setze im Spacer bei den Welten deiner Mod halt Freepoints, welche zB TREASURE im Namen haben und pass dein TA Skript entsprechend an oder du lässt deine NPC halt nur an ihrem im TA festgelegten Waypoint buddeln.
-
Zitat von Moe
Im Spacer sind für den Tagesablauf Freepoints gesetzt, welche im Namen SWEEP stehen haben, also setze im Spacer bei den Welten deiner Mod halt Freepoints, welche zB TREASURE im Namen haben und pass dein TA Skript entsprechend an oder du lässt deine NPC halt nur an ihrem im TA festgelegten Waypoint buddeln.
Ja gut, dass die FPs in meinem Fall dann "Digging" im Namen haben müssen ist ja eine Sache. Das ist ja nicht das Problem.
Ich weiß nur nicht, wie ich die Animation selbst im Script hinterlege...
Also im Endeffekt. Wie lege ich denn fest welche Animation für das TA Script abgerufen wird?
"Es ist nicht schwer, von jedem ethischen Prinzip zu beweisen, dass es in der Praxis scheitern muss, wenn man zugleich voraussetzt, dass allgemeiner Schwachsinn herrscht."
- John Stuart Mill
-
Zitat von Xardas1001
Ja gut, dass die FPs in meinem Fall dann "Digging" im Namen haben müssen ist ja eine Sache. Das ist ja nicht das Problem.
Ich weiß nur nicht, wie ich die Animation selbst im Script hinterlege...
Also im Endeffekt. Wie lege ich denn fest welche Animation für das TA Script abgerufen wird?
Groß- und Kleinschreibung ist meines Wissens nach wichtig, also DIGGING im Spacer und auch in den Skripten.
AI_PlayAni(self,"Ani einsetzen");
Für Beispiele die Skripte nach AI_PlayAni durchsuchen.
Anis:
Code:
// ---------------------------------------------------------------------------------------------------------------
// Schatzsuchen
ani ("t_TREASURE_Stand_2_S0" 1 "s_TREASURE_S2" 0.1 0.0 M. "Hum_TREASURE_A01.asc" F 0 15)
{
*eventTag (5 "DEF_INSERT_ITEM" "ZS_LEFTHAND")
}
ani ("s_TREASURE_S0" 1 "t_TREASURE_S0_2_S1" 0.0 0.0 M. "Hum_TREASURE_A01.asc" F 15 15)
ani ("t_TREASURE_S0_2_Stand" 1 "" 0.0 0.1 M. "Hum_TREASURE_A01.asc" R 0 15)
{
*eventTag (5 "DEF_REMOVE_ITEM")
}
ani ("t_TREASURE_S0_2_S1" 1 "s_TREASURE_S1" 0.0 0.0 M. "Hum_TREASURE_A01.asc" F 15 15)
ani ("s_TREASURE_S1" 1 "t_TREASURE_S0_2_Stand" 0.0 0.0 M. "Hum_TREASURE_A01.asc" F 15 15)
ani ("s_TREASURE_S2" 1 "s_TREASURE_S3" 0.0 0.0 M. "Hum_TREASURE_A01.asc" F 15 75)
{
*eventPFX (44 1 "CPFX_IAI_STONE" "ZS_RIGHTHAND" )
*eventSFX (44 "pickore" R:1000 EMPTY_SLOT)
}
ani ("s_TREASURE_S3" 1 "s_TREASURE_S4" 0.0 0.0 M. "Hum_TREASURE_A01.asc" F 15 75)
{
*eventPFX (44 1 "CPFX_IAI_STONE" "ZS_RIGHTHAND" )
*eventSFX (44 "pickore" R:1000 EMPTY_SLOT)
}
ani ("s_TREASURE_S4" 1 "s_TREASURE_S0" 0.0 0.0 M. "Hum_TREASURE_A01.asc" F 15 75)
{
*eventPFX (44 1 "CPFX_IAI_STONE" "ZS_RIGHTHAND" )
*eventSFX (44 "pickore" R:1000 EMPTY_SLOT)
}
aniAlias ("t_TREASURE_S1_2_S0" 1 "s_TREASURE_S0" 0.0 0.0 M. "t_TREASURE_S0_2_S1" R)
aniAlias ("t_TREASURE_STAND_2_S1" 1 "t_TREASURE_S1_2_STAND" 0.0 0.0 M. "t_dontknow" F)
ani ("t_TREASURE_S1_2_STAND" 1 "" 0.0 0.0 M. "Hum_TREASURE_A01.asc" F 0 0)
-
Zitat von Moe
Groß- und Kleinschreibung ist meines Wissens nach wichtig, also DIGGING im Spacer und auch in den Skripten.
AI_PlayAni(self,"Ani einsetzen");
Für Beispiele die Skripte nach AI_PlayAni durchsuchen.
Anis:
Code:
// ---------------------------------------------------------------------------------------------------------------
// Schatzsuchen
ani ("t_TREASURE_Stand_2_S0" 1 "s_TREASURE_S2" 0.1 0.0 M. "Hum_TREASURE_A01.asc" F 0 15)
{
*eventTag (5 "DEF_INSERT_ITEM" "ZS_LEFTHAND")
}
ani ("s_TREASURE_S0" 1 "t_TREASURE_S0_2_S1" 0.0 0.0 M. "Hum_TREASURE_A01.asc" F 15 15)
ani ("t_TREASURE_S0_2_Stand" 1 "" 0.0 0.1 M. "Hum_TREASURE_A01.asc" R 0 15)
{
*eventTag (5 "DEF_REMOVE_ITEM")
}
ani ("t_TREASURE_S0_2_S1" 1 "s_TREASURE_S1" 0.0 0.0 M. "Hum_TREASURE_A01.asc" F 15 15)
ani ("s_TREASURE_S1" 1 "t_TREASURE_S0_2_Stand" 0.0 0.0 M. "Hum_TREASURE_A01.asc" F 15 15)
ani ("s_TREASURE_S2" 1 "s_TREASURE_S3" 0.0 0.0 M. "Hum_TREASURE_A01.asc" F 15 75)
{
*eventPFX (44 1 "CPFX_IAI_STONE" "ZS_RIGHTHAND" )
*eventSFX (44 "pickore" R:1000 EMPTY_SLOT)
}
ani ("s_TREASURE_S3" 1 "s_TREASURE_S4" 0.0 0.0 M. "Hum_TREASURE_A01.asc" F 15 75)
{
*eventPFX (44 1 "CPFX_IAI_STONE" "ZS_RIGHTHAND" )
*eventSFX (44 "pickore" R:1000 EMPTY_SLOT)
}
ani ("s_TREASURE_S4" 1 "s_TREASURE_S0" 0.0 0.0 M. "Hum_TREASURE_A01.asc" F 15 75)
{
*eventPFX (44 1 "CPFX_IAI_STONE" "ZS_RIGHTHAND" )
*eventSFX (44 "pickore" R:1000 EMPTY_SLOT)
}
aniAlias ("t_TREASURE_S1_2_S0" 1 "s_TREASURE_S0" 0.0 0.0 M. "t_TREASURE_S0_2_S1" R)
aniAlias ("t_TREASURE_STAND_2_S1" 1 "t_TREASURE_S1_2_STAND" 0.0 0.0 M. "t_dontknow" F)
ani ("t_TREASURE_S1_2_STAND" 1 "" 0.0 0.0 M. "Hum_TREASURE_A01.asc" F 0 0)
Klingt einfach, aber in den Scripten, also zumindest in denen ZS_Rake_FP z.B. steht ja nirgends AI_PlayAni.
Und ich habe auch kein Script gefunden, in dem das drin steht.
Auch das Script, dass du hier reingepostet hast - ich hab keine Ahnung wo ich das finden soll... (vielleicht sinnvoll zu erwähnen, dass ich bisher hauptsäschlich Dialoge, Items und NPCs gescriptet habe^^ für mehr als Dialog-Mobsis hat es bisher noch nicht gereicht.)
"Es ist nicht schwer, von jedem ethischen Prinzip zu beweisen, dass es in der Praxis scheitern muss, wenn man zugleich voraussetzt, dass allgemeiner Schwachsinn herrscht."
- John Stuart Mill
-
Was, du durchsuchst die Skripte händisch? Nimm doch notepad++ oder so und geh auf "In Dateien suchen", dann gibst du das Verzeichnis deiner Skripte ein und tippst den Suchbegriff AI_PlayAni ein, fertig.
-
Zitat von Moe
Was, du durchsuchst die Skripte händisch? Nimm doch notepad++ oder so und geh auf "In Dateien suchen", dann gibst du das Verzeichnis deiner Skripte ein und tippst den Suchbegriff AI_PlayAni ein, fertig.
Nagut, das muss man auch erstmal wissen, dass es so ein Programm gibt, oder? (<- blutiger Anfänger...)
Code:
func void ZS_DIGGING_FP ()
{
Perception_Set_Normal();
B_ResetAll (self);
AI_SetWalkmode (self,NPC_WALK);
if (Npc_GetDistToWP (self,self.wp) > TA_DIST_SELFWP_MAX)
{
AI_GotoWP (self, self.wp);
};
if (Npc_HasItems (self, ItMw_2H_Axe_L_01) == 0)
{
CreateInvItem (self, ItMw_2H_Axe_L_01);
};
self.aivar[AIV_TAPOSITION] = NOTINPOS;
};
func int ZS_DIGGING_FP_Loop ()
{
if (Npc_IsOnFP (self, "DIGGING"))
{
AI_AlignToFP (self);
if (self.aivar[AIV_TAPOSITION] == NOTINPOS_WALK)
{
self.aivar[AIV_TAPOSITION] = NOTINPOS;
};
}
else if (Wld_IsFPAvailable(self,"DIGGING"))
{
AI_GotoFP (self, "DIGGING");
AI_PlayAni (self, "S_TREASURE_S1");
AI_StandUp (self);
AI_AlignToFP (self);
self.aivar[AIV_TAPOSITION] = NOTINPOS_WALK;
}
else
{
AI_AlignToWP (self);
if (self.aivar[AIV_TAPOSITION] == NOTINPOS_WALK)
{
self.aivar[AIV_TAPOSITION] = NOTINPOS;
};
};
if (self.aivar[AIV_TAPOSITION] == NOTINPOS)
{
AI_UseItemToState (self,ItMw_2H_Axe_L_01,1);
self.aivar[AIV_TAPOSITION] = ISINPOS;
};
return LOOP_CONTINUE;
};
func void ZS_DIGGING_FP_End ()
{
AI_UseItemToState (self, ItMw_2H_Axe_L_01,1);
};
Mein Script sieht jetzt so aus.
Und - ich kann es selbst kaum glauben, aber die Animation wird immerhin tatsächlich abgespielt. Allerdings nur einmal, und ohne Spitzhacke in der Hand.
Aber das ist ein Fortschritt.
Nur: Wie sorge ich dafür, dass der NPC die Spitzhacke in die Hand nimmt. Und wie sorge ich dafür, dass es einen Loop gibt?
"Es ist nicht schwer, von jedem ethischen Prinzip zu beweisen, dass es in der Praxis scheitern muss, wenn man zugleich voraussetzt, dass allgemeiner Schwachsinn herrscht."
- John Stuart Mill
-
Ich würde es mal mit der ZS_Practice_Sword Methode versuchen, also dass du die Spitzhacke als Waffe den NPCs in die Hand gibst und sie diese, bevor sie die Animation ausführen, ausrüsten sprich gezogen haben müssen. Die Ani von ZS_Practice_Sword wird auch dauernd wiederholt, orientier dich daran.
-
Zitat von Moe
Ich würde es mal mit der ZS_Practice_Sword Methode versuchen, also dass du die Spitzhacke als Waffe den NPCs in die Hand gibst und sie diese, bevor sie die Animation ausführen, ausrüsten sprich gezogen haben müssen. Die Ani von ZS_Practice_Sword wird auch dauernd wiederholt, orientier dich daran.
Damit klappt es ziemlich solide, auf jeden Fall schonmal eine Menge Dank.
Die Hacke hängt zwar in der Luft rum (-.-), und der Loop ist unflüssig, aber es gibt einen Loop. Immerhin das.
Naja, ich bedanke mich schonmal.
Da werd ich mich wohl irgendwann nochmal dransetzen müssen...
"Es ist nicht schwer, von jedem ethischen Prinzip zu beweisen, dass es in der Praxis scheitern muss, wenn man zugleich voraussetzt, dass allgemeiner Schwachsinn herrscht."
- John Stuart Mill
-
Bei SWEEP ist die Animation im Item hinterlegt.
Der Npc benutzt einen Gegenstand (Besen) bis zum Zustand S1 (das ist der Loop wo der sich beim Fegen hin und her dreht).
Du solltest also mal in das Itemskript It_Misc schauen, dir das Besenskript kopieren, unten einfügen und das Visual zu Spitzhacke und den Animationsnamen zu Hacken ändern.
Dann lässt du dieses neue Item in deinem Tagesablauf bis State S1 nutzen und voila.
-
Zitat von Bisasam
Bei SWEEP ist die Animation im Item hinterlegt.
Der Npc benutzt einen Gegenstand (Besen) bis zum Zustand S1 (das ist der Loop wo der sich beim Fegen hin und her dreht).
Du solltest also mal in das Itemskript It_Misc schauen, dir das Besenskript kopieren, unten einfügen und das Visual zu Spitzhacke und den Animationsnamen zu Hacken ändern.
Dann lässt du dieses neue Item in deinem Tagesablauf bis State S1 nutzen und voila.
Ich verstehe deine Herangehensweise, allerdings sehe ich nicht, wo im Skript da die Animation hinterlegt sein soll?
Die einzige Variante, die für mich logisch war, war diese hier:
Code:
/******************************************************************************************/
// Besen zum Fegen
INSTANCE ItMi_Spitzhacke (C_Item)
{
name = "Spitzhacke";
mainflag = ITEM_KAT_NONE;
flags = ITEM_MULTI;
value = Value_Broom;
visual = "ItMw_020_2h_Pickaxe_01.3DS";
material = MAT_WOOD;
scemeName = "BROOM";
on_state[0] = Use_Spitzhacke;
description = name;
TEXT[5] = NAME_Value;
COUNT[5] = value;
};
func void Use_Spitzhacke()
{
AI_PlayAni (self, "S_TREASURE_S1");
};
Die sorgt dann allerdings dafür, dass ich das genau ein einziges mal benutzen kann, bevor alles einfreezt, also nichts mit Loop.
Und leider geschieht auch hier die Situation, dass die Hacke in der Luft schwebt, statt in den Händen gehalten zu werden...
Im Allgemeinen klappt das mit der Variante, das über die Schwertübung zu machen schon ganz gut, wenn das dieses "Grafik"problem nicht wäre, dass die Hacke eben nicht in den Händen gehalten wird.
Oder hab ich das Grundprinzip falsch verstanden?
"Es ist nicht schwer, von jedem ethischen Prinzip zu beweisen, dass es in der Praxis scheitern muss, wenn man zugleich voraussetzt, dass allgemeiner Schwachsinn herrscht."
- John Stuart Mill
-
21.11.2020 18:16
#12
Die bisherigen Hilfestellungen sind etwas irreführend. So einfach ist es nicht, wenn man es auf diesem Weg machen möchte.
Das einfachste wäre wohl wenn es mit einer Spitzhacke sein soll, ein unsichtbares Erzhack mobsi zu setzen, wenn es nicht zu tief ist, sollten das Npcs auch nutzen können. Da kannst du auch das exakt gleiche TA (ZS_Pick_Ore) nutzen. Am besten eine ConditionFunc für den Player false zurückgeben für das Mobsi, wenn es nur für Npcs gedacht ist.
-
Zitat von Falugify
Die bisherigen Hilfestellungen sind etwas irreführend. So einfach ist es nicht, wenn man es auf diesem Weg machen möchte.
Das einfachste wäre wohl wenn es mit einer Spitzhacke sein soll, ein unsichtbares Erzhack mobsi zu setzen, wenn es nicht zu tief ist, sollten das Npcs auch nutzen können. Da kannst du auch das exakt gleiche TA (ZS_Pick_Ore) nutzen. Am besten eine ConditionFunc für den Player false zurückgeben für das Mobsi, wenn es nur für Npcs gedacht ist.
Naja, aber die ZS_Pick_Ore Ani ist ja auch eine andere, als die, die zum Ausgraben von Piratenschätzen verwendet wird. Bei TREASURE wird ja auf den Boden gehackt, beim Erz an die Wand...
Die umgeschriebene Training-ZS funktioniert ja eigentlich ziemlich gut, abgesehen von der Tatsache, dass die Hacke nicht in den Händen liegt, was eigentlich mein absolutes Hauptproblem bei dem Thema momentan ist. Die Animation wird ausgeführt und geloopt. Im Endeffekt genau das, was ich haben will, relativ einfach bewerkstelligt, und unabhängig von Mobsis - dafür halt vom Freepoint.
"Es ist nicht schwer, von jedem ethischen Prinzip zu beweisen, dass es in der Praxis scheitern muss, wenn man zugleich voraussetzt, dass allgemeiner Schwachsinn herrscht."
- John Stuart Mill
-
23.11.2020 23:31
#14
Zitat von Xardas1001
Naja, aber die ZS_Pick_Ore Ani ist ja auch eine andere, als die, die zum Ausgraben von Piratenschätzen verwendet wird. Bei TREASURE wird ja auf den Boden gehackt, beim Erz an die Wand...
Die umgeschriebene Training-ZS funktioniert ja eigentlich ziemlich gut, abgesehen von der Tatsache, dass die Hacke nicht in den Händen liegt, was eigentlich mein absolutes Hauptproblem bei dem Thema momentan ist. Die Animation wird ausgeführt und geloopt. Im Endeffekt genau das, was ich haben will, relativ einfach bewerkstelligt, und unabhängig von Mobsis - dafür halt vom Freepoint.
Hat schon seinen Grund, warum ich die Idee vorschlage.
[Bild: Orepick.jpg]
-
Zitat von Falugify
Übersetzung:
Das Erzhacken passt sich an die Position des Mobs an. Positionierst du es im Boden, wird auch im Boden gehackt.
"Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
-Korallenkette
Berechtigungen
- Neue Themen erstellen: Nein
- Themen beantworten: Nein
- Anhänge hochladen: Nein
- Beiträge bearbeiten: Nein
|