Merge branch 'master' into qteditor

qteditor
Sven Eberhardt 2016-08-06 21:45:19 -04:00
commit 5db45c0f47
62 changed files with 2622 additions and 1781 deletions

View File

@ -0,0 +1,17 @@
[DefCore]
id=Deco_Tree_Deciduous4_Burned
Version=6,1
Category=C4D_StaticBack
Width=80
Height=90
Offset=-40,-45
Vertices=6
VertexX=0,0,0,0,0
VertexY=45,35,20,0,-20,-40
VertexCNAT=8,16,16,16,16,4
VertexFriction=50,25,25,25,25,50
Mass=80
StretchGrowth=1
Oversize=1
Float=1
Rotate=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -0,0 +1,14 @@
/*-- Yet Another Additional Burned Deciduous Tree --*/
#include Library_Plant
#include Library_Tree
public func IsBurnedTree()
{
return true;
}
local Name = "$Name$";
local Touchable = 0;
local BlastIncinerate = 1;
local ContactIncinerate = 3;

View File

@ -0,0 +1,17 @@
[DefCore]
id=Deco_Tree_Deciduous4
Version=6,1
Category=C4D_StaticBack
Width=80
Height=90
Offset=-40,-45
Vertices=6
VertexX=0,0,0,0,0
VertexY=45,35,20,0,-20,-40
VertexCNAT=8,16,16,16,16,4
VertexFriction=50,25,25,25,25,50
Mass=110
StretchGrowth=1
Oversize=1
Float=1
Rotate=1

View File

@ -0,0 +1,28 @@
material tree09_diffuse
{
receive_shadows on
technique
{
pass
{
scene_blend one zero
cull_hardware none
alpha_rejection greater_equal 128
alpha_to_coverage on
ambient 1.0 1.0 1.0 0.0
diffuse 1.0 1.0 1.0 1.0
specular 0 0 0 0 23.5
emissive 0 0 0 0
texture_unit
{
texture tree.png
tex_address_mode wrap
filtering trilinear
}
}
}
}

View File

@ -0,0 +1,22 @@
/*-- Yet Another Additional Deciduous Tree --*/
#include Library_Plant
#include Library_Tree
private func SeedChance() { return 500; }
private func SeedArea() { return 400; }
private func SeedAmount() { return 10; }
local lib_tree_burned = Deco_Tree_Deciduous4_Burned;
public func GetTreetopPosition(pos)
{
return Shape->Rectangle(-30,-30, 60,80)->GetRandomPoint(pos);
}
local Name = "$Name$";
local Touchable = 0;
local BlastIncinerate = 2;
local ContactIncinerate = 6;
local NoBurnDecay = 1;
local Components = {Wood = 4};

View File

@ -0,0 +1 @@
Name=Laubbaum

View File

@ -0,0 +1 @@
Name=Deciduous tree

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 KiB

View File

@ -28,6 +28,7 @@ func Split2Components(...)
func GetComponent(comp_id)
{
var result = inherited(comp_id, ...);
if (GetType(this) == C4V_Def) return result;
if (comp_id == Wood) result += 1 + (GetCon() > 25);
return result;
}

View File

@ -355,7 +355,6 @@ Jump = {
Length = 20,
Delay = 2,
Animation = "Move",
PhaseCall = "CheckStuck",
StartCall = "StartJump",
EndCall = "EndJump",
AbortCall = "EndJump"

View File

@ -74,7 +74,9 @@ private func Sleep()
}
// One last trip, then become invisible
MoveToTarget();
lib_insect_going2sleep = true;
// Insect might have been removed.
if (this)
lib_insect_going2sleep = true;
}
private func SleepComplete()

View File

@ -16,29 +16,28 @@
#include Clonk_Animations
// un-comment them as soon as the new controls work with context menus etc.^
// Context menu
//#include Library_ContextMenu
// Auto production
//#include Library_AutoProduction
// ladder climbing
#include Library_CanClimbLadder
/* Initialization */
protected func Construction()
func Construction()
{
_inherited(...);
SetSkin(0);
AddEffect("IntTurn", this, 1, 1, this);
AddEffect("IntEyes", this, 1, 35+Random(4), this);
AttachBackpack();
iHandMesh = [0,0];
this.hand_display = {};
this.hand_display.hand_mesh = [0,0];
this.hand_display.hand_action = 0;
this.hand_display.both_handed = false;
this.hand_display.on_back = false;
SetSkin(0);
SetAction("Walk");
SetDir(Random(2));
// Broadcast for rules
@ -282,6 +281,19 @@ local iHandMesh;
local fHandAction;
local fBothHanded;
// Mesh attachment handling
local hand_display;
/* Features 4 properties:
hand_mesh: Array of attachment numbers for items on the clonk.
hand_action: Determines whether the clonk's hands are busy if items can be used.
one of three ints: -1, 0 or 1
-1: no items are drawn on the clonk but they are usable
0: items are drawn and can be used
+1: items are not drawn and cannot be used
both_handed: The first item held is held with both hands, so draw the second one differently.
on_back: The first item is currently on the clonk's back, so draw the second one differently (if it also goes on the back).
*/
func OnSelectionChanged(int oldslot, int newslot, bool secondaryslot)
{
AttachHandItem(secondaryslot);
@ -308,9 +320,14 @@ public func DetachObject(object obj)
func DetachHandItem(bool secondary)
{
if(iHandMesh[secondary])
DetachMesh(iHandMesh[secondary]);
iHandMesh[secondary] = 0;
if(this.hand_display.hand_mesh[secondary])
{
DetachMesh(this.hand_display.hand_mesh[secondary]);
var anim = "Close2Hand";
if (secondary) anim = "Close1Hand";
PlayAnimation(anim, CLONK_ANIM_SLOT_Hands + secondary, Anim_Const(0));
}
this.hand_display.hand_mesh[secondary] = 0;
}
func AttachHandItem(bool secondary)
@ -322,32 +339,47 @@ func AttachHandItem(bool secondary)
func UpdateAttach()
{
StopAnimation(GetRootAnimation(6));
if (this.hand_display.hand_mesh)
{
DetachHandItem(0);
DetachHandItem(1);
}
DoUpdateAttach(0);
DoUpdateAttach(1);
}
func DoUpdateAttach(bool sec)
func DoUpdateAttach(int sec)
{
var obj = GetHandItem(sec);
var other_obj = GetHandItem(!sec);
if(!obj) return;
var iAttachMode = obj->~GetCarryMode(this);
if(iAttachMode == CARRY_None) return;
if(iHandMesh[sec])
var attach_mode = obj->~GetCarryMode(this, sec);
if(attach_mode == CARRY_None) return;
if(!sec)
{
DetachMesh(iHandMesh[sec]);
iHandMesh[sec] = 0;
this.hand_display.both_handed = false;
this.hand_display.on_back = false;
}
if(this.hand_display.hand_mesh[sec])
{
DetachMesh(this.hand_display.hand_mesh[sec]);
this.hand_display.hand_mesh[sec] = 0;
}
var bone = "main";
var bone2;
if(obj->~GetCarryBone()) bone = obj->~GetCarryBone(this);
if(obj->~GetCarryBone2()) bone2 = obj->~GetCarryBone2(this);
if(obj->~GetCarryBone()) bone = obj->~GetCarryBone(this, sec);
if(obj->~GetCarryBone2()) bone2 = obj->~GetCarryBone2(this, sec);
else bone2 = bone;
var nohand = 0;
if(!HasHandAction(sec, 1)) nohand = 1;
var trans = obj->~GetCarryTransform(this, sec, nohand);
var nohand = false;
if(!HasHandAction(sec, 1)) nohand = true;
var trans = obj->~GetCarryTransform(this, sec, nohand, this.hand_display.on_back);
var pos_hand = "pos_hand2";
if(sec) pos_hand = "pos_hand1";
@ -355,94 +387,128 @@ func DoUpdateAttach(bool sec)
if(sec) pos_back = "pos_back2";
var closehand = "Close2Hand";
if(sec) closehand = "Close1Hand";
if(!sec) fBothHanded = 0;
var pos_belt = "skeleton_leg_upper.R";
if (sec) pos_belt = "skeleton_leg_upper.L";
var special = obj->~GetCarrySpecial(this);
var special_other;
if(other_obj) special_other = other_obj->~GetCarrySpecial(this);
if(other_obj) special_other = other_obj->~GetCarrySpecial(this, sec);
if(special)
{
iHandMesh[sec] = AttachMesh(obj, special, bone, trans);
iAttachMode = 0;
this.hand_display.hand_mesh[sec] = AttachMesh(obj, special, bone, trans);
attach_mode = 0;
}
if(iAttachMode == CARRY_Hand)
if(attach_mode == CARRY_Hand)
{
if(HasHandAction(sec, 1))
{
iHandMesh[sec] = AttachMesh(obj, pos_hand, bone, trans);
PlayAnimation(closehand, CLONK_ANIM_SLOT_Hands, Anim_Const(GetAnimationLength(closehand)));
this.hand_display.hand_mesh[sec] = AttachMesh(obj, pos_hand, bone, trans);
PlayAnimation(closehand, CLONK_ANIM_SLOT_Hands + sec, Anim_Const(GetAnimationLength(closehand)));
}
}
else if(iAttachMode == CARRY_HandBack)
else if(attach_mode == CARRY_HandBack)
{
if(HasHandAction(sec, 1))
{
iHandMesh[sec] = AttachMesh(obj, pos_hand, bone, trans);
PlayAnimation(closehand, CLONK_ANIM_SLOT_Hands, Anim_Const(GetAnimationLength(closehand)));
this.hand_display.hand_mesh[sec] = AttachMesh(obj, pos_hand, bone, trans);
PlayAnimation(closehand, CLONK_ANIM_SLOT_Hands + sec, Anim_Const(GetAnimationLength(closehand)));
}
else
iHandMesh[sec] = AttachMesh(obj, pos_back, bone2, trans);
{
this.hand_display.hand_mesh[sec] = AttachMesh(obj, pos_back, bone2, trans);
if (!sec)
this.hand_display.on_back = true;
}
}
else if(iAttachMode == CARRY_HandAlways)
else if(attach_mode == CARRY_HandAlways)
{
iHandMesh[sec] = AttachMesh(obj, pos_hand, bone, trans);
PlayAnimation(closehand, CLONK_ANIM_SLOT_Hands, Anim_Const(GetAnimationLength(closehand)));
this.hand_display.hand_mesh[sec] = AttachMesh(obj, pos_hand, bone, trans);
PlayAnimation(closehand, CLONK_ANIM_SLOT_Hands + sec, Anim_Const(GetAnimationLength(closehand)));
}
else if(iAttachMode == CARRY_Back)
else if(attach_mode == CARRY_Back)
{
iHandMesh[sec] = AttachMesh(obj, pos_back, bone2, trans);
this.hand_display.hand_mesh[sec] = AttachMesh(obj, pos_back, bone2, trans);
if (!sec)
this.hand_display.on_back = true;
}
else if(iAttachMode == CARRY_BothHands)
else if(attach_mode == CARRY_BothHands)
{
if(sec) return;
if(HasHandAction(sec, 1) && !sec && !special_other)
{
iHandMesh[sec] = AttachMesh(obj, "pos_tool1", bone, trans);
PlayAnimation("CarryArms", CLONK_ANIM_SLOT_Hands, Anim_Const(obj->~GetCarryPhase(this)));
fBothHanded = 1;
this.hand_display.hand_mesh[sec] = AttachMesh(obj, "pos_tool1", bone, trans);
PlayAnimation("CarryArms", CLONK_ANIM_SLOT_Hands + sec, Anim_Const(obj->~GetCarryPhase(this)));
this.hand_display.both_handed = true;
}
}
else if(iAttachMode == CARRY_Spear)
else if(attach_mode == CARRY_Spear)
{
// This is a one sided animation, so switch to back if not in the main hand
if(HasHandAction(sec, 1) && !sec)
{
this.hand_display.hand_mesh[sec] = AttachMesh(obj, pos_hand, bone, trans);
PlayAnimation("CarrySpear", CLONK_ANIM_SLOT_Hands + sec, Anim_Const(0));
}
else
{
this.hand_display.hand_mesh[sec] = AttachMesh(obj, pos_back, bone2, trans);
if (!sec)
this.hand_display.on_back = true;
}
}
else if(attach_mode == CARRY_Musket)
{
if(HasHandAction(sec, 1) && !sec)
{
PlayAnimation("CarrySpear", CLONK_ANIM_SLOT_Hands, Anim_Const(0));
this.hand_display.hand_mesh[sec] = AttachMesh(obj, "pos_hand2", bone, trans);
PlayAnimation("CarryMusket", CLONK_ANIM_SLOT_Hands + sec, Anim_Const(0), Anim_Const(1000));
this.hand_display.both_handed = true;
}
else
iHandMesh[sec] = AttachMesh(obj, pos_back, bone2, trans);
{
this.hand_display.hand_mesh[sec] = AttachMesh(obj, pos_back, bone2, trans);
if (!sec)
this.hand_display.on_back = true;
}
}
else if(iAttachMode == CARRY_Musket)
else if(attach_mode == CARRY_Grappler)
{
if(HasHandAction(sec, 1) && !sec)
{
iHandMesh[sec] = AttachMesh(obj, "pos_hand2", bone, trans);
PlayAnimation("CarryMusket", CLONK_ANIM_SLOT_Hands, Anim_Const(0), Anim_Const(1000));
fBothHanded = 1;
this.hand_display.hand_mesh[sec] = AttachMesh(obj, "pos_hand2", bone, trans);
PlayAnimation("CarryCrossbow", CLONK_ANIM_SLOT_Hands + sec, Anim_Const(0), Anim_Const(1000));
this.hand_display.both_handed = true;
}
else
iHandMesh[sec] = AttachMesh(obj, pos_back, bone2, trans);
}
else if(iAttachMode == CARRY_Grappler)
{
if(HasHandAction(sec, 1) && !sec)
{
iHandMesh[sec] = AttachMesh(obj, "pos_hand2", bone, trans);
PlayAnimation("CarryCrossbow", CLONK_ANIM_SLOT_Hands, Anim_Const(0), Anim_Const(1000));
fBothHanded = 1;
this.hand_display.hand_mesh[sec] = AttachMesh(obj, pos_back, bone2, trans);
if (!sec)
this.hand_display.on_back = true;
}
else
iHandMesh[sec] = AttachMesh(obj, pos_back, bone2, trans);
}
}//AttachMesh(DynamiteBox, "pos_tool1", "main", Trans_Translate(0,0,0));
else if(attach_mode == CARRY_Belt)
{
// Do some extra transforms for this kind of carrying
if (trans)
trans = Trans_Mul(trans, Trans_Rotate(160,0,0,1), Trans_Rotate(5,0,1), Trans_Rotate(30,1), Trans_Translate(-2500,0,700), Trans_Scale(700));
else
trans = Trans_Mul(Trans_Rotate(160,0,0,1), Trans_Rotate(5,0,1), Trans_Rotate(30,1), Trans_Translate(-2500,0,800), Trans_Scale(700));
this.hand_display.hand_mesh[sec] = AttachMesh(obj, pos_belt, bone, trans);
}
else if(attach_mode == CARRY_Sword)
{
this.hand_display.hand_mesh[sec] = AttachMesh(obj, "skeleton_hips", bone, trans);
}
}
public func GetHandMesh(object obj)
{
if(GetHandItem(0) == obj)
return iHandMesh[0];
return this.hand_display.hand_mesh[0];
if(GetHandItem(1) == obj)
return iHandMesh[1];
return this.hand_display.hand_mesh[1];
}
static const CARRY_None = 0;
@ -454,6 +520,8 @@ static const CARRY_BothHands = 5;
static const CARRY_Spear = 6;
static const CARRY_Musket = 7;
static const CARRY_Grappler = 8;
static const CARRY_Belt = 9;
static const CARRY_Sword = 10;
func HasHandAction(sec, just_wear, bool force_landscape_letgo)
{
@ -461,16 +529,17 @@ func HasHandAction(sec, just_wear, bool force_landscape_letgo)
// sec: Needs both hands (e.g. CarryHeavy?)
// just_wear: ???
// force_landscape_letgo: Also allow from actions where hands are currently grabbing the landscape (scale, hangle)
if(sec && fBothHanded)
if(sec && this.hand_display.both_handed)
return false;
if(just_wear)
{
if( HasActionProcedure(force_landscape_letgo) && !fHandAction ) // For wear purpose fHandAction==-1 also blocks
if( HasActionProcedure(force_landscape_letgo) && !this.hand_display.hand_action )
// For wear purpose this.hand_display.hand_action==-1 also blocks
return true;
}
else
{
if( HasActionProcedure(force_landscape_letgo) && (!fHandAction || fHandAction == -1) )
if( HasActionProcedure(force_landscape_letgo) && (!this.hand_display.hand_action || this.hand_display.hand_action == -1) )
return true;
}
return false;
@ -498,17 +567,17 @@ public func ReadyToAction(fNoArmCheck)
public func SetHandAction(bool fNewValue)
{
if(fNewValue > 0)
fHandAction = 1; // 1 means can't use items and doesn't draw items in hand
this.hand_display.hand_action = 1; // 1 means can't use items and doesn't draw items in hand
else if(fNewValue < 0)
fHandAction = -1; // just don't draw items in hand can still use them
this.hand_display.hand_action = -1; // just don't draw items in hand can still use them
else
fHandAction = 0;
this.hand_display.hand_action = 0;
UpdateAttach();
}
public func GetHandAction()
{
if(fHandAction == 1)
if(this.hand_display.hand_action == 1)
return true;
return false;
}

View File

@ -11,6 +11,7 @@
ID: submenu ID. Unique in combination with the target == this
obj: last object that was shown here
hand: bool, whether select with a hand
quick: bool, whether this is the quick switch slot
*/
// HUD margin and size in tenths of em.
@ -119,6 +120,7 @@ private func UpdateInventory()
// update inventory-slots
var hand_item_pos = clonk->~GetHandItemPos(0);
var quick_switch_slot = clonk->~GetQuickSwitchSlot();
for (var slot_info in inventory_slots)
{
@ -134,8 +136,9 @@ private func UpdateInventory()
custom_overlay = item->~GetInventoryIconOverlay();
}
var needs_selection = hand_item_pos == slot_info.slot;
var needs_quick_switch = quick_switch_slot == slot_info.slot;
var has_extra_slot = item && item->~HasExtraSlot();
if ((!!item == slot_info.empty) || (item != slot_info.obj) || (needs_selection != slot_info.hand) || (stack_count != slot_info.last_count) || has_extra_slot || slot_info.had_custom_overlay || custom_overlay)
if ((!!item == slot_info.empty) || (item != slot_info.obj) || (needs_selection != slot_info.hand) || (needs_quick_switch != slot_info.quick) || (stack_count != slot_info.last_count) || has_extra_slot || slot_info.had_custom_overlay || custom_overlay)
{
// Hide or show extra-slot display?
var extra_slot_player = NO_OWNER;
@ -225,10 +228,12 @@ private func UpdateInventory()
GuiUpdate(update, inventory_gui_id, slot_info.ID, this);
var tag = "Std";
if (needs_quick_switch) tag = "Quick";
if (needs_selection) tag = "Selected";
GuiUpdateTag(tag, inventory_gui_id, slot_info.ID, this);
slot_info.hand = needs_selection;
slot_info.quick = needs_quick_switch;
slot_info.obj = item;
slot_info.empty = !item;
}
@ -275,6 +280,7 @@ private func CreateNewInventoryButton(int max_slots)
slot = slot_number,
ID = slot_number + 1,
hand = false,
quick = false,
obj = nil,
empty = true
};
@ -292,9 +298,19 @@ private func CreateNewInventoryButton(int max_slots)
Style = GUI_TextTop,
Text = Format("%2d", slot_info.slot + 1)
},
quick_switch = // Shows quick switch control key if this is the quick switch slot
{
Priority = 3,
Style = GUI_NoCrop | GUI_TextHCenter | GUI_TextBottom,
Left = "-50%",
Right = "150%",
Top = Format(" %s%s", "20%", ToEmString(-2)),
Bottom = "20%",
Text = { Std = "", Quick = Format("<c dddd00>[%s]</c>", GetPlayerControlAssignment(GetOwner(), CON_QuickSwitch, true)), Selected = "" }
},
Style = GUI_NoCrop,
ID = slot_info.ID,
Symbol = {Std = Icon_Menu_Circle, Selected = Icon_Menu_CircleHighlight},
Symbol = {Std = Icon_Menu_Circle, Quick = Icon_Menu_Circle, Selected = Icon_Menu_CircleHighlight},
Left = pos.Left, Top = pos.Top, Right = pos.Right, Bottom = pos.Bottom,
count =
{

View File

@ -1,7 +1,11 @@
/*-- Cooked Mushroom --*/
/**
Cooked Mushroom
Yummier meal than an uncooked mushroom.
*/
/*-- Engine Callbacks --*/
protected func Construction()
func Construction()
{
this.MeshTransformation = Trans_Rotate(RandomX(0, 359), 0, 1, 0);
}
@ -11,9 +15,9 @@ func Hit()
Sound("Hits::GeneralHit?");
}
/* Eating */
/*-- Eating --*/
protected func ControlUse(object clonk)
public func ControlUse(object clonk)
{
clonk->Eat(this);
return true;
@ -21,9 +25,25 @@ protected func ControlUse(object clonk)
public func NutritionalValue() { return 25; }
/*-- Production --*/
public func IsKitchenProduct() { return true; }
public func GetFuelNeed() { return 50; }
/*-- Display --*/
public func GetCarryMode()
{
return CARRY_Hand;
}
public func GetCarryTransform()
{
return Trans_Scale(750);
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = true;

View File

@ -1,30 +1,20 @@
/*-- Sproutberry --*/
/**
Sproutberry
Fresh from nature's garden.
*/
protected func Hit()
{
Sound("Hits::SoftHit1");
}
/*-- Engine Callbacks --*/
public func Construction()
{
this.MeshTransformation = Trans_Scale(1500, 1500, 1500);
}
/* Eating */
protected func ControlUse(object clonk, int iX, int iY)
func Hit()
{
clonk->Eat(this);
return true;
Sound("Hits::SoftHit1");
}
public func NutritionalValue() { return 5; }
local Name = "$Name$";
local Description = "$Description$";
local Collectible = 1;
// sproutberries are extremely unstable and likely to grow a new plant if not carried
func Departure(object what)
{
@ -32,6 +22,27 @@ func Departure(object what)
AddEffect("SproutCheck", this, 1, 10, this);
}
func SaveScenarioObject(props, ...)
{
// Do not save berries that are still attached to bushes
if (Contained())
if (Contained()->GetID() == SproutBerryBush_Sprout)
return false;
return inherited(props, ...);
}
/*-- Eating --*/
public func ControlUse(object clonk, int iX, int iY)
{
clonk->Eat(this);
return true;
}
public func NutritionalValue() { return 5; }
/*-- Sprouting --*/
func FxSproutCheckTimer(target, effect, time)
{
var c = Contained();
@ -128,12 +139,20 @@ func FxShrinkTimer(target, effect, time)
}
}
// Scenario saving
func SaveScenarioObject(props, ...)
/*-- Display --*/
public func GetCarryMode()
{
// Do not save berries that are still attached to bushes
if (Contained())
if (Contained()->GetID() == SproutBerryBush_Sprout)
return false;
return inherited(props, ...);
return CARRY_Hand;
}
public func GetCarryBone()
{
return "Main";
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = true;

View File

@ -1,10 +1,9 @@
/*
/**
Axe
Author: Ringwaul, Clonkonaut
Used for chopping down trees. Can also harvest
wood from fallen trees, but will not yield as
many logs as a sawmill.
Used for chopping down trees. Can also harvest wood from fallen trees,
but will not yield as many logs as a sawmill.
@author: Ringwaul, Clonkonaut
*/
#include Library_MeleeWeapon
@ -16,40 +15,27 @@ local magic_number;
local movement_effect;
// When using the axe to chop a tree.
local SwingTime = 30;
// When using the axe as a weapon (without trees).
local StrikingLength = 20; // in frames
/*-- Engine Callbacks --*/
private func Hit(int x, int y)
func Hit(int x, int y)
{
StonyObjectHit(x,y);
return 1;
}
public func GetCarryMode() { return CARRY_HandBack; }
public func GetCarryBone() { return "main"; }
public func GetCarryTransform()
func Departure(object container)
{
var act = Contained()->GetAction();
if(act != "Walk" && act != "Jump")
return Trans_Mul(Trans_Translate(4500,0,0), Trans_Rotate(90,1,0,0), Trans_Rotate(180,0,1,0) );
return Trans_Rotate(-90, 1, 0, 0);
}
public func GetCarrySpecial(clonk)
{
if(using == 1)
// Always end the movement impairing effect when exiting
if (movement_effect)
{
if(clonk->GetDir() == 1)
return "pos_hand2";
else
return "pos_hand1";
RemoveEffect(nil, container, movement_effect);
movement_effect = nil;
}
return carry_bone;
}
func RejectUse(object clonk)
/*-- Usage --*/
public func RejectUse(object clonk)
{
return !clonk->IsWalking() && !clonk->IsJumping();
}
@ -61,15 +47,21 @@ func ReadyToBeUsed(proplist data)
return !RejectUse(clonk) && CanStrikeWithWeapon(clonk) && clonk->HasHandAction();
}
public func HoldingEnabled()
{
return GetEffect("IntAxe", this);
}
public func ControlUseStart(object clonk, int iX, int iY)
{
// find tree that is closest to the clonk's axe when swung
/* Chopping */
// Find tree that is closest to the clonk's axe when swung
var x_offs = 10;
if(clonk->GetDir() == DIR_Left) {
x_offs = -x_offs;
}
// Chopping
if (clonk->IsWalking()) for (var tree in FindObjects(Find_AtPoint(x_offs,0), Find_Func("IsTree"), Sort_Distance(x_offs, 0), Find_NoContainer()))
{
//treedist - the x-distance the clonk is from the centre of a tree-trunk
@ -119,7 +111,8 @@ public func ControlUseStart(object clonk, int iX, int iY)
}
}
// Combat
/* Combat */
if(!CanStrikeWithWeapon(clonk) || !clonk->HasHandAction())
{
clonk->PauseUse(this, "ReadyToBeUsed", {clonk = clonk});
@ -150,7 +143,9 @@ public func ControlUseStart(object clonk, int iX, int iY)
}
PlayWeaponAnimation(clonk, animation, 10, Anim_Linear(0, 0, clonk->GetAnimationLength(animation), StrikingLength, ANIM_Remove), Anim_Const(1000));
clonk->UpdateAttach();
Sound("Objects::Weapons::WeaponSwing?", {pitch = -Random(10)});
magic_number=((magic_number+1)%10) + (ObjectNumber()*10);
@ -159,11 +154,7 @@ public func ControlUseStart(object clonk, int iX, int iY)
return true;
}
/* Chopping */
protected func HoldingEnabled() { return GetEffect("IntAxe", this); }
func ControlUseHolding(object clonk, int new_x, int new_y)
public func ControlUseHolding(object clonk, int new_x, int new_y)
{
// Can clonk use axe?
if (!clonk->IsWalking() || GetXDir() != 0)
@ -174,7 +165,33 @@ func ControlUseHolding(object clonk, int new_x, int new_y)
return true;
}
/* Chopping effect */
func ControlUseCancel(object clonk, int ix, int iy)
{
Reset(clonk);
return true;
}
public func ControlUseStop(object clonk, int ix, int iy)
{
Reset(clonk);
return true;
}
public func Reset(clonk)
{
//Reset the clonk to normal control
using = 0;
clonk->SetHandAction(0);
clonk->UpdateAttach();
clonk->SetTurnForced(-1);
clonk->StopAnimation(swing_anim);
swing_anim = nil;
RemoveEffect("IntAxe", clonk);
RemoveEffect("IntSplit", clonk);
RemoveEffect("AxeStrike", clonk);
}
/* Chopping */
func FxIntAxeStart(object clonk, effect, int temp, object target_tree)
{
@ -221,7 +238,7 @@ func FxIntAxeStop(object clonk, effect, int temp)
if (this->Contained() == clonk) Reset(clonk);
}
/* Splitting effect */
/* Splitting */
func FxIntSplitStart(object clonk, effect, int temp, object target_tree)
{
@ -269,32 +286,6 @@ func FxIntSplitStop(object clonk, effect, int temp)
if (this->Contained() == clonk) Reset(clonk);
}
func ControlUseStop(object clonk, int ix, int iy)
{
Reset(clonk);
return true;
}
protected func ControlUseCancel(object clonk, int ix, int iy)
{
Reset(clonk);
return true;
}
public func Reset(clonk)
{
//Reset the clonk to normal control
using = 0;
clonk->SetHandAction(0);
clonk->UpdateAttach();
clonk->SetTurnForced(-1);
clonk->StopAnimation(swing_anim);
swing_anim = nil;
RemoveEffect("IntAxe", clonk);
RemoveEffect("IntSplit", clonk);
RemoveEffect("AxeStrike", clonk);
}
/* Combat */
func CheckStrike(iTime)
@ -383,24 +374,56 @@ func FxAxeStrikeStopTimer(pTarget, effect)
return -1;
}
private func Departure(object container)
{
// Always end the movement impairing effect when exiting
if (movement_effect)
{
RemoveEffect(nil, container, movement_effect);
movement_effect = nil;
}
}
/*-- Production --*/
public func IsTool() { return true; }
public func IsToolProduct() { return true; }
local Collectible = 1;
/*-- Display --*/
public func GetCarryMode(object clonk, bool idle)
{
if (!idle)
return CARRY_HandBack;
else
return CARRY_Belt;
}
public func GetCarryTransform(object clonk, bool idle)
{
if (idle) return;
var act = clonk->GetAction();
if(act != "Walk" && act != "Jump")
return Trans_Mul(Trans_Translate(4500,0,0), Trans_Rotate(90,1,0,0), Trans_Rotate(180,0,1,0) );
return Trans_Rotate(-90, 1, 0, 0);
}
public func GetCarrySpecial(clonk)
{
if(using == 1)
{
if(clonk->GetDir() == 1)
return "pos_hand2";
else
return "pos_hand1";
}
return carry_bone;
}
/*-- Properties --*/
local Collectible = true;
local Name = "$Name$";
local Description = "$Description$";
local Components = {Wood = 1, Metal = 1};
// Damage dealt to trees when chopping.
local ChopStrength = 10;
// Damage dealt to living beings when hit with an axe.
local WeaponStrength = 6;
local Components = {Wood = 1, Metal = 1};
// When using the axe to chop a tree.
local SwingTime = 30;
// When using the axe as a weapon (without trees).
local StrikingLength = 20; // in frames

View File

@ -1,76 +1,29 @@
/*--
/**
Wooden Barrel
Author: Ringwaul, ST-DDT
The barrel is used to transport liquids
--*/
@author: Ringwaul, ST-DDT
*/
#include Library_CarryHeavy
#include Library_LiquidContainer
#include Library_HasExtraSlot
public func GetCarryTransform(clonk)
{
if(GetCarrySpecial(clonk))
return Trans_Translate(1000, 6500, 0);
return Trans_Translate(1500, 0, -1500);
}
public func GetCarryPhase()
{
return 900;
}
/*-- Engine Callbacks --*/
protected func Initialize()
func Initialize()
{
AddTimer("Check", 5);
}
func CollectFromStack(object item)
{
// Callback from stackable object: Try grabbing partial objects from this stack, if the stack is too large
if (item->GetStackCount() > GetLiquidAmountRemaining() && !this->RejectStack(item))
{
// Get one sample object and try to insert it into the barrel
var candidate = item->TakeObject();
candidate->Enter(this);
// Put it back if it was not collected
if (candidate && !(candidate->Contained()))
{
item->TryAddToStack(candidate);
}
}
}
private func RejectStack(object item)
{
// Callback from stackable object: When should a stack entrance be rejected, if the object was not merged into the existing stacks?
if (Contents())
{
// The barrel can hold only one type of liquid
return true;
}
if (item->~IsLiquid() && this->~IsLiquidContainerForMaterial(item->~GetLiquidType()))
{
// The liquid is suitable, collect it!
return false;
}
else
{
// Reject anything else
return true;
}
}
public func RejectCollect(id def, object new_contents)
func RejectCollect(id def, object new_contents)
{
// The barrel can only contain liquids.
if (RejectStack(new_contents)) return true;
return _inherited(def, new_contents, ...);
}
private func Hit()
func Hit()
{
this->PlayBarrelHitSound();
if (Contents())
@ -89,139 +42,57 @@ func PlayBarrelHitSound()
Sound("Hits::Materials::Wood::DullWoodHit?");
}
private func Check()
func Collection2(object item)
{
//Fills Barrel with specified liquid from if submerged
FillWithLiquid();
//Message("Volume:|%d|Liquid:|%s", iVolume, szLiquid);
UpdateLiquidContainer();
return _inherited(item, ...);
}
private func FillWithLiquid()
func Ejection(object item)
{
var intake = this.BarrelIntakeY;
if (!GBackLiquid(0, intake)) return;
if (GetLiquidAmount() >= GetLiquidContainerMaxFillLevel()) return;
var mat = GetMaterial(0, intake);
var mat_name = MaterialName(mat);
if (!IsLiquidContainerForMaterial(mat_name)) return;
UpdateLiquidContainer();
return _inherited(item, ...);
}
var remaining_volume = GetLiquidContainerMaxFillLevel() - GetLiquidAmount();
var extracted = 0;
while(extracted < remaining_volume && GetMaterial(0, intake) == mat)
{
extracted += 1;
ExtractLiquid(0, intake);
}
var inserted = 0;
if (extracted > 0) inserted = PutLiquid(mat_name, extracted);
/*-- Callbacks --*/
if (inserted < extracted)
public func CollectFromStack(object item)
{
// Callback from stackable object: Try grabbing partial objects from this stack, if the stack is too large
if (item->GetStackCount() > GetLiquidAmountRemaining() && !this->RejectStack(item))
{
CastPXS(mat_name, extracted - inserted, 1, 0, intake);
// Get one sample object and try to insert it into the barrel
var candidate = item->TakeObject();
candidate->Enter(this);
// Put it back if it was not collected
if (candidate && !(candidate->Contained()))
{
item->TryAddToStack(candidate);
}
}
}
private func EmptyBarrel(int angle, int strength, object clonk)
public func RejectStack(object item)
{
// Callback from stackable object: When should a stack entrance be rejected, if the object was not merged into the existing stacks?
if (Contents())
{
var material = Contents()->~GetLiquidType();
var volume = Contents()->~GetLiquidAmount();
Contents()->~Disperse(angle, strength);
var spray = {};
spray.Liquid = material;
spray.Volume = volume;
spray.Strength = strength;
spray.Angle = angle;
spray.Clonk = clonk;
AddEffect("ExtinguishingSpray", clonk, 100, 1, this, nil, spray);
UpdateLiquidContainer();
// The barrel can hold only one type of liquid
return true;
}
}
private func UpdateLiquidContainer()
{
if (Contents())
if (item->~IsLiquid() && this->~IsLiquidContainerForMaterial(item->~GetLiquidType()))
{
var color;
var material = Material(Contents()->GetLiquidType());
if (material >= 0)
{
var tex = GetMaterialVal("TextureOverlay", "Material", material);
color = GetAverageTextureColor(tex);
}
else
{
color = RGB(0, 0, 0);
}
SetColor(color);
// The liquid is suitable, collect it!
return false;
}
else
{
SetColor(RGB(0, 0, 0));
// Reject anything else
return true;
}
this.Name = GetNameForBarrel();
return;
}
public func ControlUse(object clonk, int iX, int iY)
{
var AimAngle = Angle(0, 0, iX, iY);
if (Contents())
{
EmptyBarrel(AimAngle, 50, clonk);
if (iX > 1)
Contained()->SetDir(1);
if (iX < -1)
Contained()->SetDir(0);
}
return true;
}
protected func FxExtinguishingSprayStart(object target, proplist effect, int temp, proplist spray)
{
if (temp)
return FX_OK;
// Only for extinguishing materials.
if (!GetMaterialVal("Extinguisher", "Material", Material(spray.Liquid)))
return FX_Start_Deny;
// If used by an object also extinguish that.
if (spray.Clonk)
spray.Clonk->Extinguish(Min(100, spray.Volume/3));
// Store spray parameters.
effect.Volume = spray.Volume;
effect.Strength = spray.Strength;
effect.Angle = spray.Angle;
return FX_OK;
}
protected func FxExtinguishingSprayTimer(object target, proplist effect, int time)
{
// Move three lines from the barrel outwards along the defined angle.
// And extinguish all objects on these lines.
if (time > 20)
return FX_Execute_Kill;
var d = effect.Strength * time / 25;
for (var dev = -10; dev <= 10; dev+= 10)
{
var x = Sin(effect.Angle + dev, d);
var y = -Cos(effect.Angle + dev, d);
if (PathFree(GetX(), GetY(), GetX() + x, GetY() + y))
for (var obj in FindObjects(Find_AtPoint(x, y), Find_OCF(OCF_OnFire)))
obj->Extinguish(Max(0, effect.Volume/3 - 2 * d));
}
return FX_OK;
}
public func IsToolProduct() { return true; }
public func GetLiquidContainerMaxFillLevel()
{
return 300;
@ -250,39 +121,6 @@ public func CanBeStackedWith(object other)
return _inherited(other, ...) && (both_empty || both_filled);
}
func GetNameForBarrel()
{
if (Contents())
{
var name = Format("%s $NameWith$ %s", this.Prototype.Name, Contents().Prototype.Name);
return name;
}
else
{
return this.Prototype.Name;
}
}
public func Definition(proplist def)
{
SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0, 1000, 0), Trans_Rotate(-40, 1, 0, 0), Trans_Rotate(20, 0, 0, 1)), def);
}
func Collection2(object item)
{
UpdateLiquidContainer();
return _inherited(item, ...);
}
func Ejection(object item)
{
UpdateLiquidContainer();
return _inherited(item, ...);
}
// Sells the contents only, leaving an empty barrel.
// Empty barrels can then be sold separately.
public func QueryOnSell(int for_player, object in_base)
@ -299,9 +137,181 @@ public func QueryOnSell(int for_player, object in_base)
return false;
}
local Collectible = true;
/*-- Usage --*/
public func ControlUse(object clonk, int iX, int iY)
{
var AimAngle = Angle(0, 0, iX, iY);
if (Contents())
{
EmptyBarrel(AimAngle, 50, clonk);
if (iX > 1)
Contained()->SetDir(1);
if (iX < -1)
Contained()->SetDir(0);
}
return true;
}
func Check()
{
//Fills Barrel with specified liquid from if submerged
FillWithLiquid();
//Message("Volume:|%d|Liquid:|%s", iVolume, szLiquid);
}
func FillWithLiquid()
{
var intake = this.BarrelIntakeY;
if (!GBackLiquid(0, intake)) return;
if (GetLiquidAmount() >= GetLiquidContainerMaxFillLevel()) return;
var mat = GetMaterial(0, intake);
var mat_name = MaterialName(mat);
if (!IsLiquidContainerForMaterial(mat_name)) return;
var remaining_volume = GetLiquidContainerMaxFillLevel() - GetLiquidAmount();
var extracted = 0;
while(extracted < remaining_volume && GetMaterial(0, intake) == mat)
{
extracted += 1;
ExtractLiquid(0, intake);
}
var inserted = 0;
if (extracted > 0) inserted = PutLiquid(mat_name, extracted);
if (inserted < extracted)
{
CastPXS(mat_name, extracted - inserted, 1, 0, intake);
}
}
func EmptyBarrel(int angle, int strength, object clonk)
{
if (Contents())
{
var material = Contents()->~GetLiquidType();
var volume = Contents()->~GetLiquidAmount();
Contents()->~Disperse(angle, strength);
var spray = {};
spray.Liquid = material;
spray.Volume = volume;
spray.Strength = strength;
spray.Angle = angle;
spray.Clonk = clonk;
AddEffect("ExtinguishingSpray", clonk, 100, 1, this, nil, spray);
UpdateLiquidContainer();
}
}
func UpdateLiquidContainer()
{
if (Contents())
{
var color;
var material = Material(Contents()->GetLiquidType());
if (material >= 0)
{
var tex = GetMaterialVal("TextureOverlay", "Material", material);
color = GetAverageTextureColor(tex);
}
else
{
color = RGB(0, 0, 0);
}
SetColor(color);
}
else
{
SetColor(RGB(0, 0, 0));
}
this.Name = GetNameForBarrel();
return;
}
func FxExtinguishingSprayStart(object target, proplist effect, int temp, proplist spray)
{
if (temp)
return FX_OK;
// Only for extinguishing materials.
if (!GetMaterialVal("Extinguisher", "Material", Material(spray.Liquid)))
return FX_Start_Deny;
// If used by an object also extinguish that.
if (spray.Clonk)
spray.Clonk->Extinguish(Min(100, spray.Volume/3));
// Store spray parameters.
effect.Volume = spray.Volume;
effect.Strength = spray.Strength;
effect.Angle = spray.Angle;
return FX_OK;
}
func FxExtinguishingSprayTimer(object target, proplist effect, int time)
{
// Move three lines from the barrel outwards along the defined angle.
// And extinguish all objects on these lines.
if (time > 20)
return FX_Execute_Kill;
var d = effect.Strength * time / 25;
for (var dev = -10; dev <= 10; dev+= 10)
{
var x = Sin(effect.Angle + dev, d);
var y = -Cos(effect.Angle + dev, d);
if (PathFree(GetX(), GetY(), GetX() + x, GetY() + y))
for (var obj in FindObjects(Find_AtPoint(x, y), Find_OCF(OCF_OnFire)))
obj->Extinguish(Max(0, effect.Volume/3 - 2 * d));
}
return FX_OK;
}
/*-- Production --*/
public func IsToolProduct() { return true; }
/*-- Display --*/
public func GetCarryTransform(clonk)
{
if(GetCarrySpecial(clonk))
return Trans_Translate(1000, 6500, 0);
return Trans_Translate(1500, 0, -1500);
}
public func GetCarryPhase()
{
return 900;
}
public func Definition(proplist def)
{
SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0, 1000, 0), Trans_Rotate(-40, 1, 0, 0), Trans_Rotate(20, 0, 0, 1)), def);
}
/*-- Properties --*/
func GetNameForBarrel()
{
if (Contents())
{
var name = Format("%s $NameWith$ %s", this.Prototype.Name, Contents().Prototype.Name);
return name;
}
else
{
return this.Prototype.Name;
}
}
local Name = "$Name$";
local Description = "$Description$";
local Collectible = true;
local ContactIncinerate = 2;
local BarrelIntakeY = 3;
local Components = {Wood = 2, Metal = 1};
local Components = {Wood = 2, Metal = 1};

View File

@ -1,7 +1,5 @@
/*--
Boompack
Authors: Ringwaul, Newton
A risky method of flight. When the boompack is used and launched towards
the sky, the category of the boompack is changed to be a vehicle and set
to be non-collectible. The clonk is then attached to the boompack. While
@ -9,6 +7,8 @@
inventory: The ControlLeft/Right/Up/Down callbacks are issued to the boom-
pack too. Here, they are used to slightly steer the boompack to the left
or right plus to jump off the rocket.
@author: Ringwaul, Newton
--*/
#include Library_CarryHeavy
@ -20,18 +20,9 @@ local riderattach;
local dirdev;
local controllable;
public func GetCarryMode(clonk) { return CARRY_BothHands; }
public func GetCarryPhase() { return 700; }
/*-- Engine Callbacks --*/
public func GetCarryTransform(clonk)
{
if(GetCarrySpecial(clonk))
return Trans_Translate(0, 6500, 0);
return Trans_Translate(0, 0, -1500);
}
protected func Construction()
func Construction()
{
//flight length
fuel=100;
@ -39,44 +30,97 @@ protected func Construction()
controllable = true;
}
func Fuse()
{
Launch(GetR());
}
func Incineration(int caused_by)
{
SetController(caused_by);
Fuse();
}
protected func Destruction()
func Hit()
{
if(rider)
{
JumpOff(rider);
}
Sound("Hits::GeneralHit?");
if(GetEffect("Flight",this)) DoFireworks();
}
func Destruction()
{
if(rider) JumpOff(rider);
}
func ControlRight()
/*-- Callbacks --*/
// Called when hitting something mid-air after the Clonk jumped off.
public func HitObject(object target)
{
if (target && WeaponCanHit(target))
target->~OnProjectileHit(this);
if (this)
DoFireworks();
}
public func OnMount(clonk)
{
var iDir = 1;
if(clonk->GetDir() == 1) iDir = -1;
clonk->PlayAnimation("PosRocket", CLONK_ANIM_SLOT_Arms, Anim_Const(0), Anim_Const(1000));
riderattach = AttachMesh(clonk, "main", "pos_tool1", Trans_Mul(Trans_Translate(-1000,2000*iDir,2000), Trans_Rotate(-90*iDir,1,0,0)));
//Modify picture transform to fit icon on clonk mount
this.PictureTransformation = Trans_Mul(Trans_Translate(5000 * clonk->GetDir(),0,0), Trans_Rotate(-20,1,0,0), Trans_Rotate(0,0,0,1), Trans_Rotate(0,0,1,0), Trans_Scale(700));
return true;
}
public func OnUnmount(clonk)
{
clonk->StopAnimation(clonk->GetRootAnimation(10));
DetachMesh(riderattach);
DefaultPicTransform();
return true;
}
public func IsProjectileTarget(object projectile)
{
return projectile->GetID() != GetID();
}
public func OnProjectileHit(object projectile)
{
Incinerate(100, projectile->GetController());
}
/*-- Usage --*/
public func Fuse()
{
Launch(GetR());
}
public func ControlRight()
{
if(controllable)
SetRDir(+3);
return true;
}
func ControlLeft()
public func ControlLeft()
{
if(controllable)
SetRDir(-3);
return true;
}
func ControlStop()
public func ControlStop()
{
if(controllable)
SetRDir(0);
return true;
}
func ControlJump(object clonk)
public func ControlJump(object clonk)
{
if(controllable)
JumpOff(clonk,60);
@ -91,8 +135,7 @@ public func RejectUse(object clonk)
return clonk->GetProcedure() != "WALK" && clonk->GetProcedure() != "FLIGHT";
}
func ControlUse(object clonk, int x, int y)
public func ControlUse(object clonk, int x, int y)
{
// forward control to item
if(clonk->GetProcedure()=="ATTACH") return false;
@ -103,8 +146,7 @@ func ControlUse(object clonk, int x, int y)
return true;
}
protected func FxFlightTimer(object pTarget, effect, int iEffectTime)
func FxFlightTimer(object pTarget, effect, int iEffectTime)
{
// clonk does sense the danger and with great presence of mind jumps of the rocket
if(fuel<20 && rider)
@ -140,7 +182,7 @@ protected func FxFlightTimer(object pTarget, effect, int iEffectTime)
fuel--;
}
private func JumpOff(object clonk, int speed)
func JumpOff(object clonk, int speed)
{
rider = nil;
@ -163,46 +205,7 @@ private func JumpOff(object clonk, int speed)
AddEffect("HitCheck", this, 1, 2, nil, nil, clonk);
}
protected func Hit()
{
if(rider)
{
JumpOff(rider);
}
Sound("Hits::GeneralHit?");
if(GetEffect("Flight",this)) DoFireworks();
}
// Called when hitting something mid-air after the Clonk jumped off.
public func HitObject(object target)
{
if (target && WeaponCanHit(target))
target->~OnProjectileHit(this);
if (this)
DoFireworks();
}
public func OnMount(clonk)
{
var iDir = 1;
if(clonk->GetDir() == 1) iDir = -1;
clonk->PlayAnimation("PosRocket", CLONK_ANIM_SLOT_Arms, Anim_Const(0), Anim_Const(1000));
riderattach = AttachMesh(clonk, "main", "pos_tool1", Trans_Mul(Trans_Translate(-1000,2000*iDir,2000), Trans_Rotate(-90*iDir,1,0,0)));
//Modify picture transform to fit icon on clonk mount
this.PictureTransformation = Trans_Mul(Trans_Translate(5000 * clonk->GetDir(),0,0), Trans_Rotate(-20,1,0,0), Trans_Rotate(0,0,0,1), Trans_Rotate(0,0,1,0), Trans_Scale(700));
return true;
}
public func OnUnmount(clonk)
{
clonk->StopAnimation(clonk->GetRootAnimation(10));
DetachMesh(riderattach);
DefaultPicTransform();
return true;
}
func Launch(int angle, object clonk)
public func Launch(int angle, object clonk)
{
SetProperty("Collectible",0);
SetCategory(C4D_Vehicle);
@ -251,51 +254,62 @@ func DoFireworks()
Explode(30);
}
func SetFuel(int new)
public func SetFuel(int new)
{
fuel = new;
}
func SetDirectionDeviation(int new)
public func SetDirectionDeviation(int new)
{
dirdev = new;
}
func SetControllable(bool new)
public func SetControllable(bool new)
{
controllable = new;
}
func GetFuel()
public func GetFuel()
{
return fuel;
}
public func IsProjectileTarget(object projectile)
{
return projectile->GetID() != GetID();
}
func OnProjectileHit(object projectile)
{
Incinerate(100, projectile->GetController());
}
/*-- Production --*/
func IsInventorProduct() { return true; }
private func DefaultPicTransform()
/*-- Display --*/
func DefaultPicTransform()
{
this.PictureTransformation = this.Prototype.PictureTransformation;
}
public func GetCarryMode()
{
return CARRY_BothHands;
}
public func GetCarryPhase() { return 700; }
public func GetCarryTransform(object clonk)
{
if(GetCarrySpecial(clonk))
return Trans_Translate(0, 6500, 0);
return Trans_Translate(0, 0, -1500);
}
public func Definition(def)
{
def.PictureTransformation = Trans_Mul(Trans_Translate(-3000, -1000, 0), Trans_Rotate(45,0,0,1),Trans_Rotate(-35,1,0,0),Trans_Scale(1200));
}
local Collectible = true;
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = true;
local BlastIncinerate = 1;
local ContactIncinerate = 1;
local Components = {Wood = 1, Firestone = 1, PowderKeg = 1};

View File

@ -3,22 +3,57 @@
Transport earth from one spot to another to form the landscape.
Replaces the old earth chunks in their behaviour.
@author Clonkonaut
@author: Clonkonaut
*/
// Uses an extra-slot to store and display material.
#include Library_HasExtraSlot
// Maximum distance at which material is collected / spilled
local maxreach = 15;
/*-- Engine Callbacks --*/
public func GetCarryMode() { return CARRY_HandBack; }
public func GetCarryBone() { return "main"; }
public func GetCarryTransform()
protected func Hit()
{
return Trans_Mul(Trans_Rotate(-90, 0, 1, 0), Trans_Translate(3500, 0, -4000));
Sound("Hits::BucketHit?");
}
public func RejectCollect(id def, object obj)
{
if (!obj->~IsBucketMaterial()) return true;
// Can only contain one stackable object.
if (Contents() && Contents(0)->~IsStackable()) return true;
return false;
}
public func SaveScenarioObject(props)
{
if (!inherited(props, ...)) return false;
return true;
}
/*-- Callbacks --*/
// Can collect IsBucketMaterial?
public func IsBucket() { return true; }
// When trying to put into a producer that can't take the item but its contents, just transfer the contents.
public func MergeWithStacksIn(object to_building, ...)
{
if (to_building && to_building->~IsProducer() && !to_building->~IsCollectionAllowed(this))
{
var i = ContentsCount(), contents, num_collected = 0;
while (i--)
if (contents = Contents(i))
if (to_building->Collect(contents))
++num_collected;
// Return if contents transfer was successful.
if (num_collected > 0) return true;
}
return _inherited(to_building, ...);
}
/*-- Usage --*/
public func RejectUse(object clonk)
{
return !clonk->HasHandAction(false, false, true);
@ -33,7 +68,7 @@ public func ControlUse(object clonk, int iX, int iY)
{
Spill(angle);
EmptyBucket();
PlayAnimation(clonk);
PlayBucketAnimation(clonk);
return true;
}
else
@ -44,14 +79,6 @@ public func ControlUse(object clonk, int iX, int iY)
return true;
}
public func RejectCollect(id def, object obj)
{
if (!obj->~IsBucketMaterial()) return true;
// Can only contain one stackable object.
if (Contents() && Contents(0)->~IsStackable()) return true;
return false;
}
public func EmptyBucket()
{
var i = ContentsCount();
@ -63,12 +90,13 @@ public func IsBucketFilled()
{
return ContentsCount();
}
public func IsBucketEmpty()
{
return !IsBucketFilled();
}
private func PlayAnimation(object clonk)
func PlayBucketAnimation(object clonk)
{
// animation only available for jumping and walking
if(!clonk->IsJumping() && !clonk->IsWalking())
@ -98,7 +126,7 @@ private func PlayAnimation(object clonk)
clonk->UpdateAttach();
}
private func Spill(int angle)
func Spill(int angle)
{
var obj = Contents(0);
if (!obj) return;
@ -111,38 +139,22 @@ private func Spill(int angle)
CastPXS(material_name, material_amount, 20, 0,0, angle, 15);
}
protected func Hit()
{
Sound("Hits::BucketHit?");
}
/*-- Production --*/
// Can collect IsBucketMaterial?
public func IsBucket() { return true; }
public func IsTool() { return true; }
public func IsToolProduct() { return true; }
// When trying to put into a producer that can't take the item but its contents, just transfer the contents.
public func MergeWithStacksIn(object to_building, ...)
/*-- Display --*/
public func GetCarryMode()
{
if (to_building && to_building->~IsProducer() && !to_building->~IsCollectionAllowed(this))
{
var i = ContentsCount(), contents, num_collected = 0;
while (i--)
if (contents = Contents(i))
if (to_building->Collect(contents))
++num_collected;
// Return if contents transfer was successful.
if (num_collected > 0) return true;
}
return _inherited(to_building, ...);
return CARRY_HandBack;
}
public func SaveScenarioObject(props)
public func GetCarryTransform(object clonk, bool idle, bool nohand)
{
if (!inherited(props, ...)) return false;
return true;
if (nohand) return Trans_Mul(Trans_Rotate(180, 0, 1, 0), Trans_Translate(3000));
return Trans_Mul(Trans_Rotate(-90, 0, 1, 0), Trans_Translate(3500, 0, -4000));
}
protected func Definition(def)
@ -150,8 +162,10 @@ protected func Definition(def)
SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(500,400,0), Trans_Rotate(-10,1,0,0), Trans_Rotate(30,0,1,0), Trans_Rotate(+25,0,0,1), Trans_Scale(1100)),def);
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = true;
local ForceFreeHands = true;
local Components = {Wood = 1, Metal = 1};
local Components = {Wood = 1, Metal = 1};

View File

@ -1,37 +1,29 @@
/*
Crate
Author: Ringwaul
Used for deliveries.
@author: Ringwaul
*/
#include Library_CarryHeavy
local crateanim;
public func GetCarryMode(clonk) { return CARRY_BothHands; }
public func GetCarryPhase() { return 800; }
/*-- Engine Callbacks --*/
public func GetCarryTransform(clonk)
{
if(GetCarrySpecial(clonk))
return Trans_Translate(3500, 6500, 0);
return Trans_Translate(0, 0, -1500);
}
protected func Construction()
func Construction()
{
PlayAnimation("Open", 1, Anim_Linear(0, 0, 1, 20, ANIM_Hold));
SetProperty("MeshTransformation",Trans_Rotate(RandomX(20,80),0,1,0));
return _inherited(...);
}
/*-- Contents --*/
func Hit()
{
Sound("Hits::Materials::Wood::DullWoodHit?");
}
local MaxContentsCount = 5;
protected func RejectCollect(id def, object obj)
func RejectCollect(id def, object obj)
{
if (ContentsCount() >= MaxContentsCount)
return true;
@ -40,34 +32,54 @@ protected func RejectCollect(id def, object obj)
return false;
}
private func Open()
/*-- Interface --*/
public func Open()
{
PlayAnimation("Open", 5, Anim_Linear(0, 0, GetAnimationLength("Open"), 22, ANIM_Hold));
Sound("Structures::Chest::Open");
}
private func Close()
public func Close()
{
crateanim = PlayAnimation("Close", 5, Anim_Linear(0, 0, GetAnimationLength("Close"), 15, ANIM_Hold));
Sound("Structures::Chest::Close");
}
protected func Definition(def)
public func IsContainer() { return true; }
/*-- Production --*/
public func IsTool() { return true; }
public func IsToolProduct() { return true; }
/*-- Display --*/
public func GetCarryMode()
{
return CARRY_BothHands;
}
public func GetCarryPhase() { return 800; }
public func GetCarryTransform(object clonk)
{
if(GetCarrySpecial(clonk))
return Trans_Translate(3500, 6500, 0);
return Trans_Translate(0, 0, -1500);
}
func Definition(def)
{
def.PictureTransformation = Trans_Mul(Trans_Translate(-500, -1500, -3000), Trans_Rotate(-30,1,0,0), Trans_Rotate(30,0,1,0));
}
public func IsTool() { return true; }
public func IsToolProduct() { return true; }
public func IsContainer() { return true; }
func Hit()
{
Sound("Hits::Materials::Wood::DullWoodHit?");
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = true;
local ContainBlast = true;
local Components = {Wood = 3};
local MaxContentsCount = 5;

View File

@ -1,32 +1,38 @@
/**
Dynamite Igniter
Dynamite Igniter
Can be used to ignite dynamite from a distance.
@author Newton
*/
#include DynamiteBox
private func Hit()
local ignited;
local dynamite_sticks;
local wires;
/*-- Engine Callbacks --*/
func Hit()
{
Sound("Hits::Materials::Metal::DullMetalHit?");
}
public func HoldingEnabled() { return true; }
// Only the main dynamite box is stored.
public func SaveScenarioObject() { return false; }
public func GetCarryMode() { return CARRY_BothHands; }
/*-- Callbacks --*/
public func GetCarryPhase() { return 250; }
public func GetCarrySpecial(clonk)
{
if (ignited)
return "pos_hand2";
public func OnFuseFinished()
{
if (Contained() != nil)
return ResetClonk(Contained());
return RemoveObject();
}
local ignited;
local dynamite_sticks;
local wires;
/*-- Usage --*/
public func HoldingEnabled() { return true; }
public func ControlUse(object clonk, int x, int y)
{
@ -59,13 +65,6 @@ public func Ignite(object clonk)
return;
}
public func OnFuseFinished()
{
if (Contained() != nil)
return ResetClonk(Contained());
return RemoveObject();
}
public func ResetClonk(object clonk)
{
// Reset animation of the clonk.
@ -78,19 +77,33 @@ public func ResetClonk(object clonk)
return;
}
// Only the main dynamite box is stored.
public func SaveScenarioObject() { return false; }
/*-- Production --*/
public func IsTool() { return true; }
public func IsChemicalProduct() { return false; }
/*-- Display --*/
public func GetCarryMode()
{
return CARRY_BothHands;
}
public func GetCarryPhase() { return 250; }
public func GetCarrySpecial(clonk)
{
if (ignited)
return "pos_hand2";
}
func Definition(def)
{
SetProperty("PictureTransformation",Trans_Mul(Trans_Rotate(-25, 1, 0, 0), Trans_Rotate(40, 0, 1, 0)), def);
}
/*-- Properties --*/
func Definition(def) {
SetProperty("PictureTransformation",Trans_Mul(Trans_Rotate(-25, 1, 0, 0), Trans_Rotate(40, 0, 1, 0)), def);
}
local Collectible = 1;
local Name = "$Name$";
local Description = "$Description$";
local Collectible = true;

View File

@ -2,7 +2,7 @@
Dynamite box
Contains five dynamite sticks which can be placed and detonated from a distance.
@author Newton
@author: Newton
*/
static const DYNA_MaxLength = 500;
@ -13,7 +13,9 @@ local dynamite_sticks;
local wires;
local wire;
public func Initialize()
/*-- Engine Callbacks --*/
func Initialize()
{
count = DYNA_MaxCount;
dynamite_sticks = [];
@ -24,20 +26,71 @@ public func Initialize()
wires[i] = nil;
}
this.PictureTransformation = Trans_Scale(); // Hide it TODO: Remove if the mesh isn't shown if there is a picture set
// Hide it TODO: Remove if the mesh isn't shown if there is a picture set
this.PictureTransformation = Trans_Scale();
UpdatePicture();
return;
}
private func Hit()
func Hit()
{
Sound("Hits::Materials::Wood::DullWoodHit?");
}
public func HoldingEnabled() { return true; }
func Incineration(int caused_by)
{
ActivateFuse();
if (!GetEffect("Fuse", this)) AddEffect("Fuse", this, 100, 1, this);
Sound("Fire::Fuse");
SetController(caused_by);
return;
}
public func GetCarryMode() { return CARRY_BothHands; }
public func GetCarryPhase() { return 450; }
func Damage(int change, int type, int by_player)
{
Incinerate(nil, by_player);
return;
}
public func OnCannonShot(object cannon)
{
Incinerate(nil, cannon->GetController());
}
/*-- Callbacks --*/
// Do not stack empty dynamite boxes with full ones.
public func CanBeStackedWith(object other)
{
if (this.count != other.count) return false;
return inherited(other, ...);
}
// Drop connected or fusing boxes
public func IsDroppedOnDeath(object clonk)
{
return GetEffect("Fuse", this) || wire;
}
public func OnFuseFinished(object fuse)
{
SetController(fuse->GetController());
DoExplode();
}
/*-- Usage --*/
public func SetDynamiteCount(int new_count)
{
count = BoundBy(new_count, 1, DYNA_MaxCount);
UpdatePicture();
// Update inventory if contained in a crew member.
if (Contained())
Contained()->~OnInventoryChange();
return;
}
public func HoldingEnabled() { return true; }
public func ControlUse(object clonk, int x, int y)
{
@ -84,27 +137,65 @@ public func ChangeToIgniter()
return true;
}
public func SetDynamiteCount(int new_count)
public func ActivateFuse()
{
count = BoundBy(new_count, 1, DYNA_MaxCount);
UpdatePicture();
// Update inventory if contained in a crew member.
if (Contained())
Contained()->~OnInventoryChange();
return;
// Activate all fuses.
for (var obj in FindObjects(Find_Category(C4D_StaticBack), Find_Func("IsFuse"), Find_ActionTargets(this)))
obj->~StartFusing(this);
}
private func UpdatePicture()
public func DoExplode()
{
// Activate all fuses.
ActivateFuse();
// Explode, calc the radius out of the area of a explosion of a single dynamite times the amount of dynamite
// This results to 18, 25, 31, 36, and 40
Explode(Sqrt(18**2*count));
}
public func FxFuseTimer(object target, effect, int timer)
{
CreateParticle("Fire", 0, 0, PV_Random(-10, 10), PV_Random(-20, 10), PV_Random(10, 40), Particles_Glimmer(), 6);
if (timer > 90)
DoExplode();
return FX_OK;
}
/*-- Production --*/
public func IsTool() { return true; }
public func IsChemicalProduct() { return true; }
/*-- Display --*/
public func GetCarryMode(object clonk, bool idle)
{
if (idle) return CARRY_Back;
if (clonk->~IsWalking() || clonk->~IsJumping()) return CARRY_BothHands;
return CARRY_Back;
}
public func GetCarryTransform(object clonk, bool idle, bool nohand, bool second_on_back)
{
if (idle)
{
if (!second_on_back)
return Trans_Mul(Trans_Translate(0,3000, 00), Trans_Rotate(-45,0,1));
else
return Trans_Mul(Trans_Translate(-5000,3000), Trans_Rotate(-45,0,1));
}
if (nohand)
return Trans_Mul(Trans_Translate(0,-3000, -2200), Trans_Rotate(-45,0,1));
}
public func GetCarryPhase()
{
return 450;
}
func UpdatePicture()
{
SetGraphics(Format("%d", 6 - count), DynamiteBox, 1, GFXOV_MODE_Picture);
return;
}
// Do not stack empty dynamite boxes with full ones.
public func CanBeStackedWith(object other)
{
if (this.count != other.count) return false;
return inherited(other, ...);
}
// Display the remaining dynamite sticks in menus.
@ -142,74 +233,12 @@ public func GetInventoryIconOverlay()
return overlay;
}
public func OnFuseFinished(object fuse)
{
SetController(fuse->GetController());
DoExplode();
}
public func ActivateFuse()
{
// Activate all fuses.
for (var obj in FindObjects(Find_Category(C4D_StaticBack), Find_Func("IsFuse"), Find_ActionTargets(this)))
obj->~StartFusing(this);
}
public func DoExplode()
{
// Activate all fuses.
ActivateFuse();
// Explode, calc the radius out of the area of a explosion of a single dynamite times the amount of dynamite
// This results to 18, 25, 31, 36, and 40
Explode(Sqrt(18**2*count));
}
protected func Incineration(int caused_by)
{
ActivateFuse();
if (!GetEffect("Fuse", this)) AddEffect("Fuse", this, 100, 1, this);
Sound("Fire::Fuse");
SetController(caused_by);
return;
}
protected func Damage(int change, int type, int by_player)
{
Incinerate(nil, by_player);
return;
}
public func OnCannonShot(object cannon)
{
Incinerate(nil, cannon->GetController());
}
public func FxFuseTimer(object target, effect, int timer)
{
CreateParticle("Fire", 0, 0, PV_Random(-10, 10), PV_Random(-20, 10), PV_Random(10, 40), Particles_Glimmer(), 6);
if (timer > 90)
DoExplode();
return FX_OK;
}
public func IsTool() { return true; }
public func IsChemicalProduct() { return true; }
/* Drop connected or fusing boxes */
public func IsDroppedOnDeath(object clonk)
{
return GetEffect("Fuse", this) || wire;
}
/*-- Properties --*/
func Definition(def) {
SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(150, 1, 0, 0), Trans_Rotate(140, 0, 1, 0)), def);
}
/*-- Properties --*/
local Collectible = 1;
local Name = "$Name$";
local Description = "$Description$";

View File

@ -5,18 +5,23 @@
@author Randrian
*/
// Display the hook on the inventory HUD
#include Library_HasExtraSlot
// Do mind that IsContainer is set to false, so the hook can't be taken out via the interaction menu (very important)
// See below in Callbacks for IsContainer
local is_aiming;
local animation_set;
local hook;
local hook_attach;
/*-- Engine Callbacks --*/
private func Initialize()
func Initialize()
{
// The aiming animation is done by adjusting the animation position to fit the angle.
animation_set = {
AimMode = AIM_Position,
AimMode = AIM_Position,
AnimationAim = "CrossbowAimArms",
AnimationShoot = nil,
ShootTime = 20,
@ -26,36 +31,106 @@ private func Initialize()
AimSpeed = 20,
};
OnRopeBreak();
return;
}
/*-- Animations --*/
public func GetCarrySpecial(object clonk)
func Hit()
{
if (is_aiming)
return "pos_hand2";
Sound("Hits::GeneralHit?");
}
public func GetCarryBone2(object clonk) { return "main2"; }
public func GetCarryMode(object clonk)
func Destruction()
{
if (hook && !hook->Contained())
return CARRY_Back;
if (is_aiming)
return CARRY_Grappler;
if (hook)
{
var rope = hook->GetRope();
if (rope)
rope->BreakRope();
}
}
func Departure()
{
if (hook)
{
var rope = hook->GetRope();
if (rope)
rope->BreakRope();
}
}
func Incineration()
{
// Grapple bow becomes unusable on incineration.
if (hook)
{
var rope = hook->GetRope();
if (rope) rope->BreakRope();
if (hook) hook->RemoveObject();
}
SetClrModulation(0xff606060);
return _inherited(...);
}
func Extinguishing()
{
// If extinguished on the same frame it got incinerated, make it usable again
if (GetCon() >= 100)
{
EnsureHook();
SetClrModulation();
}
return _inherited(...);
}
/*-- Callbacks --*/
public func GetAnimationSet() { return animation_set; }
// Callback from the clonk when loading is finished
public func FinishedLoading(object clonk)
{
clonk->~StartAim(this);
return true;
}
/*-- Controls --*/
// Callback from the clonk, when he actually has stopped aiming.
public func FinishedAiming(object clonk, int angle)
{
// Only shoot if the bow did not burn in the meantime.
if (GetCon() < 100)
return false;
// Shoot the hook and detach the mesh from the bow.
EnsureHook();
hook->Exit();
hook->Launch(angle, 100, clonk, this);
hook_attach = nil;
DetachMesh(hook_attach);
Sound("Objects::Weapons::Bow::Shoot?");
// Open the hand to let the string go and play the fire animation.
PlayAnimation("Fire", 6, Anim_Linear(0, 0, GetAnimationLength("Fire"), animation_set["ShootTime"], ANIM_Hold));
clonk->StartShoot(this);
return true;
}
public func OnRopeBreak()
{
if (hook_attach)
DetachMesh(hook_attach);
EnsureHook();
hook->Enter(this);
hook_attach = AttachMesh(hook, "bolt", "main");
PlayAnimation("Load", 5, Anim_Const(GetAnimationLength("Load")));
}
func IsContainer() { return false; } // See above for explanation
/*-- Usage --*/
public func HoldingEnabled() { return true; }
public func RejectUse(object clonk)
{
// Burned?
@ -92,13 +167,6 @@ public func ControlUseStart(object clonk, int x, int y)
return true;
}
// Callback from the clonk when loading is finished
public func FinishedLoading(object clonk)
{
clonk->~StartAim(this);
return true;
}
public func ControlUseHolding(object clonk, int x, int y)
{
// Update the aiming angle on mouse movement.
@ -109,6 +177,12 @@ public func ControlUseHolding(object clonk, int x, int y)
return true;
}
public func ControlUseCancel(object clonk, int x, int y)
{
clonk->CancelAiming();
return true;
}
// Stopping says the clonk to stop with aiming (he will go on untill he has finished loading and aiming at the given angle).
public func ControlUseStop(object clonk, int x, int y)
{
@ -116,34 +190,13 @@ public func ControlUseStop(object clonk, int x, int y)
return true;
}
// Callback from the clonk, when he actually has stopped aiming.
public func FinishedAiming(object clonk, int angle)
public func Reset(object clonk)
{
// Only shoot if the bow did not burn in the meantime.
if (GetCon() < 100)
return false;
// Shoot the hook and detach the mesh from the bow.
EnsureHook();
hook->Exit();
hook->Launch(angle, 100, clonk, this);
hook_attach = nil;
DetachMesh(hook_attach);
Sound("Objects::Weapons::Bow::Shoot?");
// Open the hand to let the string go and play the fire animation.
PlayAnimation("Fire", 6, Anim_Linear(0, 0, GetAnimationLength("Fire"), animation_set["ShootTime"], ANIM_Hold));
clonk->StartShoot(this);
return true;
is_aiming = 0;
clonk->StopAnimation(clonk->GetRootAnimation(11));
StopAnimation(GetRootAnimation(6));
}
public func ControlUseCancel(object clonk, int x, int y)
{
clonk->CancelAiming();
return true;
}
/*-- Bow Mechanics --*/
public func SetHook(object new_hook)
@ -151,7 +204,7 @@ public func SetHook(object new_hook)
hook = new_hook;
}
private func EnsureHook()
func EnsureHook()
{
// Create hook if it went missing.
if (!hook)
@ -159,17 +212,6 @@ private func EnsureHook()
return hook;
}
public func OnRopeBreak()
{
if (hook_attach)
DetachMesh(hook_attach);
EnsureHook();
hook->Enter(this);
hook_attach = AttachMesh(hook, "bolt", "main");
PlayAnimation("Load", 5, Anim_Const(GetAnimationLength("Load")));
}
public func DrawRopeIn()
{
if (hook)
@ -180,26 +222,6 @@ public func DrawRopeIn()
}
}
private func Destruction()
{
if (hook)
{
var rope = hook->GetRope();
if (rope)
rope->BreakRope();
}
}
private func Departure()
{
if (hook)
{
var rope = hook->GetRope();
if (rope)
rope->BreakRope();
}
}
// If shot (e.g. by a cannon) the rope is drawn in.
public func LaunchProjectile()
{
@ -212,58 +234,50 @@ public func LaunchProjectile()
_inherited(...);
}
/*-- Fire Effects --*/
private func Incineration()
func RejectCollect(id whatever, object hopefully_hook)
{
// Grapple bow becomes unusable on incineration.
if (hook)
{
var rope = hook->GetRope();
if (rope) rope->BreakRope();
if (hook) hook->RemoveObject();
}
SetClrModulation(0xff606060);
return _inherited(...);
// The grapple bow will only its own hook, very picky thing
if (hopefully_hook != hook) return true;
return false;
}
private func Extinguishing()
{
// If extinguished on the same frame it got incinerated, make it usable again
if (GetCon() >= 100)
{
EnsureHook();
SetClrModulation();
}
return _inherited(...);
}
/*-- Animation functions --*/
public func Reset(object clonk)
{
is_aiming = 0;
clonk->StopAnimation(clonk->GetRootAnimation(11));
StopAnimation(GetRootAnimation(6));
}
public func Hit()
{
Sound("Hits::GeneralHit?");
}
/*-- Production --*/
public func IsInventorProduct() { return true; }
/*-- Display --*/
/*-- Properties --*/
public func GetCarryMode(object clonk, bool idle)
{
if (idle) return CARRY_Back;
public func Definition(proplist def)
if (clonk->~IsJumping())
return CARRY_Hand;
return CARRY_Grappler;
}
public func GetCarryTransform(object clonk, bool idle, bool nohand)
{
if (idle || nohand)
return Trans_Translate(0,3000);
}
public func GetCarrySpecial(object clonk)
{
if (is_aiming)
return "pos_hand2";
}
public func GetCarryBone2(object clonk) { return "main2"; }
func Definition(proplist def)
{
def.PictureTransformation = Trans_Mul(Trans_Translate(-2500, 1000),Trans_Scale(1800),Trans_Rotate(-60,1,-1,1), Trans_Rotate(180, 0, 1, 0));
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = 1;

View File

@ -1,20 +1,22 @@
/*-- Hammer --*/
/**
Hammer
Basic construction tool.
*/
// Usage is handled by this library
#include Library_Constructor
private func Hit(int x, int y)
/*-- Engine Callbacks --*/
func Hit(int x, int y)
{
StonyObjectHit(x, y);
return 1;
}
public func GetCarryMode() { return CARRY_HandBack; }
public func GetCarryBone() { return "main"; }
public func GetCarryTransform() { return Trans_Rotate(-90,1,0,0); }
public func IsTool() { return true; }
public func IsToolProduct() { return true; }
/*-- Usage --*/
// Used by the constructor library
func CanBuild(id construction_plan)
{
if (!construction_plan) return false;
@ -22,14 +24,34 @@ func CanBuild(id construction_plan)
return false;
}
/*-- Properties --*/
/*-- Production --*/
func Definition(def)
public func IsTool() { return true; }
public func IsToolProduct() { return true; }
/*-- Display --*/
public func GetCarryMode(object clonk, bool idle)
{
if (!idle)
return CARRY_HandBack;
else
return CARRY_Belt;
}
public func GetCarryTransform(object clonk, bool idle)
{
if (!idle) return Trans_Rotate(-90,1,0,0);
}
func Definition(def)
{
SetProperty("PictureTransformation", Trans_Rotate(20, 1, 0, 1), def);
}
local Collectible = 1;
/*-- Properties --*/
local Collectible = true;
local Name = "$Name$";
local Description = "$Description$";
local Components = {Wood = 1, Rock = 1};

View File

@ -7,11 +7,37 @@
#include Library_Lamp
private func Construction()
/*-- Engine Callbacks --*/
func Hit()
{
//SetProperty("MeshTransformation", Trans_Mul(Trans_Scale(3500), Trans_Rotate(280,0,1,0)));
Sound("Hits::Materials::Glass::GlassHit?");
}
func Hit2()
{
// Cast flames on impact.
for (var i = 0; i < 20; i++)
CastObjects(Flame, 1, 20, RandomX(-3, 3), RandomX(-4, 0));
// Cast some particles.
// TODO?
// Sound effects.
Sound("Hits::Materials::Glass::GlassBreak");
Sound("Fire::Inflame");
Explode(10, true);
}
/** Scenario saving: Mesh material is included in lamp on-state
*/
public func SaveScenarioObject(props, ...)
{
if (!_inherited(props, ...)) return false;
props->Remove("MeshMaterial"); // stored by lamp state anyway
return true;
}
/*-- Usage --*/
public func TurnOn()
{
_inherited();
@ -24,55 +50,33 @@ public func TurnOff()
SetMeshMaterial("LanternGlass", 1);
}
/*-- Ground Hitting --*/
private func Hit()
{
Sound("Hits::Materials::Glass::GlassHit?");
}
private func Hit2()
{
// Cast flames on impact.
for (var i = 0; i < 20; i++)
CastObjects(Flame, 1, 20, RandomX(-3, 3), RandomX(-4, 0));
// Cast some particles.
// TODO?
// Sound effects.
Sound("Hits::Materials::Glass::GlassBreak");
Sound("Fire::Inflame");
Explode(10, true);
}
/*-- Visual --*/
public func GetCarryMode() { return CARRY_HandBack; }
public func GetCarryBone() { return "main"; }
public func GetCarryTransform()
{
return Trans_Rotate(-90,0,1,0);
}
private func Definition(def)
{
SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(280,0,1,0), Trans_Rotate(35,0,0,1), Trans_Rotate(10,1,0,0), Trans_Translate(0,0,250)),def);
}
/** Scenario saving: Mesh material is included in lamp on-state
*/
public func SaveScenarioObject(props, ...)
{
if (!_inherited(props, ...)) return false;
props->Remove("MeshMaterial"); // stored by lamp state anyway
return true;
}
/*-- Status --*/
/*-- Production --*/
public func IsTool() { return true; }
public func IsToolProduct() { return true; }
/*-- Display --*/
public func GetCarryMode()
{
return CARRY_HandBack;
}
public func GetCarryTransform(object clonk, bool idle, bool nohand)
{
if (nohand)
return Trans_Mul(Trans_Rotate(-120,0,1), Trans_Translate(-2000, 0, -3000));
return Trans_Rotate(-90,0,1,0);
}
func Definition(def)
{
SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(280,0,1,0), Trans_Rotate(35,0,0,1), Trans_Rotate(10,1,0,0), Trans_Translate(0,0,250)),def);
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = true;
local Components = {Firestone = 1, Metal = 1, Coal = 1};
local Components = {Firestone = 1, Metal = 1, Coal = 1};

View File

@ -1,42 +1,34 @@
/*
Pickaxe
Author: Randrian/Ringwaul
A useful but tedious tool for breaking through rock without
explosives.
A useful but tedious tool for breaking through rock without explosives.
@author: Randrian/Ringwaul
*/
local maxreach;
local swingtime;
local swingtime = 0;
local using;
public func GetCarryMode() { return CARRY_HandBack; }
public func GetCarryBone() { return "main"; }
public func GetCarrySpecial(clonk) { if(using == 1) return "pos_hand2"; }
public func GetCarryTransform()
{
return Trans_Rotate(90, 1, 0, 0);
}
static const Pickaxe_SwingTime = 40;
/*-- Engine Callbacks --*/
func Definition(def) {
SetProperty("PictureTransformation",Trans_Mul(Trans_Rotate(40, 0, 0, 1),Trans_Rotate(150, 0, 1, 0), Trans_Scale(900), Trans_Translate(600, 400, 1000)),def);
}
protected func Initialize()
{
//maxreach is the length of the pick from the clonk's hand
maxreach=12;
swingtime=0;
}
private func Hit(x, y)
func Hit(x, y)
{
StonyObjectHit(x, y);
return 1;
}
static const Pickaxe_SwingTime = 40;
// Reroute callback to clonk context to ensure DigOutObject callback is done in Clonk
public func DigOutObject(object obj)
{
// TODO: it would be nice if the method of finding the clonk does not rely on it to be the container of the pickaxe
var clonk = Contained();
if (clonk)
clonk->~DigOutObject(obj);
}
/*-- Usage --*/
public func HoldingEnabled() { return true; }
public func RejectUse(object clonk)
{
@ -44,7 +36,7 @@ public func RejectUse(object clonk)
return proc != "WALK" && proc != "SCALE";
}
func ControlUseStart(object clonk, int ix, int iy)
public func ControlUseStart(object clonk, int ix, int iy)
{
using = 1;
// Create an offset, so that the hit matches with the animation
@ -60,9 +52,7 @@ func ControlUseStart(object clonk, int ix, int iy)
return true;
}
protected func HoldingEnabled() { return true; }
func ControlUseHolding(object clonk, int new_x, int new_y)
public func ControlUseHolding(object clonk, int new_x, int new_y)
{
// Can clonk use pickaxe?
if (clonk->GetProcedure() != "WALK")
@ -76,20 +66,37 @@ func ControlUseHolding(object clonk, int new_x, int new_y)
return true;
}
func ControlUseStop(object clonk, int ix, int iy)
func ControlUseCancel(object clonk, int ix, int iy)
{
Reset(clonk);
return true;
}
protected func DoSwing(object clonk, int ix, int iy)
public func ControlUseStop(object clonk, int ix, int iy)
{
Reset(clonk);
return true;
}
public func Reset(clonk)
{
using = 0;
clonk->SetTurnType(0);
clonk->SetHandAction(false);
clonk->UpdateAttach();
clonk->StopAnimation(clonk->GetRootAnimation(10));
swingtime=0;
RemoveEffect("IntPickaxe", clonk);
}
func DoSwing(object clonk, int ix, int iy)
{
var angle = Angle(0,0,ix,iy);
//Creates an imaginary line which runs for 'maxreach' distance (units in pixels)
//Creates an imaginary line which runs for 'MaxReach' distance (units in pixels)
//or until it hits a solid wall.
var iDist=0;
while(!GBackSolid(Sin(180-angle,iDist),Cos(180-angle,iDist)) && iDist < maxreach)
while(!GBackSolid(Sin(180-angle,iDist),Cos(180-angle,iDist)) && iDist < MaxReach)
{
++iDist;
}
@ -155,19 +162,9 @@ protected func DoSwing(object clonk, int ix, int iy)
AddEffect("IntNoHitAllowed", obj, 1, 30, nil, GetID());
}
}
}
// Reroute callback to clonk context to ensure DigOutObject callback is done in Clonk
public func DigOutObject(object obj)
{
// TODO: it would be nice if the method of finding the clonk does not rely on it to be the container of the pickaxe
var clonk = Contained();
if (clonk)
clonk->~DigOutObject(obj);
}
public func FxIntPickaxeTimer(object clonk, proplist effect, int time)
func FxIntPickaxeTimer(object clonk, proplist effect, int time)
{
++swingtime;
if(swingtime >= Pickaxe_SwingTime) // Waits three seconds for animation to run (we could have a clonk swing his pick 3 times)
@ -187,32 +184,15 @@ public func FxIntPickaxeTimer(object clonk, proplist effect, int time)
clonk->SetYDir(Cos(angle,-speed),100);
}
protected func ControlUseCancel(object clonk, int ix, int iy)
{
Reset(clonk);
return true;
}
public func Reset(clonk)
{
using = 0;
clonk->SetTurnType(0);
clonk->SetHandAction(false);
clonk->UpdateAttach();
clonk->StopAnimation(clonk->GetRootAnimation(10));
swingtime=0;
RemoveEffect("IntPickaxe", clonk);
}
// Effects that sets the category of C4D_Objects to C4D_None for some time to prevent those objects from hitting the Clonk.
private func FxIntNoHitAllowedStart(object target, effect fx, temp)
func FxIntNoHitAllowedStart(object target, effect fx, temp)
{
if (temp) return;
fx.category = target->GetCategory();
target->SetCategory(C4D_None);
}
private func FxIntNoHitAllowedStop(object target, effect fx, int reason, temp)
func FxIntNoHitAllowedStop(object target, effect fx, int reason, temp)
{
if (temp || !target) return;
// If nothing magically changed the category, reset it.
@ -220,12 +200,39 @@ private func FxIntNoHitAllowedStop(object target, effect fx, int reason, temp)
target->SetCategory(fx.category);
}
/*-- Production --*/
public func IsTool() { return true; }
public func IsToolProduct() { return true; }
local Collectible = 1;
/*-- Display --*/
public func GetCarryMode(object clonk, bool idle)
{
if (!idle)
return CARRY_HandBack;
else
return CARRY_Back;
}
public func GetCarrySpecial(clonk) { if(using == 1) return "pos_hand2"; }
public func GetCarryTransform()
{
return Trans_Rotate(90, 1, 0, 0);
}
func Definition(def) {
SetProperty("PictureTransformation",Trans_Mul(Trans_Rotate(40, 0, 0, 1),Trans_Rotate(150, 0, 1, 0), Trans_Scale(900), Trans_Translate(600, 400, 1000)),def);
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = true;
//MaxReach is the length of the pick from the clonk's hand
local MaxReach = 12;
local MaxPickDensity = 70; // can't pick granite
local ForceFreeHands = true;
local Components = {Wood = 1, Metal = 1};
local Components = {Wood = 1, Metal = 1};

View File

@ -22,15 +22,17 @@ public func SetNeutral()
}
// Reddish colour.
// Please to not change otherwise people with dyschromatopsia will hunt you down.
public func SetDrain()
{
SetProperty("LineColors", [RGB(110, 80, 80), RGB(110, 80, 80)]);
SetProperty("LineColors", [RGB(238, 102, 0), RGB(238, 102, 0)]);
}
// Greenish colour.
// Please to not change otherwise people with dyschromatopsia will hunt you down.
public func SetSource()
{
SetProperty("LineColors", [RGB(80, 110, 80), RGB(80, 110, 80)]);
SetProperty("LineColors", [RGB(102, 136, 34), RGB(102, 136, 34)]);
}
// Returns true if this object is a functioning pipe.

View File

@ -1,19 +1,20 @@
/**
Shovel
Essential tool for the clonk, used to dig through materials.
Essential tool for the clonk, used to dig through materials.
@author Newtom, Sven2, Zapper, Maikel
@author: Newton, Sven2, Zapper, Maikel
*/
local is_digging;
private func Hit()
/*-- Engine Callbacks --*/
func Hit()
{
Sound("Hits::Materials::Wood::WoodHit?");
}
private func Destruction()
func Destruction()
{
// Stop shoveling when using the shovel when it's destroyed.
var user = Contained();
@ -26,15 +27,10 @@ private func Destruction()
}
}
public func GetCarryMode(clonk) { return CARRY_Back; }
public func GetCarrySpecial(clonk) { if (clonk->~GetAction() == "Dig") return "pos_hand1"; }
/*-- Usage --*/
public func IsDigging() { return is_digging; }
/*-- Usage --*/
public func HoldingEnabled() { return true; }
public func ControlUseStart(object clonk, int x, int y)
@ -175,7 +171,7 @@ public func FxShovelDigTimer(object clonk, effect fx, int time)
return FX_OK;
}
private func GetDigSpeed(object clonk)
func GetDigSpeed(object clonk)
{
var speed = clonk.ActMap.Dig.Speed * 2;
// Adjust speed at current animation position.
@ -217,18 +213,35 @@ public func Dust(object target)
return;
}
/*-- Production --*/
public func IsTool() { return true; }
public func IsToolProduct() { return true; }
/*-- Display --*/
/*-- Properties --*/
public func GetCarryMode(object clonk, bool idle)
{
if (!idle)
return CARRY_Hand;
else
return CARRY_Back;
}
public func Definition(proplist def)
public func GetCarrySpecial(object clonk, bool idle)
{
if (idle) return;
if (clonk->~GetAction() == "Dig") return "pos_hand1";
}
func Definition(proplist def)
{
def.PictureTransformation = Trans_Mul(Trans_Rotate(135, 0, 0, 1), Trans_Rotate(30, 0, 1, 0));
}
/*-- Properties --*/
local Collectible = true;
local Name = "$Name$";
local Description = "$Description$";
local Components = {Wood = 1, Metal = 1};
local Components = {Wood = 1, Metal = 1};

View File

@ -2,19 +2,19 @@
Sickle
Used for harvesting (wheat, cotton, ...)
@author Clonkonaut
@author: Clonkonaut
*/
/*-- Engine Callbacks --*/
private func Hit()
{
Sound("Hits::Materials::Wood::WoodHit?");
}
public func GetCarryMode() { return CARRY_HandBack; }
public func GetCarryBone() { return "main"; }
public func GetCarryTransform() { return Trans_Rotate(90,1,0,0); }
/*-- Usage --*/
func RejectUse(object clonk)
public func RejectUse(object clonk)
{
return !(clonk->IsWalking() || clonk->IsJumping()) || !clonk->HasHandAction();
}
@ -48,14 +48,40 @@ public func ControlUseStart(object clonk, int x, int y)
return true;
}
/*-- Production --*/
public func IsTool() { return true; }
public func IsToolProduct() { return true; }
func Definition(def) {
/*-- Display --*/
public func GetCarryMode(object clonk, bool idle)
{
if (idle)
return CARRY_Belt;
return CARRY_HandBack;
}
public func GetCarryTransform(object clonk, bool idle, bool nohand)
{
if (idle)
return Trans_Mul(Trans_Rotate(-45, 1, 0, 0), Trans_Rotate(180, 0, 0, 1), Trans_Translate(0,0,1000));
if (nohand)
return Trans_Mul(Trans_Rotate(45, 0, 1), Trans_Translate(-3000, 0, 4000));
return Trans_Rotate(90,1,0,0);
}
func Definition(def)
{
SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(15, 0, 1, 0), Trans_Rotate(320, 0,0,1)),def);
}
local Collectible = 1;
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = true;
local Components = {Wood = 1, Metal = 1};

View File

@ -1,8 +1,8 @@
/*--
TeleGlove
Author: Ringwaul
Move objects remotely.
Moves objects remotely like magic!
@author: Ringwaul
--*/
local radius; //actual effect radius to grab objects
@ -17,104 +17,61 @@ local carry_bone;
local target_object;
protected func Initialize()
/*-- Engine Callbacks --*/
func Initialize()
{
radius = 60;
radiusparticle = radius / 4;
}
func Hit()
{
Sound("Hits::GeneralHit?");
}
/*-- Global functions --*/
global func FxTeleGloveReleasedStart(object target, effect)
{
effect.t0 = FrameCounter();
return;
}
global func FxTeleGloveWeightStart(object target, proplist effect)
{
target->SetMass(target->GetMass()/2);
}
global func FxTeleGloveWeightStop(object target, proplist effect, int reason, bool temp)
{
target->SetMass(target->GetDefCoreVal("Mass", "DefCore"));
}
// Damaging Clonks with moving objects makes this tool stupidly strong. So it's blocked
// while moving the object and a few frames after release
global func FxTeleGloveWeightQueryHitClonk(object target, fx, object clonk) { return true; }
global func FxTeleGloveReleasedQueryHitClonk(object target, fx, object clonk) { return FrameCounter()-fx.t0 <= 5; }
/*-- Usage --*/
// The reach of the tele glove, can be modified by overloading.
public func GetTeleGloveReach() { return 150; }
public func GetCarryMode() { return CARRY_HandBack; }
public func GetCarrySpecial(clonk) { return carry_bone; }
public func GetCarryBone() { return "main"; }
public func GetCarryTransform()
{
//Left hand's bone is different? I don't know, but this is a work-around.
if(carry_bone == "pos_hand1") return Trans_Rotate(180,0,1,0);
return Trans_Rotate(-90,0,1,0);
}
protected func HoldingEnabled() { return true; }
public func HoldingEnabled() { return true; }
public func RejectUse(object clonk)
{
return !clonk->HasHandAction() || !(clonk->IsWalking() || clonk->IsJumping());
}
protected func ControlUseStart(object clonk, ix, iy)
public func ControlUseStart(object clonk, ix, iy)
{
StartUsage(clonk);
UpdateGloveAngle(clonk, ix, iy);
return true;
}
private func StartUsage(object clonk)
{
var hand;
// which animation to use? (which hand)
if(clonk->GetHandPosByItemPos(clonk->GetItemPos(this)) == 0)
{
carry_bone = "pos_hand2";
hand = "AimArmsGeneric.R";
}
else
{
carry_bone = "pos_hand1";
hand = "AimArmsGeneric.L";
}
aiming = 1;
aim_anim = clonk->PlayAnimation(hand, CLONK_ANIM_SLOT_Arms, Anim_Const(clonk->GetAnimationLength(hand)/2), Anim_Const(1000));
clonk->UpdateAttach();
//Animations and effects for TeleGlove
Sound("Objects::Electrical",nil,nil,nil,+1);
PlayAnimation("Opening", -5, Anim_Linear(0,0,GetAnimationLength("Opening"), 10, ANIM_Hold));
anim_spin = PlayAnimation("Spin",5, Anim_Linear(0,0,GetAnimationLength("Spin"), 40, ANIM_Loop));
// Light effects
SetLightRange(50, 10);
SetLightColor(0xa0a0ff);
}
private func EndUsage(object clonk)
{
carry_bone = nil;
aim_anim = nil;
iAngle = 0;
clonk->StopAnimation(clonk->GetRootAnimation(10));
clonk->UpdateAttach();
SetLightRange();
}
// Update the glove aim angle
private func UpdateGloveAngle(object clonk, int x, int y)
{
var angle=Normalize(Angle(0,0, x,y),-180);
angle=BoundBy(angle,-150,150);
if(clonk->GetDir() == DIR_Left)
{
if(angle > 0) return;
}
else
{
if(angle < 0) return;
}
iAngle=angle;
clonk->SetAnimationPosition(aim_anim, Anim_Const(Abs(iAngle) * 11111/1000));
// Light position at remote location
this.LightOffset = [x, y];
return true;
}
public func ControlUseHolding(object clonk, ix, iy)
{
if(!clonk->HasHandAction() || !aiming || (!clonk->IsWalking() && !clonk->IsJumping()))
@ -202,6 +159,81 @@ public func ControlUseHolding(object clonk, ix, iy)
return 1;
}
public func ControlUseCancel(object clonk, int ix, int iy)
{
return CancelUse(clonk);
}
public func ControlUseStop(object clonk, ix, iy)
{
return CancelUse(clonk);
}
func StartUsage(object clonk)
{
var hand;
// which animation to use? (which hand)
if(clonk->GetHandPosByItemPos(clonk->GetItemPos(this)) == 0)
{
carry_bone = "pos_hand2";
hand = "AimArmsGeneric.R";
}
else
{
carry_bone = "pos_hand1";
hand = "AimArmsGeneric.L";
}
aiming = 1;
aim_anim = clonk->PlayAnimation(hand, CLONK_ANIM_SLOT_Arms, Anim_Const(clonk->GetAnimationLength(hand)/2), Anim_Const(1000));
clonk->UpdateAttach();
//Animations and effects for TeleGlove
Sound("Objects::Electrical",nil,nil,nil,+1);
PlayAnimation("Opening", -5, Anim_Linear(0,0,GetAnimationLength("Opening"), 10, ANIM_Hold));
anim_spin = PlayAnimation("Spin",5, Anim_Linear(0,0,GetAnimationLength("Spin"), 40, ANIM_Loop));
// Light effects
SetLightRange(50, 10);
SetLightColor(0xa0a0ff);
}
func EndUsage(object clonk)
{
carry_bone = nil;
aim_anim = nil;
iAngle = 0;
clonk->StopAnimation(clonk->GetRootAnimation(10));
clonk->UpdateAttach();
SetLightRange();
}
// Update the glove aim angle
func UpdateGloveAngle(object clonk, int x, int y)
{
var angle=Normalize(Angle(0,0, x,y),-180);
angle=BoundBy(angle,-150,150);
if(clonk->GetDir() == DIR_Left)
{
if(angle > 0) return;
}
else
{
if(angle < 0) return;
}
iAngle=angle;
clonk->SetAnimationPosition(aim_anim, Anim_Const(Abs(iAngle) * 11111/1000));
// Light position at remote location
this.LightOffset = [x, y];
return true;
}
public func GainedTargetObject(object target)
{
if (!GetEffect("TeleGloveWeight", target))
@ -223,37 +255,6 @@ public func LostTargetObject(object target)
effect.controller = Contained()->GetController();
}
global func FxTeleGloveReleasedStart(object target, effect)
{
effect.t0 = FrameCounter();
return;
}
global func FxTeleGloveWeightStart(object target, proplist effect)
{
target->SetMass(target->GetMass()/2);
}
global func FxTeleGloveWeightStop(object target, proplist effect, int reason, bool temp)
{
target->SetMass(target->GetDefCoreVal("Mass", "DefCore"));
}
// Damaging Clonks with moving objects makes this tool stupidly strong. So it's blocked
// while moving the object and a few frames after release
global func FxTeleGloveWeightQueryHitClonk(object target, fx, object clonk) { return true; }
global func FxTeleGloveReleasedQueryHitClonk(object target, fx, object clonk) { return FrameCounter()-fx.t0 <= 5; }
protected func ControlUseStop(object clonk, ix, iy)
{
CancelUse(clonk);
return 1;
}
protected func ControlUseCancel(object clonk, int ix, int iy)
{
CancelUse(clonk);
}
protected func CancelUse(object clonk)
{
@ -264,21 +265,37 @@ protected func CancelUse(object clonk)
aiming = 0;
if(target_object) LostTargetObject(target_object);
target_object = nil;
return 1;
return true;
}
func Hit()
{
Sound("Hits::GeneralHit?");
}
/*-- Production --*/
func IsInventorProduct() { return true; }
func Definition(def) {
/*-- Display --*/
public func GetCarryMode() { return CARRY_HandBack; }
public func GetCarrySpecial(clonk) { return carry_bone; }
public func GetCarryTransform(object clonk, bool idle, bool nohand)
{
if (nohand)
return Trans_Mul(Trans_Rotate(45, 0, 1), Trans_Rotate(25, 0, 0, 1), Trans_Translate(4000, 0, 1000));
//Left hand's bone is different? I don't know, but this is a work-around.
if(carry_bone == "pos_hand1") return Trans_Rotate(180,0,1,0);
return Trans_Rotate(-90,0,1,0);
}
func Definition(def)
{
SetProperty("PictureTransformation",Trans_Rotate(-60,1,0,1),def);
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = 1;
local Components = {Metal = 2};
local Collectible = true;
local Components = {Metal = 2};

View File

@ -13,24 +13,48 @@ local TRCH_InHand = 1;
local TRCH_Attached = 2;
local TRCH_Fixed = 3;
protected func Initialize()
/*-- Engine Callbacks --*/
func Initialize()
{
local state = TRCH_Normal;
SetMeshMaterial("Torch");
return;
}
private func Hit()
func Hit()
{
Sound("Hits::Materials::Wood::WoodHit?");
return;
}
public func GetCarryMode() { return CARRY_HandBack; }
// Set state on entrance of a clonk.
func Entrance(object container)
{
if (container->~IsClonk())
state = TRCH_InHand;
return _inherited(container, ...);
}
public func IsWorkshopProduct() { return true; }
public func IsTool() { return true; }
public func IsToolProduct() { return true; }
// Set state on departure from a clonk.
func Departure(object container)
{
if (container->~IsClonk())
state = TRCH_Normal;
return _inherited(container, ...);
}
public func SaveScenarioObject(proplist props, ...)
{
if (!_inherited(props, ...)) return false;
if (state == TRCH_Attached || state == TRCH_Fixed)
{
props->AddCall("Attach", this, "AttachToWall", state == TRCH_Fixed);
props->Remove("Category");
props->Remove("Plane");
}
return true;
}
/*-- Callbacks --*/
// Returns whether the torch currently is a source of light.
public func IsLightSource()
@ -38,6 +62,15 @@ public func IsLightSource()
return !!GetEffect("IntBurning", this);
}
public func IsInteractable(object clonk)
{
return state == TRCH_Attached;
}
public func GetInteractionMetaInfo(object clonk)
{
return { Description = "$MsgTorchDetach$", IconName = nil, IconID = nil, Selected = false };
}
/*-- Usage --*/
@ -62,16 +95,6 @@ public func ControlUse(object clonk)
return true;
}
public func IsInteractable(object clonk)
{
return state == TRCH_Attached;
}
func GetInteractionMetaInfo(object clonk)
{
return { Description = "$MsgTorchDetach$", IconName = nil, IconID = nil, Selected = false };
}
public func Interact(object clonk)
{
// Do an detach animation.
@ -122,26 +145,9 @@ public func SetState(int to_state)
return;
}
// Set state on entrance of a clonk.
protected func Entrance(object container)
{
if (container->~IsClonk())
state = TRCH_InHand;
return _inherited(container, ...);
}
// Set state on departure from a clonk.
protected func Departure(object container)
{
if (container->~IsClonk())
state = TRCH_Normal;
return _inherited(container, ...);
}
/*-- Burning Effect --*/
private func FxIntBurningStart(object target, effect fx, int temporary)
func FxIntBurningStart(object target, effect fx, int temporary)
{
if (temporary)
return 1;
@ -177,7 +183,7 @@ private func FxIntBurningStart(object target, effect fx, int temporary)
return 1;
}
private func FxIntBurningTimer (object target, effect fx, int time)
func FxIntBurningTimer (object target, effect fx, int time)
{
// If the torched is attached or fixed it should emit some fire and smoke particles.
if (state == TRCH_Attached || state == TRCH_Fixed)
@ -190,36 +196,38 @@ private func FxIntBurningTimer (object target, effect fx, int time)
return 1;
}
protected func FxIntBurningStop(object target, proplist effect, int reason, bool temporary)
func FxIntBurningStop(object target, proplist effect, int reason, bool temporary)
{
if (temporary)
return 1;
// Remove the light from this torch.
// Remove the light from this torch.
SetLightRange(0);
return 1;
}
public func SaveScenarioObject(proplist props, ...)
/*-- Production --*/
public func IsTool() { return true; }
public func IsToolProduct() { return true; }
/*-- Display --*/
public func GetCarryMode(object clonk, bool idle, bool nohand)
{
if (!_inherited(props, ...)) return false;
if (state == TRCH_Attached || state == TRCH_Fixed)
{
props->AddCall("Attach", this, "AttachToWall", state == TRCH_Fixed);
props->Remove("Category");
props->Remove("Plane");
}
return true;
if (idle || nohand)
return CARRY_Back;
return CARRY_Spear;
}
/*-- Properties --*/
protected func Definition(def)
func Definition(def)
{
SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(2500, -1500, 0), Trans_Rotate(-30, 0, 0, 1)), def);
}
local Collectible = 1;
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Components = {Wood = 1, Coal = 1};
local Collectible = true;
local Components = {Wood = 1, Coal = 1};

View File

@ -7,47 +7,22 @@
local fill_amount;
/*-- Engine Callbacks --*/
protected func Initialize()
func Initialize()
{
SetR(-45);
AddEffect("IntReload", this, 100, 1, this);
return;
}
protected func Hit()
func Hit()
{
Sound("Hits::GeneralHit?");
return;
}
public func GetCarryMode(clonk) { return CARRY_Musket; }
public func GetCarryTransform()
{
return Trans_Mul(Trans_Rotate(220, 0, 1, 0), Trans_Rotate(30, 0, 0, 1), Trans_Rotate(-26, 1, 0, 0));
}
public func GetCarryPhase() { return 600; }
public func IsInventorProduct() { return true; }
/*-- Usage --*/
func RejectUse(object clonk)
{
return false;
}
// used by this object
func ReadyToBeUsed(proplist data)
{
var clonk = data.clonk;
return !RejectUse(clonk) && !GetEffect("IntReload", this);
}
protected func ControlUse(object clonk, x, y)
public func ControlUse(object clonk, x, y)
{
if (!GetEffect("IntReload", this) && !GetEffect("IntBurstWind", this))
{
@ -60,6 +35,11 @@ protected func ControlUse(object clonk, x, y)
return true;
}
func ReadyToBeUsed(proplist data)
{
var clonk = data.clonk;
return !GetEffect("IntReload", this);
}
/*-- Loading --*/
@ -69,7 +49,7 @@ public func DoFullLoad()
return;
}
public func FxIntReloadStart(object target, proplist effect, int temp)
func FxIntReloadStart(object target, proplist effect, int temp)
{
if (temp)
return FX_OK;
@ -78,7 +58,7 @@ public func FxIntReloadStart(object target, proplist effect, int temp)
return FX_OK;
}
public func FxIntReloadTimer(object target, proplist effect, int time)
func FxIntReloadTimer(object target, proplist effect, int time)
{
if (fill_amount > MaxIntake)
return FX_Execute_Kill;
@ -121,7 +101,7 @@ public func FxIntReloadTimer(object target, proplist effect, int time)
return FX_OK;
}
public func FxIntReloadStop(object target, proplist effect, int reason, bool temp)
func FxIntReloadStop(object target, proplist effect, int reason, bool temp)
{
if (temp)
return FX_OK;
@ -133,10 +113,9 @@ public func FxIntReloadStop(object target, proplist effect, int reason, bool tem
return FX_OK;
}
/*-- Blasting --*/
private func BlastWind(object clonk, int x, int y)
public func BlastWind(object clonk, int x, int y)
{
if (fill_amount <= 0)
{
@ -146,10 +125,9 @@ private func BlastWind(object clonk, int x, int y)
}
// The blast is handled by an effect.
AddEffect("IntBurstWind", this, 100, 1, this, nil, clonk, x, y);
return;
}
public func FxIntBurstWindStart(object target, proplist effect, int temp, object clonk, int x, int y)
func FxIntBurstWindStart(object target, proplist effect, int temp, object clonk, int x, int y)
{
if (temp)
return FX_OK;
@ -176,7 +154,7 @@ public func FxIntBurstWindStart(object target, proplist effect, int temp, object
return FX_OK;
}
public func FxIntBurstWindTimer(object target, proplist effect, int time)
func FxIntBurstWindTimer(object target, proplist effect, int time)
{
var real_time = time + 1;
if (real_time > 8)
@ -218,7 +196,7 @@ public func FxIntBurstWindTimer(object target, proplist effect, int time)
return FX_OK;
}
public func FxIntBurstWindStop(object target, proplist effect, int reason, bool temp)
func FxIntBurstWindStop(object target, proplist effect, int reason, bool temp)
{
if (temp)
return FX_OK;
@ -228,23 +206,49 @@ public func FxIntBurstWindStop(object target, proplist effect, int reason, bool
return FX_OK;
}
public func DrawParticleRing(int r, int x, int y)
func DrawParticleRing(int r, int x, int y)
{
for (var angle = 0; angle < 360; angle += 15)
CreateParticle("SphereSpark", x + Cos(angle, r), y + Sin(angle, r), 0, 0, 36, { Size = 2 });
return;
}
/*-- Production --*/
/*-- Properties --*/
public func IsInventorProduct() { return true; }
protected func Definition(def)
/*-- Display --*/
public func GetCarryMode(object clonk)
{
return CARRY_Musket;
}
public func GetCarryTransform(object clonk, bool idle, bool nohand, bool second_on_back)
{
if (idle)
{
if (!second_on_back)
return Trans_Mul(Trans_Rotate(180, 1), Trans_Translate(0,-3000));
else
return Trans_Mul(Trans_Rotate(180, 1), Trans_Translate(3000,-3000), Trans_Rotate(-30, 0, 1));
}
if (nohand)
return Trans_Mul(Trans_Rotate(180, 1), Trans_Translate(0,3000));
return Trans_Mul(Trans_Rotate(220, 0, 1, 0), Trans_Rotate(30, 0, 0, 1), Trans_Rotate(-26, 1, 0, 0));
}
public func GetCarryPhase() { return 600; }
func Definition(def)
{
SetProperty("PictureTransformation", Trans_Mul(Trans_Scale(1500), Trans_Rotate(150, 0, 0, 1), Trans_Rotate(-170, 1, 0, 0), Trans_Rotate(10, 0, 1, 0)), def);
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = 1;
local Collectible = true;
local MaxIntake = 30;
local Components = {Cloth = 1, Metal = 1};
local Components = {Cloth = 1, Metal = 1};

View File

@ -1,37 +1,18 @@
/*
/**
Bow
Author: Newton
The standard bow. This object is a standard projectile weapon with an extra slot.
The standard bow. This object is a standard projectile weapon
with an extra slot.
@author: Newton
*/
// has extra slot
#include Library_HasExtraSlot
// Initial velocity of the arrow
local shooting_strength = 100;
private func Hit()
{
Sound("Hits::Materials::Wood::WoodHit?");
}
local fAiming;
local iArrowMesh;
public func GetCarryMode() { return CARRY_HandBack; }
public func GetCarrySpecial(clonk) { if(fAiming) return "pos_hand2"; }
/* +++++++++++ Controls ++++++++++++++ */
// holding callbacks are made
public func HoldingEnabled() { return true; }
local animation_set;
/*-- Engine Callbacks --*/
func Initialize()
{
animation_set = {
@ -55,8 +36,71 @@ func Initialize()
};
}
func Hit()
{
Sound("Hits::Materials::Wood::WoodHit?");
}
func RejectCollect(id arrowid, object arrows)
{
// arrows are not arrows? decline!
if(!(arrows->~IsArrow())) return true;
}
/*-- Callbacks --*/
public func GetAnimationSet() { return animation_set; }
// Attach the arrow during the animation
public func DuringLoad(object clonk) { return AddArrow(clonk); }
// Callback from the clonk when loading is finished
public func FinishedLoading(object clonk)
{
clonk->~StartAim(this);
return true;
}
// Callback from the clonk, when he actually has stopped aiming
public func FinishedAiming(object clonk, int angle)
{
clonk->DetachMesh(iArrowMesh);
iArrowMesh = nil;
// shoot
if(Contents(0))
{
if(Contents(0)->~IsArrow())
{
var arrow = Contents(0)->TakeObject();
arrow->Launch(angle,shooting_strength,clonk);
Sound("Objects::Weapons::Bow::Shoot?");
}
}
// Open the hand to let the string go and play the fire animation
PlayAnimation("Fire", 6, Anim_Linear(0, 0, GetAnimationLength("Fire"), animation_set["ShootTime"], ANIM_Hold));
clonk->PlayAnimation("Close1Hand", 11, Anim_Const(0), Anim_Const(1000));
clonk->StartShoot(this);
return true;
}
/*
func Selection()
{
Sound("Objects::Weapons::Bow::Draw");
}
func Deselection()
{
Sound("Objects::Weapons::Bow::PutAwayBow");
}
*/
/*-- Usage --*/
public func HoldingEnabled() { return true; }
public func RejectUse(object clonk)
{
// if the clonk doesn't have an action where he can use it's hands do nothing
@ -95,23 +139,6 @@ public func ControlUseStart(object clonk, int x, int y)
return true;
}
// Attach the arrow during the animation
public func DuringLoad(object clonk) { return AddArrow(clonk); }
// Called during loading then the arrow is added to the animation
public func AddArrow(object clonk)
{
Sound("Objects::Weapons::Bow::Load?");
iArrowMesh = clonk->AttachMesh(HelpArrow, "pos_hand1", "main", nil);
}
// Callback from the clonk when loading is finished
public func FinishedLoading(object clonk)
{
clonk->~StartAim(this);
return true;
}
// Update the angle on mouse movement
public func ControlUseHolding(object clonk, int x, int y)
{
@ -134,37 +161,18 @@ public func ControlUseStop(object clonk, int x, int y)
return true;
}
// Callback from the clonk, when he actually has stopped aiming
public func FinishedAiming(object clonk, int angle)
{
clonk->DetachMesh(iArrowMesh);
iArrowMesh = nil;
// shoot
if(Contents(0))
{
if(Contents(0)->~IsArrow())
{
var arrow = Contents(0)->TakeObject();
arrow->Launch(angle,shooting_strength,clonk);
Sound("Objects::Weapons::Bow::Shoot?");
}
}
// Open the hand to let the string go and play the fire animation
PlayAnimation("Fire", 6, Anim_Linear(0, 0, GetAnimationLength("Fire"), animation_set["ShootTime"], ANIM_Hold));
clonk->PlayAnimation("Close1Hand", 11, Anim_Const(0), Anim_Const(1000));
clonk->StartShoot(this);
return true;
}
public func ControlUseCancel(object clonk, int x, int y)
{
clonk->CancelAiming(this);
return true;
}
/* ++++++++ Animation functions ++++++++ */
// Called during loading then the arrow is added to the animation
public func AddArrow(object clonk)
{
Sound("Objects::Weapons::Bow::Load?");
iArrowMesh = clonk->AttachMesh(HelpArrow, "pos_hand1", "main", nil);
}
public func Reset(clonk)
{
@ -177,9 +185,7 @@ public func Reset(clonk)
StopAnimation(GetRootAnimation(6));
}
/* ++++++++ Helper functions ++++++++ */
private func ClonkAimLimit(object clonk, int angle)
func ClonkAimLimit(object clonk, int angle)
{
angle = Normalize(angle,-180);
if(Abs(angle) > 160) return false;
@ -188,8 +194,6 @@ private func ClonkAimLimit(object clonk, int angle)
return true;
}
/* +++++++++++ Slow walk +++++++++++ */
func FxIntWalkSlowStart(pTarget, effect, fTmp, iValue)
{
if(iValue == nil || iValue == 0) iValue = 84;
@ -201,37 +205,39 @@ func FxIntWalkSlowStop(pTarget, effect)
pTarget->PopActionSpeed("Walk");
}
/* +++++++++++ Various callbacks +++++++++ */
func RejectCollect(id arrowid, object arrows)
{
// arrows are not arrows? decline!
if(!(arrows->~IsArrow())) return true;
}
/*
func Selection()
{
Sound("Objects::Weapons::Bow::Draw");
}
func Deselection()
{
Sound("Objects::Weapons::Bow::PutAwayBow");
}
*/
/*-- Production --*/
public func IsWeapon() { return true; }
public func IsArmoryProduct() { return true; }
/*-- Display --*/
public func GetCarryMode(object clonk, bool idle)
{
if (idle)
return CARRY_Back;
return CARRY_HandBack;
}
public func GetCarrySpecial(clonk)
{
if(fAiming) return "pos_hand2";
}
func Definition(def)
{
def.PictureTransformation = Trans_Mul(Trans_Translate(-4000,-2000,4000),Trans_Rotate(180,0,1,0),Trans_Rotate(-45,0,0,1));
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = 1;
local Collectible = true;
local BlastIncinerate = 30;
local ContactIncinerate = 5;
local ForceFreeHands = true;
local Components = {Wood = 3};
// Initial velocity of the arrow
local shooting_strength = 100;

View File

@ -1,33 +1,26 @@
/*-- Club --*/
/**
Club
Simple striking weapon.
*/
#include Library_MeleeWeapon
private func Hit()
{
Sound("Hits::Materials::Wood::WoodHit?");
}
public func GetCarryMode() { return CARRY_HandBack; }
public func GetCarrySpecial(clonk)
{
if(fAiming)
{
if(clonk->GetHandPosByItemPos(clonk->GetItemPos(this)) == 1)
return "pos_hand1";
else
return "pos_hand2";
}
}
local animation_set;
local fAiming;
/*-- Engine Callbacks --*/
func Initialize()
{
ClubChangeHandAnims("R");
}
private func ClubChangeHandAnims(string hand)
func Hit()
{
Sound("Hits::Materials::Wood::WoodHit?");
}
func ClubChangeHandAnims(string hand)
{
if(hand == "R")
{
@ -59,11 +52,36 @@ private func ClubChangeHandAnims(string hand)
}
}
/*-- Callbacks --*/
public func GetAnimationSet() { return animation_set; }
public func HoldingEnabled() { return true; }
// Callback from the clonk, when he actually has stopped aiming
public func FinishedAiming(object clonk, int angle)
{
clonk->StartShoot(this);
// since the Clonk internal callback is only once, we cannot use it
// ..
AddEffect("DuringClubShootControl", clonk, 1, 1, this, nil, angle);
// aaaand, a cooldown
AddEffect("ClubWeaponCooldown", clonk, 1, 5, this);
Sound("Objects::Weapons::WeaponSwing?", {pitch = -50});
return true;
}
local fAiming;
// Called in the half of the shoot animation (when ShootTime2 is over)
public func DuringShoot(object clonk, int angle)
{
// called only once. We don't want it only once..
// DoStrike(clonk, angle);
}
/*-- Usage --*/
public func HoldingEnabled() { return true; }
public func RejectUse(object clonk)
{
@ -83,7 +101,7 @@ public func ControlUseStart(object clonk, int x, int y)
return 1;
}
func ControlUseHolding(object clonk, ix, iy)
public func ControlUseHolding(object clonk, ix, iy)
{
var angle = Angle(0,0,ix,iy);
angle = Normalize(angle,-180);
@ -99,29 +117,7 @@ public func ControlUseStop(object clonk, ix, iy)
return true;
}
public func ControlUseCancel(object clonk, ix, iy)
{
clonk->StopAim();
return true;
}
// Callback from the clonk, when he actually has stopped aiming
public func FinishedAiming(object clonk, int angle)
{
clonk->StartShoot(this);
// since the Clonk internal callback is only once, we cannot use it
// ..
AddEffect("DuringClubShootControl", clonk, 1, 1, this, nil, angle);
// aaaand, a cooldown
AddEffect("ClubWeaponCooldown", clonk, 1, 5, this);
Sound("Objects::Weapons::WeaponSwing?", {pitch = -50});
return true;
}
protected func ControlUseCancel(object clonk, int x, int y)
public func ControlUseCancel(object clonk, int x, int y)
{
clonk->CancelAiming(this);
return true;
@ -132,13 +128,6 @@ public func Reset(clonk)
fAiming = 0;
}
// Called in the half of the shoot animation (when ShootTime2 is over)
public func DuringShoot(object clonk, int angle)
{
// called only once. We don't want it only once..
// DoStrike(clonk, angle);
}
func FxDuringClubShootControlStart(target, effect, temp, p1)
{
if(temp) return;
@ -239,16 +228,49 @@ func DoStrike(clonk, angle)
}
}
/*-- Production --*/
public func IsWeapon() { return true; }
public func IsArmoryProduct() { return true; }
/*-- Display --*/
public func GetCarryMode(object clonk, bool idle, bool nohand)
{
if (idle || nohand)
return CARRY_Back;
return CARRY_Musket;
}
public func GetCarrySpecial(clonk)
{
if(fAiming)
{
if(clonk->GetHandPosByItemPos(clonk->GetItemPos(this)) == 1)
return "pos_hand1";
else
return "pos_hand2";
}
}
public func GetCarryTransform(object clonk, bool idle, bool nohand)
{
if (idle || nohand || fAiming)
return;
return Trans_Mul(Trans_Rotate(10, 0, 1), Trans_Translate(-800));
}
func Definition(def)
{
def.PictureTransformation = Trans_Mul(Trans_Translate(-4500, -2000, 2000), Trans_Rotate(45,0,0,1));
}
local Collectible = 1;
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = true;
local ForceFreeHands = true;
local Components = {Wood = 1, Metal = 1};
local Components = {Wood = 1, Metal = 1};

View File

@ -1,33 +1,25 @@
/*--
/**
Grenade Launcher
Author: Clonkonaut
A single shot grenade launcher which fires dangerous iron bombs.
@author: Clonkonaut
*/
--*/
//Uses the extra slot library
#include Library_HasExtraSlot
// Initial velocity of the bomb
local shooting_strength = 75;
func Hit()
{
Sound("Hits::GeneralHit?");
}
local is_aiming;
public func GetCarryMode(clonk) { return CARRY_Musket; }
public func GetCarrySpecial(clonk) { if (is_aiming) return "pos_hand2"; }
public func GetCarryBone() { return "main"; }
public func GetCarryTransform()
{
return Trans_Mul(Trans_Rotate(90,1,0,0), Trans_Rotate(-10,0,0,1));
}
local animation_set;
local loaded;
local reload;
local yOffset;
local iBarrel;
local holding;
local MuzzleUp; local MuzzleFront; local MuzzleDown; local MuzzleOffset;
/*-- Engine Callbacks --*/
func Initialize()
{
@ -52,26 +44,58 @@ func Initialize()
};
}
func Hit()
{
Sound("Hits::GeneralHit?");
}
func RejectCollect(id shotid, object shot)
{
// Only collect grenade launcher ammo
if(!(shot->~IsGrenadeLauncherAmmo())) return true;
}
/*-- Callbacks --*/
public func GetAnimationSet() { return animation_set; }
local loaded;
local reload;
// Callback from the clonk when loading is finished
public func FinishedLoading(object clonk)
{
SetLoaded();
if(holding) clonk->StartAim(this);
return holding; // false means stop here and reset the clonk
}
local yOffset;
local iBarrel;
// Callback from the clonk, when he actually has stopped aiming
public func FinishedAiming(object clonk, int angle)
{
if(!loaded) return;
// Fire
if(Contents(0) && Contents(0)->~IsGrenadeLauncherAmmo())
FireWeapon(clonk, angle);
Trajectory->Remove(clonk);
clonk->StartShoot(this);
return true;
}
local holding;
// Can only be stacked with same state: loaded vs. non-loaded.
public func CanBeStackedWith(object other)
{
return this->IsLoaded() == other->~IsLoaded() && inherited(other, ...);
}
local MuzzleUp; local MuzzleFront; local MuzzleDown; local MuzzleOffset;
/*-- Usage --*/
protected func HoldingEnabled() { return true; }
public func HoldingEnabled() { return true; }
public func RejectUse(object clonk)
{
return !clonk->HasHandAction(false, false, true);
}
func ControlUseStart(object clonk, int x, int y)
public func ControlUseStart(object clonk, int x, int y)
{
// nothing in extraslot?
if(!Contents(0))
@ -105,15 +129,7 @@ func ControlUseStart(object clonk, int x, int y)
return true;
}
// Callback from the clonk when loading is finished
public func FinishedLoading(object clonk)
{
SetLoaded();
if(holding) clonk->StartAim(this);
return holding; // false means stop here and reset the clonk
}
func ControlUseHolding(object clonk, ix, iy)
public func ControlUseHolding(object clonk, ix, iy)
{
var angle = Angle(0,0,ix,iy-MuzzleOffset);
angle = Normalize(angle,-180);
@ -130,39 +146,26 @@ func ControlUseHolding(object clonk, ix, iy)
return true;
}
protected func ControlUseStop(object clonk, ix, iy)
{
holding = false;
clonk->StopAim();
return true;
}
// Callback from the clonk, when he actually has stopped aiming
public func FinishedAiming(object clonk, int angle)
{
if(!loaded) return;
// Fire
if(Contents(0) && Contents(0)->~IsGrenadeLauncherAmmo())
FireWeapon(clonk, angle);
Trajectory->Remove(clonk);
clonk->StartShoot(this);
return true;
}
protected func ControlUseCancel(object clonk, int x, int y)
public func ControlUseCancel(object clonk, int x, int y)
{
clonk->CancelAiming(this);
Trajectory->Remove(clonk);
return true;
}
public func ControlUseStop(object clonk, ix, iy)
{
holding = false;
clonk->StopAim();
return true;
}
public func Reset(clonk)
{
is_aiming = false;
}
private func FireWeapon(object clonk, int angle)
func FireWeapon(object clonk, int angle)
{
var shot = Contents(0)->~TakeObject() ?? Contents(0);
@ -191,12 +194,6 @@ private func FireWeapon(object clonk, int angle)
CreateParticle("Flash", 0, 0, 0, 0, 8, Particles_Flash());
}
func RejectCollect(id shotid, object shot)
{
// Only collect grenade launcher ammo
if(!(shot->~IsGrenadeLauncherAmmo())) return true;
}
public func SetLoaded()
{
loaded = true;
@ -207,24 +204,55 @@ public func SetLoaded()
public func IsLoaded() { return loaded; }
// Can only be stacked with same state: loaded vs. non-loaded.
public func CanBeStackedWith(object other)
{
return this->IsLoaded() == other->~IsLoaded() && inherited(other, ...);
}
/*-- Production --*/
public func IsWeapon() { return true; }
public func IsArmoryProduct() { return true; }
/*-- Display --*/
public func GetCarryMode(object clonk, bool idle, bool nohand)
{
if (idle || nohand)
return CARRY_Back;
return CARRY_Musket;
}
public func GetCarrySpecial()
{
if (is_aiming) return "pos_hand2";
}
public func GetCarryTransform(object clonk, bool idle, bool nohand, bool second_on_back)
{
if (is_aiming)
return Trans_Mul(Trans_Rotate(90,1,0,0), Trans_Rotate(-10,0,0,1));
if (idle)
{
if (!second_on_back)
return Trans_Mul(Trans_Translate(0, 3000), Trans_Rotate(180, 1));
else
return Trans_Mul(Trans_Translate(3000, 3000, -1500), Trans_Rotate(180, 1), Trans_Rotate(-30, 0, 1));
}
if (nohand)
return Trans_Translate(0, -3000);
return Trans_Mul(Trans_Rotate(90,1,0,0), Trans_Rotate(-10,0,0,1));
}
func Definition(def)
{
def.PictureTransformation = Trans_Mul(Trans_Translate(-3000, 1000, 1500),Trans_Rotate(170,0,1,0),Trans_Rotate(30,0,0,1));
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = 1;
local Collectible = true;
local ForceFreeHands = true;
local Components = {Wood = 1, Metal = 3};
local Components = {Wood = 1, Metal = 3};
// Initial velocity of the bomb
local shooting_strength = 75;

View File

@ -1,21 +1,16 @@
/*--
Javelin
Author: Ringwaul
A simple but dangerous throwing weapon.
@author: Ringwaul
--*/
#include Library_Stackable
// Multiplication factor to clonk.ThrowSpeed
local shooting_strength = 21;
public func MaxStackCount() { return 3; }
// Note that the javelin damage also takes the speed into account. A direct eye-to-eye hit will do roughly this damage.
public func JavelinStrength() { return 16; }
public func TumbleStrength() { return 100; }
local animation_set;
local aiming;
/*-- Engine Callbacks --*/
func Initialize()
{
@ -31,51 +26,29 @@ func Initialize()
};
}
func Hit()
{
if(GetEffect("Flight",this))
{
Stick();
Sound("Objects::Weapons::Javelin::HitGround");
}
else
Sound("Hits::Materials::Wood::WoodHit?");
}
func Entrance()
{
// reset sticky-vertex
SetVertex(2,VTX_Y,0,1);
}
/*-- Callbacks --*/
public func MaxStackCount() { return 3; }
public func GetAnimationSet() { return animation_set; }
local aiming;
public func GetCarryMode(clonk) { if(aiming >= 0) return CARRY_HandBack; }
public func GetCarryBone() { return "Javelin"; }
public func GetCarrySpecial(clonk) { if(aiming > 0) return "pos_hand2"; }
public func GetCarryTransform() { if(aiming == 1) return Trans_Rotate(180, 0, 0, 1); }
public func RejectUse(object clonk)
{
return !clonk->HasHandAction(false, false, true);
}
public func ControlUseStart(object clonk, int x, int y)
{
aiming = 1;
clonk->StartAim(this);
ControlUseHolding(clonk, x, y);
Sound("Objects::Weapons::Javelin::Draw");
return 1;
}
public func HoldingEnabled() { return true; }
func ControlUseHolding(object clonk, ix, iy)
{
var angle = Angle(0,0,ix,iy);
angle = Normalize(angle,-180);
clonk->SetAimPosition(angle);
return true;
}
protected func ControlUseStop(object clonk, ix, iy)
{
if(aiming)
clonk->StopAim();
return true;
}
// Callback from the clonk, when he actually has stopped aiming
public func FinishedAiming(object clonk, int angle)
{
@ -83,48 +56,12 @@ public func FinishedAiming(object clonk, int angle)
return true;
}
public func ControlUseCancel(object clonk, int x, int y)
{
clonk->CancelAiming(this);
return true;
}
public func Reset(clonk)
{
aiming = 0;
}
// Called in the half of the shoot animation (when ShootTime2 is over)
public func DuringShoot(object clonk, int angle)
{
DoThrow(clonk, angle);
}
public func DoThrow(object clonk, int angle)
{
var javelin=TakeObject();
var div = 60; // 40% is converted to the direction of the throwing angle.
var xdir = clonk->GetXDir(1000);
var ydir = clonk->GetYDir(1000);
var speed = clonk.ThrowSpeed * shooting_strength + (100 - div) * Sqrt(xdir**2 + ydir**2) / 100;
var jav_x = div * xdir / 100 + Sin(angle, speed);
var jav_y = div * ydir / 100 - Cos(angle, speed);
SetController(clonk->GetController());
javelin->AddEffect("Flight",javelin,1,1,javelin,nil);
javelin->AddEffect("HitCheck",javelin,1,1,nil,nil,clonk);
javelin->SetXDir(jav_x, 1000);
javelin->SetYDir(jav_y, 1000);
javelin->SetPosition(clonk->GetX(), clonk->GetY() - 6);
Sound("Objects::Weapons::Javelin::Throw?");
aiming = -1;
clonk->UpdateAttach();
}
//slightly modified HitObject() from arrow
public func HitObject(object obj)
{
@ -150,18 +87,85 @@ public func HitObject(object obj)
Stick();
}
protected func Hit()
/*-- Usage --*/
public func HoldingEnabled() { return true; }
public func RejectUse(object clonk)
{
if(GetEffect("Flight",this))
{
Stick();
Sound("Objects::Weapons::Javelin::HitGround");
}
else
Sound("Hits::Materials::Wood::WoodHit?");
return !clonk->HasHandAction(false, false, true);
}
protected func Stick()
public func ControlUseStart(object clonk, int x, int y)
{
aiming = 1;
clonk->StartAim(this);
ControlUseHolding(clonk, x, y);
Sound("Objects::Weapons::Javelin::Draw");
return 1;
}
public func ControlUseHolding(object clonk, ix, iy)
{
var angle = Angle(0,0,ix,iy);
angle = Normalize(angle,-180);
clonk->SetAimPosition(angle);
return true;
}
public func ControlUseCancel(object clonk, int x, int y)
{
clonk->CancelAiming(this);
return true;
}
public func ControlUseStop(object clonk, ix, iy)
{
if(aiming)
clonk->StopAim();
return true;
}
// Note that the javelin damage also takes the speed into account. A direct eye-to-eye hit will do roughly this damage.
public func JavelinStrength() { return 16; }
public func TumbleStrength() { return 100; }
public func Reset(clonk)
{
aiming = 0;
}
public func DoThrow(object clonk, int angle)
{
var javelin=TakeObject();
var div = 60; // 40% is converted to the direction of the throwing angle.
var xdir = clonk->GetXDir(1000);
var ydir = clonk->GetYDir(1000);
var speed = clonk.ThrowSpeed * shooting_strength + (100 - div) * Sqrt(xdir**2 + ydir**2) / 100;
var jav_x = div * xdir / 100 + Sin(angle, speed);
var jav_y = div * ydir / 100 - Cos(angle, speed);
SetController(clonk->GetController());
javelin->AddEffect("Flight",javelin,1,1,javelin,nil);
javelin->AddEffect("HitCheck",javelin,1,1,nil,nil,clonk);
javelin->SetXDir(jav_x, 1000);
javelin->SetYDir(jav_y, 1000);
javelin->SetPosition(clonk->GetX(), clonk->GetY() - 6);
Sound("Objects::Weapons::Javelin::Throw?");
aiming = -1;
clonk->UpdateAttach();
}
func Stick()
{
if(GetEffect("Flight",this))
{
@ -187,13 +191,7 @@ protected func Stick()
}
}
func Entrance()
{
// reset sticky-vertex
SetVertex(2,VTX_Y,0,1);
}
protected func FxFlightStart(object target, effect fx, int temp)
func FxFlightStart(object target, effect fx, int temp)
{
if (temp)
return FX_OK;
@ -203,7 +201,7 @@ protected func FxFlightStart(object target, effect fx, int temp)
return FX_OK;
}
protected func FxFlightTimer(object target, effect fx, int time)
func FxFlightTimer(object target, effect fx, int time)
{
//Using Newton's arrow rotation. This would be much easier if we had arctan :(
var oldx = fx.x;
@ -222,7 +220,7 @@ protected func FxFlightTimer(object target, effect fx, int time)
return FX_OK;
}
protected func FxFlightStop(object target, effect fx, int reason, bool temp)
func FxFlightStop(object target, effect fx, int reason, bool temp)
{
if (temp)
return FX_OK;
@ -231,15 +229,46 @@ protected func FxFlightStop(object target, effect fx, int reason, bool temp)
return FX_OK;
}
/*-- Production --*/
public func IsWeapon() { return true; }
public func IsArmoryProduct() { return true; }
/*-- Display --*/
public func GetCarryMode(object clonk, bool idle, bool nohand)
{
if (idle || nohand)
return CARRY_Back;
if (aiming > 0)
return CARRY_Hand;
return CARRY_Spear;
}
public func GetCarryBone() { return "Javelin"; }
public func GetCarrySpecial(clonk)
{
if(aiming > 0) return "pos_hand2";
}
public func GetCarryTransform()
{
if(aiming == 1) return Trans_Rotate(180, 0, 0, 1);
}
func Definition(def) {
SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(40,0,0,1),Trans_Rotate(-10,1,0,0)),def);
}
local Collectible = 1;
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = true;
local ForceFreeHands = true;
local Components = {Wood = 2, Metal = 1};
// Multiplication factor to clonk.ThrowSpeed
local shooting_strength = 21;

View File

@ -1,30 +1,25 @@
/*--
/**
Musket
Author: Ringwaul
A single shot musket which fires metal-shot at incredible speed.
@author: Ringwaul
*/
--*/
//Uses the extra slot library
#include Library_HasExtraSlot
func Hit()
{
Sound("Hits::GeneralHit?");
}
local is_aiming;
public func GetCarryMode(clonk) { return CARRY_Musket; }
public func GetCarrySpecial(clonk) { if (is_aiming) return "pos_hand2"; }
public func GetCarryBone() { return "main"; }
public func GetCarryTransform()
{
return Trans_Rotate(90, 1, 0, 0);
}
local animation_set;
local loaded;
local reload;
local yOffset;
local iBarrel;
local holding;
local MuskUp; local MuskFront; local MuskDown; local MuskOffset;
/*-- Engine Callbacks --*/
func Initialize()
{
@ -49,26 +44,57 @@ func Initialize()
};
}
func Hit()
{
Sound("Hits::GeneralHit?");
}
func RejectCollect(id shotid, object shot)
{
// Only collect musket-ammo
if(!(shot->~IsMusketAmmo())) return true;
}
/*-- Callbacks --*/
public func GetAnimationSet() { return animation_set; }
local loaded;
local reload;
// Callback from the clonk when loading is finished
public func FinishedLoading(object clonk)
{
SetLoaded();
if(holding) clonk->StartAim(this);
return holding; // false means stop here and reset the clonk
}
local yOffset;
local iBarrel;
// Callback from the clonk, when he actually has stopped aiming
public func FinishedAiming(object clonk, int angle)
{
if(!loaded) return;
// Fire
if(Contents(0) && Contents(0)->IsMusketAmmo())
FireWeapon(clonk, angle);
clonk->StartShoot(this);
return true;
}
local holding;
// Can only be stacked with same state: loaded vs. non-loaded.
public func CanBeStackedWith(object other)
{
return this->IsLoaded() == other->~IsLoaded() && inherited(other, ...);
}
local MuskUp; local MuskFront; local MuskDown; local MuskOffset;
/*-- Usage --*/
protected func HoldingEnabled() { return true; }
public func HoldingEnabled() { return true; }
func RejectUse(object clonk)
public func RejectUse(object clonk)
{
return !clonk->HasHandAction(false, false, true);
}
func ControlUseStart(object clonk, int x, int y)
public func ControlUseStart(object clonk, int x, int y)
{
// nothing in extraslot?
if(!Contents(0))
@ -104,15 +130,7 @@ func ControlUseStart(object clonk, int x, int y)
return true;
}
// Callback from the clonk when loading is finished
public func FinishedLoading(object clonk)
{
SetLoaded();
if(holding) clonk->StartAim(this);
return holding; // false means stop here and reset the clonk
}
func ControlUseHolding(object clonk, ix, iy)
public func ControlUseHolding(object clonk, ix, iy)
{
var angle = Angle(0,0,ix,iy-MuskOffset);
angle = Normalize(angle,-180);
@ -122,37 +140,25 @@ func ControlUseHolding(object clonk, ix, iy)
return true;
}
protected func ControlUseStop(object clonk, ix, iy)
public func ControlUseCancel(object clonk, int x, int y)
{
clonk->CancelAiming(this);
return true;
}
public func ControlUseStop(object clonk, ix, iy)
{
holding = false;
clonk->StopAim();
return true;
}
// Callback from the clonk, when he actually has stopped aiming
public func FinishedAiming(object clonk, int angle)
{
if(!loaded) return;
// Fire
if(Contents(0) && Contents(0)->IsMusketAmmo())
FireWeapon(clonk, angle);
clonk->StartShoot(this);
return true;
}
protected func ControlUseCancel(object clonk, int x, int y)
{
clonk->CancelAiming(this);
return true;
}
public func Reset(clonk)
{
is_aiming = false;
}
private func FireWeapon(object clonk, int angle)
func FireWeapon(object clonk, int angle)
{
// calculate offset for shot and effects
var IX=Sin(180-angle,MuskFront);
@ -177,12 +183,6 @@ private func FireWeapon(object clonk, int angle)
CreateParticle("Flash", 0, 0, 0, 0, 8, Particles_Flash());
}
func RejectCollect(id shotid, object shot)
{
// Only collect musket-ammo
if(!(shot->~IsMusketAmmo())) return true;
}
public func SetLoaded()
{
loaded = true;
@ -193,21 +193,39 @@ public func SetLoaded()
public func IsLoaded() { return loaded; }
// Can only be stacked with same state: loaded vs. non-loaded.
public func CanBeStackedWith(object other)
{
return this->IsLoaded() == other->~IsLoaded() && inherited(other, ...);
}
/*-- Production --*/
public func IsWeapon() { return true; }
public func IsArmoryProduct() { return true; }
/*-- Display --*/
public func GetCarryMode(object clonk, bool idle, bool nohand)
{
if (idle || nohand)
return CARRY_Back;
return CARRY_Musket;
}
public func GetCarrySpecial(clonk)
{
if (is_aiming) return "pos_hand2";
}
public func GetCarryTransform()
{
return Trans_Rotate(90, 1, 0, 0);
}
func Definition(def) {
SetProperty("PictureTransformation",Trans_Mul(Trans_Translate(1500,0,-1500),Trans_Rotate(170,0,1,0),Trans_Rotate(30,0,0,1)),def);
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = 1;
local Collectible = true;
local ForceFreeHands = true;
local Components = {Wood = 1, Metal = 2};

View File

@ -1,4 +1,7 @@
/*-- Shield --*/
/**
Shield
Offers protection against all kinds of attacks.
*/
#include Library_MeleeWeapon
@ -9,9 +12,47 @@ local mTrans;
local solid_mask_helper;
/* Usage callbacks */
/*-- Engine Callbacks --*/
func RejectUse(object clonk)
func Hit()
{
Sound("Hits::Materials::Metal::DullMetalHit?");
}
// Colour by owner
func Entrance(object container)
{
if(container->GetOwner() != NO_OWNER) SetColor(GetPlayerColor(container->GetOwner()));
}
/*-- Callbacks --*/
public func HitByWeapon(by, iDamage)
{
var object_angle = Angle(GetX(),GetY(),by->GetX(), by->GetY());
var shield_angle = iAngle;
// angle difference: 0..180
var angle_diff = Abs(Normalize(shield_angle-object_angle,-180));
if (angle_diff > 45) return 0;
Sound("Objects::Weapons::Shield::MetalHit?");
// bash him hard!
ApplyWeaponBash(by, 100, iAngle);
// uber advantage in melee combat
AddEffect("ShieldBlockWeaponCooldown", by, 1, 30, this);
// shield factor
return 100;
}
/*-- Usage --*/
public func HoldingEnabled() { return true; }
public func RejectUse(object clonk)
{
return !clonk->HasHandAction() || !clonk->IsWalking() || !CanStrikeWithWeapon(clonk);
}
@ -28,13 +69,6 @@ public func ControlUseHolding(object clonk, int x, int y)
UpdateShieldAngle(clonk, x, y);
}
public func HoldingEnabled() { return true; }
public func ControlUseStop(object clonk)
{
ControlUseCancel(clonk);
}
public func ControlUseCancel(object clonk)
{
EndUsage(clonk);
@ -42,7 +76,12 @@ public func ControlUseCancel(object clonk)
RemoveEffect("IntShieldSuspend", clonk);
}
private func StartUsage(object clonk)
public func ControlUseStop(object clonk)
{
ControlUseCancel(clonk);
}
func StartUsage(object clonk)
{
var hand;
// which animation to use? (which hand)
@ -78,7 +117,7 @@ private func StartUsage(object clonk)
clonk->SetTurnType(1, 1);
}
private func EndUsage(object clonk)
func EndUsage(object clonk)
{
carry_bone = nil;
aim_anim = nil;
@ -100,8 +139,7 @@ private func EndUsage(object clonk)
StopWeaponHitCheckEffect(clonk);
}
// Update the shield angle
private func UpdateShieldAngle(object clonk, int x, int y)
func UpdateShieldAngle(object clonk, int x, int y)
{
var angle=Normalize(Angle(0,0, x,y),-180);
angle=BoundBy(angle,-150,150);
@ -130,7 +168,7 @@ private func UpdateShieldAngle(object clonk, int x, int y)
// Adjust solid mask of shield
// if the shield is held up, it has a solid mask on which other clonks can climb onto
private func AdjustSolidMaskHelper()
func AdjustSolidMaskHelper()
{
if(aim_anim && Contained() && Abs(iAngle) <= 20)
{
@ -159,40 +197,6 @@ private func AdjustSolidMaskHelper()
solid_mask_helper->SetVertexXY(0, -x, -y);
}
/* other callbacks */
func Hit()
{
Sound("Hits::Materials::Metal::DullMetalHit?");
}
func OnWeaponHitCheckStop()
{
return;
}
func HitByWeapon(by, iDamage)
{
var object_angle = Angle(GetX(),GetY(),by->GetX(), by->GetY());
var shield_angle = iAngle;
// angle difference: 0..180
var angle_diff = Abs(Normalize(shield_angle-object_angle,-180));
if (angle_diff > 45) return 0;
Sound("Objects::Weapons::Shield::MetalHit?");
// bash him hard!
ApplyWeaponBash(by, 100, iAngle);
// uber advantage in melee combat
AddEffect("ShieldBlockWeaponCooldown", by, 1, 30, this);
// shield factor
return 100;
}
/* main shield effect */
func FxShieldStopControlStart(object target, effect, temp)
{
target->PushActionSpeed("Walk", 84);
@ -252,13 +256,12 @@ func FxShieldStopControlQueryCatchBlow(object target, effect, object obj)
return true;
}
/* Colour by owner */
public func Entrance(object container)
{
if(container->GetOwner() != NO_OWNER) SetColor(GetPlayerColor(container->GetOwner()));
}
/*-- Production --*/
/* Shield animation */
public func IsWeapon() { return true; }
public func IsArmoryProduct() { return true; }
/*-- Display --*/
public func GetCarryMode() { return CARRY_HandBack; }
public func GetCarrySpecial(clonk) { return carry_bone; }
@ -274,20 +277,18 @@ public func GetCarryTransform(clonk, sec, back)
return nil;
}
if(back) return Trans_Mul(Trans_Mul(Trans_Rotate(90, 0, 1, 0),Trans_Rotate(180, 1, 0, 0)),Trans_Translate(0,-400,0));
if(back) return Trans_Mul(Trans_Mul(Trans_Rotate(90, 0, 1, 0),Trans_Rotate(180, 1, 0, 0)),Trans_Translate(0,-400,1000));
return Trans_Rotate(180,0,0,1);
}
public func IsWeapon() { return true; }
public func IsArmoryProduct() { return true; }
/* Definition */
func Definition(def) {
func Definition(def)
{
SetProperty("PictureTransformation",Trans_Mul(Trans_Translate(1000,-500),Trans_Rotate(20,1,1,-1),Trans_Scale(1200)),def);
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = 1;
local Collectible = true;
local Components = {Wood = 1, Metal = 1};

View File

@ -1,33 +1,61 @@
/*-- Sword --*/
/**
Sword
Standard melee weapon.
*/
#include Library_MeleeWeapon
static const Sword_Standard_StrikingLength = 15; // in frames
local movement_effect;
local magic_number;
local carry_bone;
/*-- Engine Callbacks --*/
func Initialize()
{
PlayAnimation("Base", 5, Anim_Const(0), Anim_Const(1000));
return _inherited(...);
}
func Hit()
{
Sound("Hits::Materials::Metal::LightMetalHit?");
}
public func Initialize()
func Departure(object container)
{
PlayAnimation("Base", 5, Anim_Const(0), Anim_Const(1000));
return _inherited(...);
// Always end the movement impairing effect when exiting
if (movement_effect)
{
RemoveEffect(nil, container, movement_effect);
movement_effect = nil;
}
}
public func GetCarryMode() { return CARRY_HandBack; }
public func GetCarryBone() { return "main"; }
public func GetCarrySpecial(clonk) { return carry_bone; }
public func GetCarryTransform(clonk, sec, back)
/*-- Callbacks --*/
public func OnWeaponHitCheckStop(clonk)
{
if(back) return Trans_Mul(Trans_Rotate(180,0,1,0), Trans_Rotate(-90,1,0,0), Trans_Translate(-7000,0,0));
return Trans_Rotate(-90, 1, 0, 0);
carry_bone = nil;
clonk->UpdateAttach();
if(GetEffect("SwordStrikeSpeedUp", clonk))
RemoveEffect("SwordStrikeSpeedUp", clonk);
if(clonk->IsJumping())
{
if(!GetEffect("Fall", clonk))
AddEffect("Fall",clonk,1,1,clonk);
}
if(GetEffect("SwordStrikeStop", clonk))
RemoveEffect("SwordStrikeStop", clonk);
return;
}
local magic_number;
local carry_bone;
/*-- Usage --*/
public func RejectUse(object clonk)
{
@ -139,31 +167,6 @@ func FxVisualJumpStrikeStop(target, effect, reason, temp)
effect.visual->FadeOut();
}
func OnWeaponHitCheckStop(clonk)
{
carry_bone = nil;
clonk->UpdateAttach();
if(GetEffect("SwordStrikeSpeedUp", clonk))
RemoveEffect("SwordStrikeSpeedUp", clonk);
if(clonk->IsJumping())
{
if(!GetEffect("Fall", clonk))
AddEffect("Fall",clonk,1,1,clonk);
}
if(GetEffect("SwordStrikeStop", clonk))
RemoveEffect("SwordStrikeStop", clonk);
return;
}
// called when the strike expired before end of length (aborted)
func WeaponStrikeExpired()
{
}
func SwordDamage(int shield)
{
return ((100-shield)*9*1000 / 100);
@ -325,24 +328,38 @@ func FxSwordStrikeSlowStop(pTarget, effect, iCause, iTemp)
pTarget->PopActionSpeed("Walk");
}
private func Departure(object container)
{
// Always end the movement impairing effect when exiting
if (movement_effect)
{
RemoveEffect(nil, container, movement_effect);
movement_effect = nil;
}
}
/*-- Production --*/
public func IsWeapon() { return true; }
public func IsArmoryProduct() { return true; }
/*-- Display --*/
public func GetCarryMode(object clonk, bool idle, bool nohand)
{
if (idle)
return CARRY_Sword;
return CARRY_HandBack;
}
public func GetCarrySpecial(clonk) { return carry_bone; }
public func GetCarryTransform(clonk, sec, back)
{
if (sec) return Trans_Mul(Trans_Rotate(130, 0, 0, 1), Trans_Translate(-3500, 0, 2800));
if(back) return Trans_Mul(Trans_Rotate(180,0,1,0), Trans_Rotate(-90,1,0,0), Trans_Translate(-7000,0,0));
return Trans_Rotate(-90, 1, 0, 0);
}
func Definition(def) {
SetProperty("PictureTransformation",Trans_Rotate(20, 0, 0, 1),def);
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = 1;
local Components = {Wood = 1, Metal = 1};
local Collectible = true;
local Components = {Wood = 1, Metal = 1};

View File

@ -7,8 +7,11 @@
/*
used properties:
this.inventory.last_slot: last inventory-slot that has been selected. Used for QuickSwitching
this.inventory.is_picking_up: whether currently picking up
this.inventory.quick_slot: slot that is currently selected for quick switching
this.inventory.hotkey_down: the number of a hotkey being held down
this.inventory.quick_slot_switched: true if the quick slot was switched during pressing down of a hotkey, the hotkey release will do nothing
this.inventory.slots_switched: true if two inventory were switched (pressed a hotkey while another one was pressed); the hotkey release will do nothing
other used properties of "this.inventory" might have been declared in Inventory.ocd
*/
@ -18,7 +21,8 @@ func Construction()
{
if(this.inventory == nil)
this.inventory = {};
this.inventory.last_slot = 1;
this.inventory.quick_slot = 1;
this.inventory.hotkey_down = nil;
return _inherited(...);
}
@ -29,6 +33,11 @@ public func OnShiftCursor(object new_cursor)
return _inherited(new_cursor, ...);
}
public func GetQuickSwitchSlot()
{
return this.inventory.quick_slot;
}
// Called by other libraries and objects when the Clonk has forcefully dropped (not thrown) an object.
func OnDropped(object obj)
{
@ -48,21 +57,31 @@ func RejectCollect(id objid, object obj)
public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool repeat, bool release)
{
if (!this)
if (!this)
return inherited(plr, ctrl, x, y, strength, repeat, release, ...);
// Quickswitch changes the active slot to the last selected one
if (ctrl == CON_QuickSwitch)
// Quickswitch changes the current active inventory slot
if (ctrl == CON_QuickSwitch && !release)
{
// but ignore quickswitch if we have more than 1 hand-slot
if(this.HandObjects > 1)
return inherited(plr, ctrl, x, y, strength, repeat, release, ...);;
// select last slot
SetHandItemPos(0, this.inventory.last_slot); // last_slot is updated in SetHandItemPos
// A number key (hotkey) is pressed, change quick switch slot
/*if (this.inventory.hotkey_down != nil)
{
if (SetQuickSwitchSlot(this.inventory.hotkey_down-1))
this.inventory.quick_slot_switched = true;
return true;
}*/
// Otherwise select slot
SetHandItemPos(0, this.inventory.quick_slot); // quick_slot is updated in SetHandItemPos
return true;
}
if (ctrl == CON_QuickSwitch && release) // Do nothing for now but will be used in the future
{
return true;
}
// Collection and dropping is only allowed when the Clonk is not contained.
if (!Contained())
{
@ -186,7 +205,7 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re
this->~DropInventoryItem(hot-1);
return true;
}
// inventory
hot = 0;
if (ctrl == CON_Hotkey0) hot = 10;
@ -200,14 +219,54 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re
if (ctrl == CON_Hotkey8) hot = 8;
if (ctrl == CON_Hotkey9) hot = 9;
// only the last-pressed key is taken into consideration.
// if 2 hotkeys are held, the earlier one is being treated as released
if (hot > 0 && hot <= this.MaxContentsCount)
// another hotkey is already pressed
if (this.inventory.hotkey_down != nil && hot > 0 && hot <= this.MaxContentsCount && this.inventory.hotkey_down != hot)
{
SetHandItemPos(0, hot-1);
// do nothing if this is just key down
if (!release)
return true;
// switch the two slots
this->~Switch2Items(this.inventory.hotkey_down-1, hot-1);
//this.inventory.slots_switched = true;
// This needs some explanation:
// In the event of the Clonk window ever losing focus, a hotkey might still be registered as being held down.
// If this was ever the case, the inventory would constantly switch around unless the exact same hotkey is pressed
// again to trigger a release. This could very well confuse players as it is not obvious which key needs to be
// pressed. With this, there will only be one switch and afterwards the inventory works just fine.
// The downside is that after one switch a hotkey has be pressed again for another switch.
this.inventory.hotkey_down = nil;
return true;
}
// hotkey up: perform slot selection
if (hot > 0 && hot <= this.MaxContentsCount && release)
{
// This wasn't liked by many players, so slot selection is back to key down.
// Only perform slot selection if nothing happened in the meantime
/*if (!this.inventory.quick_slot_switched)
if (!this.inventory.slots_switched)
SetHandItemPos(0, hot-1);*/
this.inventory.hotkey_down = nil;
//this.inventory.quick_slot_switched = false;
//this.inventory.slots_switched = false;
return true;
}
// a hotkey is pressed, save it for now
if (hot > 0 && hot <= this.MaxContentsCount && !release)
{
this.inventory.hotkey_down = hot;
// For safety
//this.inventory.quick_slot_switched = false;
//this.inventory.slots_switched = false;
SetHandItemPos(0, hot-1);
return true;
}
return inherited(plr, ctrl, x, y, strength, repeat, release, ...);
}
@ -420,11 +479,26 @@ public func SetHandItemPos(int hand, int inv)
// Save the current slot as the last slot only for the first hand
// and if the inventory slot actually changes.
if (hand == 0 && this->GetHandItemPos(0) != inv)
this.inventory.last_slot = this->GetHandItemPos(0);
this.inventory.quick_slot = this->GetHandItemPos(0);
return _inherited(hand, inv, ...);
}
public func SetQuickSwitchSlot(int slot)
{
// Do not set if the quick switch slot doesn't change
if (slot == this.inventory.quick_slot) return false;
// Do not set if slot is currently selected
if (slot == this->GetHandItemPos(0)) return false;
this.inventory.quick_slot = slot;
// Notify HUD
this->~OnInventoryChange();
this->~UpdateAttach();
return true;
}
/* Backpack control */
func Selected(object mnu, object mnu_item)
{

View File

@ -8,6 +8,7 @@
static const CONSTRUCTION_STICK_Left = 1;
static const CONSTRUCTION_STICK_Right = 2;
static const CONSTRUCTION_STICK_Bottom = 4;
static const CONSTRUCTION_STICK_Top = 8;
local extra_overlay, dimension_x, dimension_y, clonk, structure, direction, stick_to, blocked;
local GFX_StructureOverlay = 1;
@ -110,47 +111,118 @@ public func AdjustPreview(bool below_surface, bool look_up, bool no_call)
// x and y are refined mouse coordinates so always centered at the clonk
func Reposition(int x, int y)
{
x = BoundBy(x, -dimension_x/2, dimension_x/2);
y = BoundBy(y, -dimension_y/2, dimension_y/2);
var clonk_width = clonk->GetObjWidth();
var clonk_height = clonk->GetObjHeight();
x = BoundBy(x, -dimension_x - clonk_width/2, dimension_x + clonk_width/2);
y = BoundBy(y, -dimension_y - clonk_height/2, dimension_y + clonk_height/2);
// Try to combine the structure with other structures.
var found = false;
if (structure->~ConstructionCombineWith())
{
var stick_dir = structure->~ConstructionCombineDirection();
var find_rect = Find_InRect(AbsX(clonk->GetX() + x - dimension_x/2 - 10), AbsY(clonk->GetY() + y - dimension_y/2 - 10), dimension_x + 20, dimension_y + 20);
if ((stick_dir & CONSTRUCTION_STICK_Bottom))
find_rect = Find_AtPoint(AbsX(clonk->GetX() + x), AbsY(clonk->GetY() + y));
var other = FindObject(Find_Func(structure->ConstructionCombineWith(), this),
find_rect,
Find_OCF(OCF_Fullcon),
Find_Layer(clonk->GetObjectLayer()),
Find_Allied(clonk->GetOwner()),
Find_NoContainer());
if (other)
// There is no use in doing all the other checks if no sticking direction is defined at all
// That's just wrong use of ConstructionCombineWith
if (structure->~ConstructionCombineDirection())
{
x = other->GetX();
y = other->GetY();
// Combine to different directions.
if ((stick_dir & CONSTRUCTION_STICK_Left) && other->GetX() >= GetX())
x = other->GetX() - other->GetObjWidth()/2 - dimension_x / 2;
if ((stick_dir & CONSTRUCTION_STICK_Right) && other->GetX() < GetX())
x = other->GetX() + other->GetObjWidth()/2 + dimension_x / 2;
if ((stick_dir & CONSTRUCTION_STICK_Bottom))
y = other->GetY() + other->GetObjHeight()/2 + dimension_y / 2;
// Add an additional offset if needed, for example a basement can be place
// only under a part of the structure.
var stick_offset = structure->~ConstructionCombineOffset(other);
if (stick_offset)
//var find_rect = Find_InRect(AbsX(clonk->GetX() + x - dimension_x/2 - 10), AbsY(clonk->GetY() + y - dimension_y/2 - 10), dimension_x + 20, dimension_y + 20);
//if ((stick_dir & CONSTRUCTION_STICK_Bottom))
var find_rect = Find_AtPoint(clonk->GetX() - GetX() + x, clonk->GetY() - GetY() + y);
var other = FindObject(Find_Func(structure->ConstructionCombineWith(), this),
find_rect,
Find_OCF(OCF_Fullcon),
Find_Layer(clonk->GetObjectLayer()),
Find_Allied(clonk->GetOwner()),
Find_NoContainer());
if (other)
{
x += stick_offset[0];
y += stick_offset[1];
var stick_dir = structure->ConstructionCombineDirection(other);
var other_width = other->GetObjWidth();
var other_height = other->GetObjHeight();
// Determine the position from the other object's center currently hovered
var other_offset_x = clonk->GetX() + x - other->GetX();
var other_offset_y = clonk->GetY() + y - other->GetY();
// The tricky part is now to determine which of the four possible directions should be used
// The shape of the 'other' is divided like this (* is center):
// __________________________
// | | Top | |
// | Left |----*----| Right |
// |_______|_Bottom__|_______|
//
// Whichever part is howered on is checked first for stick direction
// Hopefully, in the end this contains a single sticking direction.
var single_stick_to = 0;
// Left
if (other_offset_x < other_width / -6)
{
single_stick_to = GetStickingDirection(stick_dir, CONSTRUCTION_STICK_Left, CONSTRUCTION_STICK_Bottom, CONSTRUCTION_STICK_Top, CONSTRUCTION_STICK_Right, other_offset_y, 0);
}
// Right
else if (other_offset_x > other_width / 6)
{
single_stick_to = GetStickingDirection(stick_dir, CONSTRUCTION_STICK_Right, CONSTRUCTION_STICK_Bottom, CONSTRUCTION_STICK_Top, CONSTRUCTION_STICK_Left, other_offset_y, 0);
}
// Bottom
else if (other_offset_y >= 0)
{
single_stick_to = GetStickingDirection(stick_dir, CONSTRUCTION_STICK_Bottom, CONSTRUCTION_STICK_Right, CONSTRUCTION_STICK_Left, CONSTRUCTION_STICK_Top, other_offset_x, 0);
}
// Top
else if (other_offset_y < 0)
{
single_stick_to = GetStickingDirection(stick_dir, CONSTRUCTION_STICK_Top, CONSTRUCTION_STICK_Right, CONSTRUCTION_STICK_Left, CONSTRUCTION_STICK_Bottom, other_offset_x, 0);
}
// If no direction is found, something went wrong.
// Probably ConstructionCombineDirection() returned garbage.
if (single_stick_to)
{
if (single_stick_to == CONSTRUCTION_STICK_Left)
{
x = other->GetX() - other_width/2 - dimension_x/2;
y = other->GetY();
}
if (single_stick_to == CONSTRUCTION_STICK_Right)
{
x = other->GetX() + other_width/2 + dimension_x/2;
y = other->GetY();
}
if (single_stick_to == CONSTRUCTION_STICK_Bottom)
{
x = other->GetX();
y = other->GetY() + other_height/2 + dimension_y/2;
}
if (single_stick_to == CONSTRUCTION_STICK_Top)
{
x = other->GetX();
y = other->GetY() - other_height/2 - dimension_y/2;
}
// Add an additional offset if needed, for example a basement can be place
// only under a part of the structure.
var stick_offset = structure->~ConstructionCombineOffset(other, single_stick_to);
if (stick_offset)
{
x += stick_offset[0];
y += stick_offset[1];
}
// Save the other building for use in AdjustPreview and for color changing
stick_to = other;
// Found another building and a way to stick to it!
found = true;
}
}
stick_to = other;
found = true;
}
}
if (!found)
{
// Narrow the distance a construction site can be built around the clonk
x = BoundBy(x, -dimension_x/2 - clonk_width/2, dimension_x/2 + clonk_width/2);
y = BoundBy(y, -dimension_y/2 - clonk_height/2, dimension_y/2 + clonk_height/2);
x = clonk->GetX() + x;
y = clonk->GetY() + y;
}
@ -163,11 +235,14 @@ func Reposition(int x, int y)
else if (stick_to)
{
SetGraphics(nil, ConstructionPreviewer_IconCombine, GFX_CombineIconOverlay, GFXOV_MODE_Base);
var dir = 1;
if (stick_to->GetX() < GetX()) dir = -1;
if (structure->~CombineToBottom())
dir = 0;
SetObjDrawTransform(1000, 0, dimension_x/2 * 1000 * dir, 0, 1000, 0, GFX_CombineIconOverlay);
var x_dir = 1, y_dir = 1;
if (stick_to->GetX() < GetX()) x_dir = -1;
if (stick_to->GetY() < GetY()) y_dir = -1;
if (single_stick_to == CONSTRUCTION_STICK_Bottom || single_stick_to == CONSTRUCTION_STICK_Top)
x_dir = 0;
if (single_stick_to == CONSTRUCTION_STICK_Left || single_stick_to == CONSTRUCTION_STICK_Right)
y_dir = 0;
SetObjDrawTransform(1000, 0, dimension_x/2 * 1000 * x_dir, 0, 1000, dimension_y/2 * 1000 * y_dir, GFX_CombineIconOverlay);
}
// Update the extra overlay possibly added to the preview.
extra_overlay = structure->~ConstructionPreview(this, GFX_PreviewerPictureOverlay, direction);
@ -177,6 +252,47 @@ func Reposition(int x, int y)
AdjustPreview(structure->~IsBelowSurfaceConstruction());
}
// Helper function to return a definite sticking direction.
// Used whenever the cursor hovers the 'left' or 'right' part of the other building.
// See Reposition() to see an example of the four parts.
func GetStickingDirection(int stick_dir, int primary_dir, int secondary_dir, int tertiary_dir, int fourth_dir, int cursor_coord, int other_coord)
{
// If the primary direction is in stick_dir, we're done
if (stick_dir & primary_dir)
{
return primary_dir;
}
// Afterwards check second / third directions
else if (stick_dir & secondary_dir || stick_dir & tertiary_dir)
{
// If one of those isn't in stick_dir, no coordinate checking is necessary
if (!(stick_dir & tertiary_dir))
{
return secondary_dir;
}
else if (!(stick_dir & secondary_dir))
{
return tertiary_dir;
}
else
{
// Coordinates have to be checked
// secondary always is one pixel better than tertiary
if (cursor_coord >= other_coord)
return secondary_dir;
else
return tertiary_dir;
}
}
// Fourth direction is returned last but no other directions takes the point
else if (stick_dir & fourth_dir)
{
return fourth_dir;
}
// If this happens, something is wrong
return 0;
}
// Flips the preview horizontally
func Flip()
{
@ -196,4 +312,6 @@ func Flip()
}
// UI not saved.
func SaveScenarioObject() { return false; }
func SaveScenarioObject() { return false; }
local Plane = 210;

View File

@ -70,21 +70,45 @@ public func GetItemCount()
return count;
}
// This function was useful back when the clonk had two usable hand items.
// Feel free to uncomment whenever this obsolete control style is reinvented.
/** Get the 'i'th item in hands.
These are the items that will be used with use-commands. (Left mouse click, etc...) */
public func GetHandItem(int i)
/*public func GetHandItem(int i)
{
// i is valid range
if (i >= GetLength(this.inventory.hand_objects))
return nil;
if (i < 0) return nil;
if (i < 0) return nil;
return GetItem(this.inventory.hand_objects[i]);
}*/
// 0: returns currently selected inventory item
// 1: returns item in quick slot
public func GetHandItem(int i)
{
// Range exceeded
if (i < 0 || i >= 2) return nil;
if (i == 0)
return GetItem(this.inventory.hand_objects[0]);
if (i == 1)
{
var slot = this->~GetQuickSwitchSlot();
if (slot < 0 || slot >= this.MaxContentsCount) return nil;
// Don't show the same item twice
if (slot == this.inventory.hand_objects[0]) return nil;
return GetItem(slot);
}
// no more than 2 hands
return nil;
}
/** Set the 'hand'th use-item to the 'inv'th slot */
public func SetHandItemPos(int hand, int inv)
{
// indices are in range?
// indices are in range?
if(hand >= HandObjects || inv >= MaxContentsCount)
return nil;
if(hand < 0 || inv < 0) return nil;
@ -258,6 +282,7 @@ public func Switch2Items(int one, int two)
}
this->~OnInventoryChange(one, two);
this->~UpdateAttach();
}

View File

@ -208,7 +208,7 @@ public func FxIntUpgradeProductProgressBarOnMenuOpened(object target, effect fx,
public func FxIntUpgradeProductProgressBarTimer(object target, effect fx, int time)
{
if (fx.menu_target == nil) return FX_OK;
if (fx.menu_target == nil) return -1;
// Find (new?) production effect if not already given.
if (fx.production_effect == nil)
{

View File

@ -2,7 +2,7 @@
Basement
Provides basements to structures, but can also be built as a single object.
@author Maikel
@author: Maikel
*/
#include Library_Structure
@ -10,16 +10,14 @@
local parent;
local width;
protected func Construction()
func Construction()
{
// Make sure the basement does not move while constructing.
SetCategory(C4D_StaticBack);
return _inherited(...);
}
public func IsHammerBuildable() { return true; }
protected func Initialize()
func Initialize()
{
var wdt = GetObjWidth();
if (parent)
@ -34,7 +32,7 @@ protected func Initialize()
return _inherited(...);
}
protected func Destruction()
func Destruction()
{
// Cast a single rock.
CastObjects(Rock, 1, 15, 0, -5);
@ -53,13 +51,6 @@ public func SetWidth(int wdt)
public func GetWidth() { return width; }
// Set the parent if the basement is attached to a structure.
public func CombineWith(object stick_to)
{
SetParent(stick_to);
return;
}
public func SetParent(object to_parent)
{
parent = to_parent;
@ -74,12 +65,48 @@ public func SetParent(object to_parent)
public func GetParent() { return parent; }
/*-- Saving --*/
public func SaveScenarioObject(proplist props)
{
if (!inherited(props, ...))
return false;
if (parent)
props->AddCall("BasementParent", this, "SetParent", parent);
else if (width != GetObjWidth())
props->AddCall("BasementWidth", this, "SetWidth", width);
props->Remove("Category");
return true;
}
/*-- Construction --*/
public func IsHammerBuildable() { return true; }
// It should not be a structure.
public func IsStructure() { return false; }
// But a basement!
public func IsBasement() { return true; }
// Is a construction that is built just below the surface.
public func IsBelowSurfaceConstruction() { return true; }
// Sticking to other structures, at the bottom of that structure.
// This makes it possible to combine basements with each other.
public func IsStructureWithoutBasement() { return true; }
// Sticking to other structures.
public func ConstructionCombineWith() { return "IsStructureWithoutBasement"; }
public func ConstructionCombineDirection() { return CONSTRUCTION_STICK_Bottom; }
public func ConstructionCombineDirection(object other)
{
// All directions are possible for other basements
if (other && other->~IsBasement())
return CONSTRUCTION_STICK_Left | CONSTRUCTION_STICK_Right | CONSTRUCTION_STICK_Bottom | CONSTRUCTION_STICK_Top;
// For everything else, the basement is below.
return CONSTRUCTION_STICK_Bottom;
}
public func ConstructionCombineOffset(object other)
{
// Some structures like the elevator require the basement to have an offset.
@ -90,9 +117,10 @@ public func NoConstructionFlip() { return true; }
public func AlternativeConstructionPreview(object previewer, int direction, object combine_with)
{
if (combine_with && combine_with->~IsBasement()) return;
var wdt = GetSiteWidth(direction, combine_with);
previewer->SetObjDrawTransform(1000 * wdt / 40, 0, 0, 0, 1000, 0, previewer.GFX_StructureOverlay);
return;
}
public func GetSiteWidth(int direction, object combine_with)
@ -109,6 +137,8 @@ public func GetSiteWidth(int direction, object combine_with)
public func SetConstructionSiteOverlay(object site, int direction, object combine_with)
{
if (combine_with && combine_with->~IsBasement()) return;
var wdt = GetSiteWidth(direction, combine_with);
site->SetGraphics(nil, Basement, 1, GFXOV_MODE_Base);
site->SetClrModulation(RGBa(255, 255, 255, 128), 1);
@ -116,26 +146,15 @@ public func SetConstructionSiteOverlay(object site, int direction, object combin
return true;
}
// Don't stick to itself, so it should not be a structure.
public func IsStructure() { return false; }
/*-- Saving --*/
public func SaveScenarioObject(proplist props)
// Set the parent if the basement is attached to a structure.
public func CombineWith(object stick_to)
{
if (!inherited(props, ...))
return false;
if (parent)
props->AddCall("BasementParent", this, "SetParent", parent);
else if (width != GetObjWidth())
props->AddCall("BasementWidth", this, "SetWidth", width);
props->Remove("Category");
return true;
if (stick_to && stick_to->~IsBasement()) return;
SetParent(stick_to);
}
/*-- Proplist --*/
/*-- Properties --*/
local Name = "$Name$";
local Description ="$Description$";

View File

@ -19,6 +19,16 @@ public func RefuseTransfer(object toMove) { return true; } // TODO: this is not
// disallow site cancellation. Useful e.g. for sites that are pre-placed for a game goal
public func MakeUncancellable() { no_cancel = true; return true; }
/*-- Testing / Development --*/
// Builds the construction even if the required materials isn't there.
// Use for debugging purposes (or maybe cool scenario effects)
public func ForceConstruct()
{
full_material = true;
StartConstructing();
}
/*-- Interaction --*/
public func HasInteractionMenu() { return true; }

View File

@ -227,11 +227,19 @@ public func ConstructionPreview(object previewer, int overlay, int dir)
}
// Sticking to other elevators
public func ConstructionCombineWith() { return "IsElevator"; }
public func ConstructionCombineDirection() { return CONSTRUCTION_STICK_Left | CONSTRUCTION_STICK_Right; }
public func ConstructionCombineWith() { return "CanCombineElevator"; }
public func ConstructionCombineDirection(object other)
{
if (!other) return CONSTRUCTION_STICK_Left | CONSTRUCTION_STICK_Right;
// Only combine when facing correctly
if (other->GetDir() == DIR_Left)
return CONSTRUCTION_STICK_Right;
return CONSTRUCTION_STICK_Left;
}
// Called to determine if sticking is possible
public func IsElevator(object previewer)
public func CanCombineElevator(object previewer)
{
if (!previewer) return true;

View File

@ -32,6 +32,8 @@ public func NoConstructionFlip() { return true; }
// Is a construction that is built just below the surface.
public func IsBelowSurfaceConstruction() { return true; }
public func IsHammerBuildable() { return true; }
public func ConstructionCombineWith()
{
return "ConnectWoodenBridge";

View File

@ -51,6 +51,20 @@ protected func ControlUse(object clonk)
// Nutritional value depends on the completion of the mushroom.
public func NutritionalValue() { return GetCon() / 10; }
/*-- Display --*/
public func GetCarryMode()
{
return CARRY_Hand;
}
public func GetCarryTransform()
{
return Trans_Scale(750);
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = true;

View File

@ -144,6 +144,8 @@
Identifier=QuickSwitch
GUIName=$CON_QuickSwitch$
GUIDesc=$CON_QuickSwitch_Desc$
Hold=1
SendCursorPos=1
[ControlDef]
Identifier=InventoryShiftForward
@ -198,42 +200,52 @@
[ControlDef]
Identifier=Hotkey1
GUIName=$CON_Hotkey1$
Hold=1
[ControlDef]
Identifier=Hotkey2
GUIName=$CON_Hotkey2$
Hold=1
[ControlDef]
Identifier=Hotkey3
GUIName=$CON_Hotkey3$
Hold=1
[ControlDef]
Identifier=Hotkey4
GUIName=$CON_Hotkey4$
Hold=1
[ControlDef]
Identifier=Hotkey5
GUIName=$CON_Hotkey5$
Hold=1
[ControlDef]
Identifier=Hotkey6
GUIName=$CON_Hotkey6$
Hold=1
[ControlDef]
Identifier=Hotkey7
GUIName=$CON_Hotkey7$
Hold=1
[ControlDef]
Identifier=Hotkey8
GUIName=$CON_Hotkey8$
Hold=1
[ControlDef]
Identifier=Hotkey9
GUIName=$CON_Hotkey9$
Hold=1
[ControlDef]
Identifier=Hotkey0
GUIName=$CON_Hotkey0$
Hold=1
[ControlDef]
Identifier=DropHotkey1
@ -410,7 +422,6 @@
[ControlDef]
Identifier=PlayerHotkey0
# Menu control
[ControlDef]
@ -573,9 +584,9 @@
# Down S
#
# Hotkey0-9 (0-9)
# InteractionHotkey0-0 Shift+(0-9)
# DropHotkey0-9 Shift+(0-9)
#
# Use Left mouse button
# Use Left mouse button
# Drop S+Left mouse button
# Throw Right mouse button
# UseAlt Right mouse button (low priority)
@ -583,8 +594,8 @@
# Interact Space
#
# QuickSwitch Q
# InventoryShiftForward MouseWheelUp
# InventoryShiftBackward MouseWheelDown
# InventoryShiftForward MouseWheelUp
# InventoryShiftBackward MouseWheelDown
# Contents E
#
# NextCrew T

View File

@ -59,6 +59,14 @@ protected func InitializePlayer(int plr)
while (crew = GetCrew(plr, index))
{
crew->SetPosition(96 + RandomX(-12, 12), LandscapeHeight() - 92);
var u = 0;
while(crew->Stuck())
{
crew->SetPosition(crew->GetX(), crew->GetY()-1);
++u;
if (u > 50) // This is bad, the clonk will most likely die
break;
}
// First clonk can construct, others can chop.
if (index == 0)

View File

@ -44,7 +44,6 @@ don't need to include this file or any of the files it includes. */
#include <cctype>
#include <cerrno>
#include <climits>
#include <cmath>
#include <cstdarg>
#include <cstddef>
@ -56,6 +55,7 @@ don't need to include this file or any of the files it includes. */
#include <list>
#include <map>
#include <memory>
#include <regex>
#include <set>
#include <sstream>
#include <stdexcept>
@ -63,26 +63,6 @@ don't need to include this file or any of the files it includes. */
#include <utility>
#include <vector>
#include <regex>
namespace re = std;
// debug memory management - must come after standard headers,
// because those libraries use placement new
#ifndef NODEBUGMEM
#if defined(_DEBUG) && defined(_MSC_VER)
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
inline void *operator new(size_t s, const char *szFile, long iLine)
{ return ::operator new(s, _NORMAL_BLOCK, szFile, iLine); }
inline void operator delete(void *p, const char *, long)
{ ::operator delete(p); }
#define new_orig new
#define new new(__FILE__, __LINE__)
#endif
#endif
#include <new>
#include "lib/Standard.h"
#include "C4Prototypes.h"
#include "lib/C4Real.h"

View File

@ -257,7 +257,7 @@ namespace
// the beginning or end of a line, respectively, and it seems
// like in some implementations they only match the beginning
// or end of the whole string. See also #1127.
static re::regex line_pattern("(?:\n|^)([^=]+)=(.*?)\r?(?=\n|$)", static_cast<re::regex::flag_type>(re::regex_constants::optimize | re::regex_constants::ECMAScript));
static std::regex line_pattern("(?:\n|^)([^=]+)=(.*?)\r?(?=\n|$)", static_cast<std::regex::flag_type>(std::regex_constants::optimize | std::regex_constants::ECMAScript));
assert(stringtbl);
if (!stringtbl)
@ -269,7 +269,7 @@ namespace
const char *begin = stringtbl;
const char *end = begin + std::char_traits<char>::length(begin);
for (auto it = re::cregex_iterator(begin, end, line_pattern); it != re::cregex_iterator(); ++it)
for (auto it = std::cregex_iterator(begin, end, line_pattern); it != std::cregex_iterator(); ++it)
{
assert(it->size() == 3);
if (it->size() != 3)

View File

@ -18,10 +18,7 @@
#include "platform/StdScheduler.h"
#pragma push_macro("new")
#undef new
#include <pcg/pcg_random.hpp>
#pragma pop_macro("new")
#ifndef INC_C4Particles
#define INC_C4Particles

View File

@ -218,7 +218,7 @@ bool C4TextureMap::LoadFlags(C4Group &hGroup, const char *szEntryName, bool *pOv
int32_t C4TextureMap::LoadMap(C4Group &hGroup, const char *szEntryName, bool *pOverloadMaterials, bool *pOverloadTextures)
{
static re::regex line_terminator("\r?\n", static_cast<re::regex::flag_type>(re::regex_constants::optimize | re::regex_constants::ECMAScript));
static std::regex line_terminator("\r?\n", static_cast<std::regex::flag_type>(std::regex_constants::optimize | std::regex_constants::ECMAScript));
char *bpMap;
size_t map_size;
@ -230,7 +230,7 @@ int32_t C4TextureMap::LoadMap(C4Group &hGroup, const char *szEntryName, bool *pO
char *end = begin + map_size;
size_t line = 1; // Counter for error messages
for (auto it = re::cregex_token_iterator(begin, end, line_terminator, -1); it != re::cregex_token_iterator(); ++it, ++line)
for (auto it = std::cregex_token_iterator(begin, end, line_terminator, -1); it != std::cregex_token_iterator(); ++it, ++line)
{
if (it->compare("OverloadMaterials") == 0)
{

View File

@ -23,10 +23,7 @@
#include <random>
#pragma push_macro("new")
#undef new
#include <pcg/pcg_random.hpp>
#pragma pop_macro("new")
int RandomCount = 0;

View File

@ -21,8 +21,6 @@
#define INC_STANDARD
#include <type_traits>
#pragma push_macro("new")
#undef new
// The Clear/Default functions that exist on most OpenClonk classes are A
// BAD IDEA because the caller has no guarantee that every member has been
@ -39,7 +37,6 @@ inline InplaceReconstruct(T *obj)
obj->~T();
new (obj) T();
}
#pragma pop_macro("new")
#include "platform/PlatformAbstraction.h"