Post your code!

User avatar
Stix
Member
Posts: 1385
Joined: Fri Aug 04, 2017 14:19
IRC: nil
In-game: Stix [+alts]
Location: USA

Post your code!

by Stix » Post

a place to post code!
Last edited by Stix on Wed Jul 18, 2018 22:26, edited 1 time in total.
Hey, what can i say? I'm the bad guy.

User avatar
Stix
Member
Posts: 1385
Joined: Fri Aug 04, 2017 14:19
IRC: nil
In-game: Stix [+alts]
Location: USA

Re: post your code!

by Stix » Post

heres my code, its not much as i was going through rubenwardy's modding book and just changed some examples, but here you go!

Code: Select all

minetest.register_craftitem("better_bread:doublebaked_bread", {
descrition = "doublebaked_bread",
inventory_image = "better_bread_doublebaked_bread.png",
on_use = minetest.item_eat(10)
})
minetest.register_craft({
type = "cooking",
output = "better_bread:doublebaked_bread"
recipie = "farming:bread",
})
Hey, what can i say? I'm the bad guy.

User avatar
sorcerykid
Member
Posts: 1841
Joined: Fri Aug 26, 2016 15:36
GitHub: sorcerykid
In-game: Nemo
Location: Illinois, USA

Re: post your code!

by sorcerykid » Post

minetest.count_nodes_in_area( pos_min, pos_max, names, is_group )
Returns the number of nodes within the given map region by either node name or group name, if is_group is true. The map block(s) containing the region are emerged as well.

Code: Select all

minetest.count_nodes_in_area = function( pos_min, pos_max, names, is_group )
        local counts, node_counts
        local voxel_manip = minetest.get_voxel_manip( )

        voxel_manip:read_from_map( pos_min, pos_max )
        node_counts = select( 2, minetest.find_nodes_in_area( pos_min, pos_max, names ) )

        if is_group == false then
                return counts
        end

        counts = { }    -- use new table for transposing node counts into group counts
        for _, name in ipairs( names ) do
                local group_name = string.match( name, "group:(.+)" )
                if group_name then
                        counts[ name ] = 0
                        for node_name, node_count in pairs( node_counts ) do
                                if minetest.registered_nodes[ node_name ].groups[ group_name ] then
                                        counts[ name ] = counts[ name ] + node_count
                                end
                        end
                else
                        counts[ name ] = node_counts[ name ]
                end
        end
        return counts
end

User avatar
maikerumine
Member
Posts: 1420
Joined: Mon Aug 04, 2014 14:27
GitHub: maikerumine
In-game: maikerumine

Re: post your code!

by maikerumine » Post

This lil' fella:
Image

Code: Select all

minetest.register_craft({
	output = 'default:mold_sword_head',
	replacements = {{"bucket:bucket_metal_nuggets", "bucket:bucket_empty 3"}},
	recipe = {
		{'group:sand', 'group:sand', 'bucket:bucket_metal_nuggets'},
		{'group:sand', 'bucket:bucket_metal_nuggets', 'group:sand'},
		{'bucket:bucket_metal_nuggets', 'default:mold_frame', 'group:sand'},
	}
})

minetest.register_craft({
	type = 'cooking',
	recipe = 'default:mold_sword_head',
	output = 'default:redhot_mold_sword_head',
	cooktime = 135,
})

minetest.register_abm({
	nodenames = {"default:redhot_mold_sword_head","default:wrought_mold_sword_head"},
	interval = 12.0,
	chance = 1,
	action = function(pos, node, active_object_count, active_object_count_wider)
		local meta = minetest.get_meta(pos)
			meta:set_string("infotext","Mold is cool: 350 Degrees")
			hacky_swap_node(pos,"default:wrought_mold_sword_head")

			return
		--end
	end,
})

minetest.register_craft({
	output = 'default:hardened_steel_sword_head',
		replacements = {{"bucket:bucket_water", "bucket:bucket_empty"}},
	recipe = {
		{'', 'bucket:bucket_water', ''},
		{'', 'default:tool_sword_redhot_iron', ''},
		{'', '', ''},
	}
})

minetest.register_craft({
	output = 'default:tool_sword_hardened_steel',
	recipe = {
		{'', 'default:hardened_steel_sword_head', ''},
		{'default:glue', '', 'default:glue'},
		{'default:cord', 'default:handle_short','default:cord'},
	}
})
Became this:
Image
Attachments
default_tool_hardened_steelsword.png
default_tool_hardened_steelsword.png (169 Bytes) Viewed 6335 times
default_mold_sword.png
default_mold_sword.png (696 Bytes) Viewed 6335 times
Talamh Survival Minetest-->viewtopic.php?f=10&t=12959

User avatar
azekill_DIABLO
Member
Posts: 7507
Joined: Wed Oct 29, 2014 20:05
GitHub: azekillDIABLO
In-game: azekill_DIABLO
Location: OMICRON
Contact:

Re: post your code!

by azekill_DIABLO » Post

Code: Select all

--set the /mila_count command

minetest.register_chatcommand("mila_count", {
	params = "",
	privs = {interact=true},
	description = "Counts the number of M.I.L.A entities!",
	func = function(name, player)
		minetest.debug("M.I.L.A " ..mila.version..": There are " ..ent_num.. " M.I.L.A entities!")
		minetest.chat_send_all("M.I.L.A " ..mila.version..": There are " ..ent_num.. " M.I.L.A entities!")
	end,
})
Sneaky peak of mila next functions.
Gone, but not dead. Contact me on discord: azekill_DIABLO#6565
DMs are always open if you want to get in touch!

User avatar
sorcerykid
Member
Posts: 1841
Joined: Fri Aug 26, 2016 15:36
GitHub: sorcerykid
In-game: Nemo
Location: Illinois, USA

Re: post your code!

by sorcerykid » Post

minetest.drop_item( pos, item, horz, vert )
Spawn item with a vertical velocity, vert, and a random horizontal velocity ranging between 0 and horz from the position, pos. The item may be specified as either an itemstring or an ItemStack object.

Code: Select all

minetest.drop_item = function( pos, item, horz, vert )
        -- confirm itemstring or a non-empty itemstack
        if not item.is_empty or not item:is_empty( ) then
                ( minetest.add_item( pos, item ) ):setvelocity(
                        { x = math.random( -horz, horz ), y = vert, z = math.random( -horz, horz ) }
                )
        end
end
Unlike minetest.item_drop( ), this function is suitable for incidental drops that are independent of the player, such as tnt explosions or mob drops. An example would be:

Code: Select all

-- the mob should drop items with drop.chance probability in quantities between drop.min and drop.max
for _, drop in ipairs( self.drops ) do
        if math.random( 1, drop.chance ) == 1 then
                minetest.drop_item( pos, drop.name .. " " .. math.random( drop.min, drop.max ), 1, 5 )
        end
end

User avatar
azekill_DIABLO
Member
Posts: 7507
Joined: Wed Oct 29, 2014 20:05
GitHub: azekillDIABLO
In-game: azekill_DIABLO
Location: OMICRON
Contact:

Re: post your code!

by azekill_DIABLO » Post

cool! might find an use in mila.
Gone, but not dead. Contact me on discord: azekill_DIABLO#6565
DMs are always open if you want to get in touch!

User avatar
sorcerykid
Member
Posts: 1841
Joined: Fri Aug 26, 2016 15:36
GitHub: sorcerykid
In-game: Nemo
Location: Illinois, USA

Re: post your code!

by sorcerykid » Post

This is the awk script I use to export the daily chat history on my server. It expects a debug.txt file as input and the following three variables to be defined:
  • days, specifies a 24-hour offset from the current day (based on the local timezone)
  • addr, specifies the IP address or hostname of the server
  • port, specifies the port of the server.
A value of zero or greater is required for days, with the current day being zero. The timestamps for each message are automatically converted to UTC.

Code: Select all

#!/bin/awk -f
#
# Example Usage:
# ./stat.awk -v addr=jt2.intraversal.net -v port=30002 -v days=1 /home/minetest/.minetest/debug.txt > stat.txt

function get_timestamp( time_str ) {
        return mktime( sprintf( "%d %d %d %d %d %d", \
                substr( date_str, 1, 4 ), substr( date_str, 6, 2 ), substr( date_str, 9, 2 ), \
                substr( time_str, 1, 2 ), substr( time_str, 4, 2 ), substr( time_str, 7, 2 ) ) );
}

BEGIN {
        # calculate the relative date from the specified 24-hour offset
        rel_time = ( int( systime( ) / 86400 ) - days ) * 86400;

        # convert the relative date to a string for quicker comparisons
        date_str = strftime( "%Y-%m-%d", rel_time );

        print "Chat history for " addr ":" port " (" strftime( "%d-%b-%Y %Z", rel_time ) ")";
}
{
        if( $1 == date_str && $4 == "CHAT:" ) {
                # print the chat message and timestamp converted to UTC
                print "[" strftime( "%H:%M:%S", get_timestamp( $2 ), 1 ) " UTC]", substr( $0, 44 );
        }
}

User avatar
sorcerykid
Member
Posts: 1841
Joined: Fri Aug 26, 2016 15:36
GitHub: sorcerykid
In-game: Nemo
Location: Illinois, USA

Re: post your code!

by sorcerykid » Post

Below is a solution for the longstanding inability to right-click interactive nodes such as itemframes, doors, and chests while wielding craftitems or nodes that define their own placement handlers. Previously, the workaround was to add a short-circuit within the on_place( ) callback of protection blocks, carts, boats, wheat seeds, cotton seeds, etc, but that was needlessly redundant. By overriding the registration functions themselves, such logic can be consolidated. The precedence is guaranteed and thus consistent from a player perspective.

viewtopic.php?p=285258#p285258

Code: Select all

local old_register_node = minetest.register_node
local old_register_craftitem = minetest.register_craftitem

minetest.register_craftitem = function ( name, fields )
   if fields.on_place then
      fields._on_place = fields.on_place
      fields.on_place = function( itemstack, player, pointed_thing )
         local pos = pointed_thing.under
         local node = minetest.get_node( pos )

         -- allow on_rightclick callback of pointed_thing to intercept item placement
         if minetest.registered_nodes[ node.name ].on_rightclick then
            minetest.registered_nodes[ node.name ].on_rightclick( pos, node, player, itemstack )
         -- otherwise placement is dependent on anti-grief rules of this item (if hook is defined)
         elseif not fields.allow_place or fields.allow_place( pos, player ) then
            return fields._on_place( itemstack, player, pointed_thing )
         end
         return itemstack
      end
   end
   old_register_craftitem( name, fields )
end

minetest.register_node = function ( name, fields )
   if fields.on_place and fields.on_place ~= minetest.rotate_node then
      fields._on_place = fields.on_place
      fields.on_place = function( itemstack, player, pointed_thing )
         local pos = pointed_thing.under
         local node = minetest.get_node( pos )

         -- allow on_rightclick callback of pointed_thing to intercept item placement
         if minetest.registered_nodes[ node.name ].on_rightclick then
            minetest.registered_nodes[ node.name ].on_rightclick( pos, node, player, itemstack )
         -- otherwise placement is dependent on anti-grief rules of this item (if hook is defined)
         elseif not fields.allow_place or fields.allow_place( pos, player ) then
            return fields._on_place( itemstack, player, pointed_thing )
         end
         return itemstack
      end
   end
   if fields.on_punch then
      fields._on_punch = fields.on_punch
      fields.on_punch = function( pos, node, player )
         -- punching is dependent on anti-grief rules of this item (currently only used by tnt)
         if not fields.allow_punch or fields.allow_punch( pos, player ) then
            fields._on_punch( pos, node, player )
         end
      end
   end
   old_register_node( name, fields )
end
Optional anti-grief hooks can also be defined to prevent items being placed or punched under certain conditions.
  • The anti-grief hook for craftitems and nodes is provided two arguments and must return a boolean:
    allow_place( pos, player )

    The anti-grief hook for nodes is provided two arguments and must return a boolean:
    allow_punch( pos, player )
For example, if I want to restrict the placement or ignition of explosives above -250, I could override the node registration of tnt:tnt:

Code: Select all

local TNT_PLACE_DEPTH = -250

local function allow_place_explosive( node_pos, player )
        if node_pos.y > TNT_PLACE_DEPTH and not minetest.check_player_privs( player, "tnt" ) then
                minetest.chat_send_player( player:get_player_name( ), "You are not allowed to place explosives above " .. TNT_PLACE_DEPTH .. "!" )
                minetest.log( "action", player:get_player_name( ) .. " tried to place tnt:tnt above " .. TNT_PLACE_DEPTH )
                return false
        end
        return true
end

local function allow_punch_explosive( node_pos, player )
        if node_pos.y > TNT_PLACE_DEPTH and player:get_wielded_item( ):get_name( ) == "default:torch" and not minetest.check_player_privs( player, "tnt" 

) then
                minetest.chat_send_player( player:get_player_name( ), "You are not allowed to ignite explosives above " .. TNT_PLACE_DEPTH .. "!" )
                minetest.log( "action", player:get_player_name( ) .. " tried to ignite tnt:tnt above " .. TNT_PLACE_DEPTH )
                player:set_hp( 0 )
                return false
        end
        return true
end

minetest.override_item( "tnt:tnt", {
        allow_place = allow_place_explosive,
        allow_punch = allow_punch_explosive
} )

Now TNT can no longer be placed above -250m except with the "tnt" privilege. Hoewver, it is possible to open doors and chests while wielding TNT and even to "place" TNT within an itemframe.
Last edited by sorcerykid on Fri Nov 10, 2017 00:51, edited 1 time in total.

User avatar
Lone_Wolf
Member
Posts: 2576
Joined: Sun Apr 09, 2017 05:50
GitHub: LoneWolfHT
IRC: LandarVargan
In-game: LandarVargan

Re: post your code!

by Lone_Wolf » Post

What code would I use to prevent players running commands if they are within a certain amount of nodes away from a certain block?
My ContentDB -|- Working on CaptureTheFlag -|- Minetest Forums Dark Theme!! (You need it)

User avatar
sorcerykid
Member
Posts: 1841
Joined: Fri Aug 26, 2016 15:36
GitHub: sorcerykid
In-game: Nemo
Location: Illinois, USA

Re: post your code!

by sorcerykid » Post

Lone_Wolf wrote:What code would I use to prevent players running commands if they are within a certain amount of nodes away from a certain block?
Here's the code I use for the "/spawn" command on my server. It prevents players from teleporting to spawn if they are too close or too far from the static spawn point. You should be able to adapt it to your needs for any other command.

Code: Select all

local SPAWN_RANGE_MIN = 150
local SPAWN_RANGE_MAX = 1500

minetest.register_chatcommand( "spawn", {
        description = "Return to static spawn point.",
        func = function( player_name )
                local player = minetest.get_player_by_name( player_name )
                local player_pos, player_off

                -- ensure player issuing command is in-game (not via IRC client)
                if player then
                        player_pos = player:getpos( )
                        player_off = vector.distance( player_pos, default.spawn_pos )

                        if player_off > SPAWN_RANGE_MAX and player_pos.y > -SPAWN_RANGE_MIN then
                                return false, "You must be closer to spawn to use this command."
                        elseif player_off < SPAWN_RANGE_MIN then
                                return false, "You must be further from spawn to use this command."
                        end

                        player:setpos( default.spawn_pos )

                        -- sound effect is from teleport_request mod, might want to move to default
                        minetest.sound_play( "whoosh", { pos = default.spawn_pos, gain = 0.3, max_hear_distance = 10 } )
                        minetest.log( "action", "Moving " .. player_name .. " from " .. minetest.pos_to_string( player_pos ) .. " to static spawnpoint" )

                        if default.player_get_animation( player ).animation == "sit" then
                                player:set_eye_offset( vector.origin, vector.origin )
                                player:set_physics_override( { speed = 1, jump = 1, gravity = 1 } )
                                player:hud_set_flags( { wielditem = true } )

                                default.player_set_animation( player, "stand", 30 )
                                default.player_attached[ player_name ] = false
                        end
                end
        end
})

User avatar
Lone_Wolf
Member
Posts: 2576
Joined: Sun Apr 09, 2017 05:50
GitHub: LoneWolfHT
IRC: LandarVargan
In-game: LandarVargan

Re: post your code!

by Lone_Wolf » Post

sorcerykid wrote:
Lone_Wolf wrote:What code would I use to prevent players running commands if they are within a certain amount of nodes away from a certain block?
Here's the code I use for the "/spawn" command on my server. It prevents players from teleporting to spawn if they are too close or too far from the static spawn point. You should be able to adapt it to your needs for any other command.

Code: Select all

local SPAWN_RANGE_MIN = 150
local SPAWN_RANGE_MAX = 1500

minetest.register_chatcommand( "spawn", {
        description = "Return to static spawn point.",
        func = function( player_name )
                local player = minetest.get_player_by_name( player_name )
                local player_pos, player_off

                -- ensure player issuing command is in-game (not via IRC client)
                if player then
                        player_pos = player:getpos( )
                        player_off = vector.distance( player_pos, default.spawn_pos )

                        if player_off > SPAWN_RANGE_MAX and player_pos.y > -SPAWN_RANGE_MIN then
                                return false, "You must be closer to spawn to use this command."
                        elseif player_off < SPAWN_RANGE_MIN then
                                return false, "You must be further from spawn to use this command."
                        end

                        player:setpos( default.spawn_pos )

                        -- sound effect is from teleport_request mod, might want to move to default
                        minetest.sound_play( "whoosh", { pos = default.spawn_pos, gain = 0.3, max_hear_distance = 10 } )
                        minetest.log( "action", "Moving " .. player_name .. " from " .. minetest.pos_to_string( player_pos ) .. " to static spawnpoint" )

                        if default.player_get_animation( player ).animation == "sit" then
                                player:set_eye_offset( vector.origin, vector.origin )
                                player:set_physics_override( { speed = 1, jump = 1, gravity = 1 } )
                                player:hud_set_flags( { wielditem = true } )

                                default.player_set_animation( player, "stand", 30 )
                                default.player_attached[ player_name ] = false
                        end
                end
        end
})
Thanks!
My ContentDB -|- Working on CaptureTheFlag -|- Minetest Forums Dark Theme!! (You need it)

User avatar
Andrey01
Member
Posts: 2574
Joined: Wed Oct 19, 2016 15:18
GitHub: Andrey2470T
In-game: Andrey01
Location: Russia, Moscow

Re: post your code!

by Andrey01 » Post

What`s code should be posted here? Minetest API? Just Lua code? Or anything else?

User avatar
sorcerykid
Member
Posts: 1841
Joined: Fri Aug 26, 2016 15:36
GitHub: sorcerykid
In-game: Nemo
Location: Illinois, USA

Re: post your code!

by sorcerykid » Post

This is a handy function I wrote to get the daylight and nightlight values from the param1 of a node simultaneously. It is a bit more convenient than calling minetest.get_node_light( ) twice, once with timeofday value of 0 and then again with timeofday 0.5.

param1 = minetest.get_node_param1( pos )

Code: Select all

minetest.get_node_param1 = function( pos )
        param1 = minetest.get_node( pos ).param1
        -- comparing nightlight and daylight is not a foolproof way to get sunlight
        -- since artificial light can exceed the natural light in shady areas
        return { daylight = ( param1 / 16 ) % 1 * 16, nightlight = math.floor( param1 / 16 ) }
end
The daylight and nightlight values of the param1 table correspond to the combined artificial light and natural light of a node at pos during the day vs during the night. There is, unfortunately, no way to ascertain sunlight exclusively since that is only calculated when the lighting is updated by the engine, and not stored anywhere (to my knowlege).

User avatar
sorcerykid
Member
Posts: 1841
Joined: Fri Aug 26, 2016 15:36
GitHub: sorcerykid
In-game: Nemo
Location: Illinois, USA

Re: post your code!

by sorcerykid » Post

Here are two helper functions I wrote for converting the game time and the game date into strings. These can be useful in formspecs, chat commands, HUD elements, etc. Both functions accept a tokenized input string for customization.

date_str = minetest.get_date_string( str, env_date )
Returns the game date as a human-readable string
  • str - an optional tokenized string to represent the game date
  • env_date - an optional game date specifier, or the current date if nil
  • Code: Select all

    Cardinal values:
    %Y - elapsed years in epoch
    %M - elapsed months in year
    %D - elapsed days in month
    %J - elapsed days in year
    
    Ordinal values:
    %y - current year of epoch
    %m - current month of year
    %d - current day of month
    %j - current day of year
    
time_str = minetest.get_time_string( str, env_time )
Returns the game time as a human-readable string
  • str - an optional tokenized string to represent the game time
  • env_date - an optional game time specifier, or the current time if nil
  • Code: Select all

    %pp - daypart as AM or PM
    %hh - hours in 24-hour clock
    %cc - hours in 12-hour clock
    %mm - minutes
    
Even though there is no formal calendar convention in most Minetest games, I settled on months having 30 days and years having 360 days -- as a suitable homage to the mathematical simplicity of the voxel world.

Code: Select all

minetest.get_date_string = function( str, env_date )
        if not env_date then
                env_date = minetest.get_day_count( )
        end

        local months1 = { 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' }
        local months2 = { 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' }

        if str == nil then
                str = "%D Days, %M Months, %Y Years"
        end

        local y = math.floor( env_date / 360 )
        local m = math.floor( env_date % 360 / 30 )
        local d = math.floor( env_date % 360 % 30 )
        local j = math.floor( env_date % 360 )

        -- cardinal values
        str = string.gsub( str, "%%Y", y )              -- elapsed years in epoch
        str = string.gsub( str, "%%M", m )              -- elapsed months in year
        str = string.gsub( str, "%%D", d )              -- elapsed days in month
        str = string.gsub( str, "%%J", j )              -- elapsed days in year

        -- ordinal values
        str = string.gsub( str, "%%y", y + 1 )          -- current year of epoch
        str = string.gsub( str, "%%m", m + 1 )          -- current month of year
        str = string.gsub( str, "%%d", d + 1 )          -- current day of month
        str = string.gsub( str, "%%j", j + 1 )          -- current day of year

        str = string.gsub( str, "%%b", months1[ m + 1 ] )       -- current month long name
        str = string.gsub( str, "%%h", months2[ m + 1 ] )       -- current month short name

        str = string.gsub( str, "%%z", "%%" )

        return str
end

minetest.get_time_string = function( str, env_time )
        if not env_time then
                env_time = math.floor( minetest.get_timeofday( ) * 1440 )
        elseif env_time > 1440 then
                env_time = env_time % 1440      -- prevent overflow
        end

        if str == nil then
                str = "%cc:%mm %pp"
        end

        local pp = env_time < 720 and "AM" or "PM"
        local hh = math.floor( env_time / 60 )
        local mm = math.floor( env_time % 60 )
        local cc = hh

        if cc > 12 then
                cc = cc - 12;
        elseif cc == 0 then
                cc = 12;
        end

        str = string.gsub( str, "%%pp", pp )                            -- daypart as AM or PM
        str = string.gsub( str, "%%hh", string.format( "%02d", hh ) )   -- hours in 24 hour clock
        str = string.gsub( str, "%%cc", string.format( "%02d", cc ) )   -- hours in 12 hour clock
        str = string.gsub( str, "%%mm", string.format( "%02d", mm ) )   -- minutes

        return str
end


User avatar
sorcerykid
Member
Posts: 1841
Joined: Fri Aug 26, 2016 15:36
GitHub: sorcerykid
In-game: Nemo
Location: Illinois, USA

Re: post your code!

by sorcerykid » Post

Here is an authentication rule I devised for rejecting player names with nonsensical or annoying formatting, including bots and guests:
  • names that begin or end with a symbol, as in "BobVila_" or "--BobVila--"
  • names with three or more uppercase letters in a row (uppercase spamming), as in "BOBVILA"
  • names shorter than 3 characters or longer than 20 characters
  • names with three or more numbers in a row (number spamming), as in "BobVila1996"
  • names with two or more symbols in a row (symbol spamming), as in "Bob____Vila"
  • auto-generated names like TommyTomato55, BillyHarrington121, Guest96, Player12
I believe, this should weed out the majority of nuisance names, the rest can be handled on a case-by-case basis :)

Code: Select all

try "Sorry, the player name '$name' is not allowed on this server. Please choose a more suitable name."

fail any
if $name->len() gt 20
if $name->len() lt 3
if $name is /*;;;*/
if $name is /*###*/
if $name is /*==*/
if $name is /*=/
if $name is /=*/
if $name is /;*;*##/
if $name is /Player#/
if $name is /Player##/
if lc($name) is /guest*/
continue

User avatar
sorcerykid
Member
Posts: 1841
Joined: Fri Aug 26, 2016 15:36
GitHub: sorcerykid
In-game: Nemo
Location: Illinois, USA

Re: Post your code!

by sorcerykid » Post

This is an authentication ruleset for blocking players that try to login to a server with the wrong password more than four times in a row from a single IP address, imposing a 1 minute waiting period.

Code: Select all

try "You cannot create a new account right now. Please try again later."
fail all
if $is_new eq $true
if $ip_failures gt 0
unless $ip_prelogin lt -5m
continue

try "Your access to the account $name has been temporarily restricted."
fail all
if $ip_failures gt 4
if $ip_names_list->clip(-5)->count($name) gt 0
unless $ip_newcheck lt -1m
continue

pass now
In addition, the ruleset prevents players from creating a new account for at least 5 minutes after failing to login to an existing account (a common problem with little kids that forget their password). The ruleset has been battlefield tested in the new MARS debugger :)

Image

User avatar
Linuxdirk
Member
Posts: 3217
Joined: Wed Sep 17, 2014 11:21
In-game: Linuxdirk
Location: Germany
Contact:

Re: Post your code!

by Linuxdirk » Post

Recursively replace all occurrences of a string in all table entries

Code: Select all

-- needs to be created first in order to make recursive calling it possible
local deep_replace

-- Build the function
deep_replace = function (table, search_for, replacement)
    local result = {}

    for id,entry in pairs(table) do
        if type(entry) == 'table' then
            result[id] = deep_replace(entry, search_for, replacement)
        else
            result[id] = entry:gsub(search_for, replacement)
        end
    end

    return result
end
Example:

Code: Select all

local my_table = {
    foo = 'bar',
    blah = {
        lala = 'foo and bar',
        lolo = {
            haha = 'bar and foo'
        }
    }
}

local new_table = deep_replace(my_table, 'bar', 'baz')
my_table:

Code: Select all

foo: bar
blah: 
  lolo: 
    haha: bar and foo
  lala: foo and bar
new_table:

Code: Select all

foo: baz
blah: 
  lala: foo and baz
  lolo: 
    haha: baz and foo
Maybe there’s a better version but I like this one.

User avatar
Stix
Member
Posts: 1385
Joined: Fri Aug 04, 2017 14:19
IRC: nil
In-game: Stix [+alts]
Location: USA

Re: Post your code!

by Stix » Post

Ive been leaning C and created a simple and crappy terminal-based text-adventure game:

Code: Select all

#include <stdio.h>
#include <string.h>

int hunger;
int thirst;
int day;
int status;
int choice;
int water;
int fooditems;
char current_sit[100];

int drink() //Defining the function 'drink'.
{
  if(water < 1)
    printf("You have no more water to drink\n");
  else
    {   
      water--;
      thirst = thirst - 5;
      printf("You drank some water and are less thirsty.\n");
    }
  if(thirst < 0)
    thirst = 0;
}

int eat() //Defining the function 'eat'.
{
  if(fooditems < 1)
    printf("You have no more food to eat.\n");
  else
    {
      fooditems--;
      hunger = hunger - 3;
      printf("You ate some food and are less hungry.\n");
    }
  if(hunger < 0)
    hunger = 0;
}

int defaults() //Defining a function that stores default values.
{
  status = 0;
  day = 1;
  water = 3;
  fooditems = 5;
  thirst = 0;
  hunger = 0;
}

main()
{
  
  defaults();
  
  strcpy(current_sit, "You are walking through an anbandoned town.");
  
  while(status == 0)
    {
      printf("\n\nDay %d: %s\n", day, current_sit);  //Here's the characters status.
      printf("\nHunger: %d out of 10.", hunger);
      printf("\nThirst: %d out of 10.", thirst);
      printf("\n\nYou have %d water-bottles.", water);
      printf("\nYou have %d food-items.", fooditems);
      printf("\n\nPress \'1\' to drink, \'2\' to eat, or \'3\' to wait: "); //Taking input.

      scanf("%d", &choice);
      
      if(choice == 1) //This part handles choices.
	drink();
      if(choice == 2)
	eat();
      if(choice == 3)
	hunger = hunger;
      
      hunger++;  //Here we increase the players atributes and the day each loop.
      thirst = thirst + 2;
      day++;
      
      if(hunger > 10)  //Here we define the situations that will break the loop.
	status = 1;
      
      if(thirst > 10)
	status = 2;
      
      if(status == 1)
	{
	  printf("\nYou died of hunger. ");
	  printf("Press \'1\' to restart or \'2\' to quit: ");
	  scanf("%d", &choice);

	  if(choice == 1)
	    {
	      defaults();
	      continue;
	    }

	  if(choice == 2)
	    break;
	}
      
      if(status == 2)
	{
	  printf("\nYou died of thirst. ");
	  printf("Press \'1\' to restart or \'2\' to quit: ");
	  scanf("%d", &choice);

	  if(choice == 1)
	    {
	      defaults();
	      continue;
	    }
	    
	  if(choice == 2)
	    break; 
	}
      
    }
      
  return(0);
}
Hey, what can i say? I'm the bad guy.

User avatar
Lone_Wolf
Member
Posts: 2576
Joined: Sun Apr 09, 2017 05:50
GitHub: LoneWolfHT
IRC: LandarVargan
In-game: LandarVargan

Re: Post your code!

by Lone_Wolf » Post

Stix wrote:Ive been leaning C and created a simple and crappy terminal-based text-adventure game:

Code: Select all

#include <stdio.h>
#include <string.h>

int hunger;
int thirst;
int day;
int status;
int choice;
int water;
int fooditems;
char current_sit[100];

int drink() //Defining the function 'drink'.
{
  if(water < 1)
    printf("You have no more water to drink\n");
  else
    {   
      water--;
      thirst = thirst - 5;
      printf("You drank some water and are less thirsty.\n");
    }
  if(thirst < 0)
    thirst = 0;
}

int eat() //Defining the function 'eat'.
{
  if(fooditems < 1)
    printf("You have no more food to eat.\n");
  else
    {
      fooditems--;
      hunger = hunger - 3;
      printf("You ate some food and are less hungry.\n");
    }
  if(hunger < 0)
    hunger = 0;
}

int defaults() //Defining a function that stores default values.
{
  status = 0;
  day = 1;
  water = 3;
  fooditems = 5;
  thirst = 0;
  hunger = 0;
}

main()
{
  
  defaults();
  
  strcpy(current_sit, "You are walking through an anbandoned town.");
  
  while(status == 0)
    {
      printf("\n\nDay %d: %s\n", day, current_sit);  //Here's the characters status.
      printf("\nHunger: %d out of 10.", hunger);
      printf("\nThirst: %d out of 10.", thirst);
      printf("\n\nYou have %d water-bottles.", water);
      printf("\nYou have %d food-items.", fooditems);
      printf("\n\nPress \'1\' to drink, \'2\' to eat, or \'3\' to wait: "); //Taking input.

      scanf("%d", &choice);
      
      if(choice == 1) //This part handles choices.
	drink();
      if(choice == 2)
	eat();
      if(choice == 3)
	hunger = hunger;
      
      hunger++;  //Here we increase the players atributes and the day each loop.
      thirst = thirst + 2;
      day++;
      
      if(hunger > 10)  //Here we define the situations that will break the loop.
	status = 1;
      
      if(thirst > 10)
	status = 2;
      
      if(status == 1)
	{
	  printf("\nYou died of hunger. ");
	  printf("Press \'1\' to restart or \'2\' to quit: ");
	  scanf("%d", &choice);

	  if(choice == 1)
	    {
	      defaults();
	      continue;
	    }

	  if(choice == 2)
	    break;
	}
      
      if(status == 2)
	{
	  printf("\nYou died of thirst. ");
	  printf("Press \'1\' to restart or \'2\' to quit: ");
	  scanf("%d", &choice);

	  if(choice == 1)
	    {
	      defaults();
	      continue;
	    }
	    
	  if(choice == 2)
	    break; 
	}
      
    }
      
  return(0);
}
Nice :P
You might be interested in ncurses. (This was a good tutorial p.org/HOWTO/NCURSES-Programming-HOWTO/)
I did a few games with it. Pretty easy to work with. I've been working on a 2d sidescrolling sandbox terminal game recently. And I put a badly written dungeon-exploring one on Github https://github.com/LoneWolfHT/Dungeteer

Terminal games give me a nice vibe, even the simple ones
My ContentDB -|- Working on CaptureTheFlag -|- Minetest Forums Dark Theme!! (You need it)

User avatar
orwell
Member
Posts: 958
Joined: Wed Jun 24, 2015 18:45
GitHub: orwell96
IRC: orwell96_mt
In-game: orwell
Location: Raxacoricofallapatorius

Re: Post your code!

by orwell » Post

Stix wrote:Ive been leaning C and created a simple and crappy terminal-based text-adventure game:

Code: Select all

#include <stdio.h>
#include <string.h>

int hunger;
int thirst;
int day;
int status;
int choice;
int water;
int fooditems;
char current_sit[100];

int drink() //Defining the function 'drink'.
{
  if(water < 1)
    printf("You have no more water to drink\n");
  else
    {   
      water--;
      thirst = thirst - 5;
      printf("You drank some water and are less thirsty.\n");
    }
  if(thirst < 0)
    thirst = 0;
}

int eat() //Defining the function 'eat'.
{
  if(fooditems < 1)
    printf("You have no more food to eat.\n");
  else
    {
      fooditems--;
      hunger = hunger - 3;
      printf("You ate some food and are less hungry.\n");
    }
  if(hunger < 0)
    hunger = 0;
}

int defaults() //Defining a function that stores default values.
{
  status = 0;
  day = 1;
  water = 3;
  fooditems = 5;
  thirst = 0;
  hunger = 0;
}

main()
{
  
  defaults();
  
  strcpy(current_sit, "You are walking through an anbandoned town.");
  
  while(status == 0)
    {
      printf("\n\nDay %d: %s\n", day, current_sit);  //Here's the characters status.
      printf("\nHunger: %d out of 10.", hunger);
      printf("\nThirst: %d out of 10.", thirst);
      printf("\n\nYou have %d water-bottles.", water);
      printf("\nYou have %d food-items.", fooditems);
      printf("\n\nPress \'1\' to drink, \'2\' to eat, or \'3\' to wait: "); //Taking input.

      scanf("%d", &choice);
      
      if(choice == 1) //This part handles choices.
	drink();
      if(choice == 2)
	eat();
      if(choice == 3)
	hunger = hunger;
      
      hunger++;  //Here we increase the players atributes and the day each loop.
      thirst = thirst + 2;
      day++;
      
      if(hunger > 10)  //Here we define the situations that will break the loop.
	status = 1;
      
      if(thirst > 10)
	status = 2;
      
      if(status == 1)
	{
	  printf("\nYou died of hunger. ");
	  printf("Press \'1\' to restart or \'2\' to quit: ");
	  scanf("%d", &choice);

	  if(choice == 1)
	    {
	      defaults();
	      continue;
	    }

	  if(choice == 2)
	    break;
	}
      
      if(status == 2)
	{
	  printf("\nYou died of thirst. ");
	  printf("Press \'1\' to restart or \'2\' to quit: ");
	  scanf("%d", &choice);

	  if(choice == 1)
	    {
	      defaults();
	      continue;
	    }
	    
	  if(choice == 2)
	    break; 
	}
      
    }
      
  return(0);
}
Hey, this reminds me of my so-called "Dog-program", the more or less first program I wrote. Also a simple text adventure, but with no real challenge. You had a dog with a "hunger" and an "energy" value, and you could walk it, feed it and let it sleep. Eating decreased hunger, walking increased hunger and decreased energy and sleeping increased energy. When any of the values fell out of bounds in either direction, something happened. (E.g. energy>300 dog died of heart attack)
Lua is great!
List of my mods
I like singing. I like dancing. I like ... niyummm...

User avatar
Stix
Member
Posts: 1385
Joined: Fri Aug 04, 2017 14:19
IRC: nil
In-game: Stix [+alts]
Location: USA

Re: Post your code!

by Stix » Post

I dedicated some of my time programming today in improving my program 3 posts up. Among other things ive corrected several bugs, added a way to win, and have been making the code more flexible and less hard-coded:

Code: Select all

#include <stdio.h>
#include <string.h>

int hunger;
int thirst;
int day;
int water;
int fooditems;
int status;
int condition;
int input;
int output;
int win_check;
char death[100];
char choice1[100];
char choice2[100];
char choice3[100];
char situation1[100];
char situation2[100];
char situation3[100];
char current_sit[100];

int drink() //Defining the function 'drink'.
{
  if(water < 1)
    printf("You have no more water to drink\n");
  else
    {   
      water--;
      thirst = thirst - 5;
      printf("You drank some water and are less thirsty.\n");
    }
  if(thirst < 0)
    thirst = 0;
}

int eat() //Defining the function 'eat'.
{
  if(fooditems < 1)
    printf("You have no more food to eat.\n");
  else
    {
      fooditems--;
      hunger = hunger - 3;
      printf("You ate some food and are less hungry.\n");
    }
  if(hunger < 0)
    hunger = 0;
}

//defines a function that makes an if statement do nothing after conditions are met. 
int do_nothing()
{
  status = status;
}

int defaults() //Defining a function that stores default values.
{
  condition = 0;
  day = 0;
  water = 23;
  fooditems = 25;
  thirst = 0;
  hunger = 0;
  strcpy(current_sit, situation1); 
}

int event() //Handles events, very WIP.
{
  strcpy(situation1, "You are walking through an abandoned town.");
  output = strcmp(situation1, current_sit);

  if(output == 0)
    {
      strcpy(choice1, "Drink.");
      strcpy(choice2, "Eat.");
      strcpy(choice3, "Do nothing.");
    }
}

int death_event() //Computes cause of death and prints the death-message accordingly.
{
  if(win_check != 1)
    {
      if(hunger > 10)
	{ 
	  condition = 1;
	  strcpy(death, "hunger");
	}
      if(thirst > 10)
	{
	  condition = 1;
	  strcpy(death, "thirst");
	}
      if(condition == 1)
	{
	  printf("\nDeath by %s, you survived %d days. ", death, day);
	  printf("Press \'1\' to restart or \'2\' to quit: ");
	  scanf("%d", &input);
	  
	  if(input == 1)
	    {
	      defaults();
	      status = 1;
	    }
	  
	  if(input == 2)
	    status = 2;
	  
	  if(input > 2)
	    {	  
	      printf("\nError: to high a value.\n\n");
	      status = 2;
	    }
	}
    }
}
	    
int win()
{
  if(day > 29) //checks if the user wins and displays a message accordingly.
    {  
      printf("\nCongratulations, you survived all %d days!\n\n", day);
      win_check = 1;
    }
}

main()
{
  event();
  defaults();
  event();
 
  for(day = 1; day < 31; day++)
    {
      printf("\n\nDay %d: %s\n", day, current_sit);  //Here's the characters status.
      printf("\nHunger: %d out of 10.", hunger);
      printf("\nThirst: %d out of 10.", thirst);
      printf("\n\nYou have %d water-bottles.", water);
      printf("\nYou have %d food-items.", fooditems);
      printf("\n\nShould you: \n1) %s \n2) %s \n3) %s\n", choice1, choice2, choice3);

      scanf("%d", &input);
      
      if(input == 1)
	drink();
      if(input == 2)
	eat();
      if(input == 3)
	do_nothing();
      
      hunger++;  //Here we increase the players atributes each loop.
      thirst+=2;
            
      win();
      death_event();

      if(status == 1)
	continue;
      if(status == 2)
	break;
    }
      
  return(0);
}
Hey, what can i say? I'm the bad guy.

User avatar
sorcerykid
Member
Posts: 1841
Joined: Fri Aug 26, 2016 15:36
GitHub: sorcerykid
In-game: Nemo
Location: Illinois, USA

Re: Post your code!

by sorcerykid » Post

Here's an authenticatiion ruleset that I adapted from the guest blocker mod at https://github.com/thomasrudin-mt/guest_blocker

I tweaked it slightly, so it also allows players to bypass the soft limit if they are veterans to the server (account older than one year).

Code: Select all

# block guest players when more than 5 players currently online
# block new players when more than 15 players currently online
# block players without "limit_bypass" privilege when more than 25 players currently online
# block players that only registered this past year when more than 25 players currently online

try "Guests not allowed. Please use the official Minetest app."
fail all
if $cur_users gte 5
if $name is /+###/
continue

try "Too many players online right now. Please rejoin at a less busy moment."
fail all
if $cur_users gte 15
if $is_new eq $true
continue

fail all
if $cur_users gte 25
unless "limit_bypass" in $privs_list
if oldlogin gte -1y
continue

pass now

User avatar
Stix
Member
Posts: 1385
Joined: Fri Aug 04, 2017 14:19
IRC: nil
In-game: Stix [+alts]
Location: USA

Re: Post your code!

by Stix » Post

This is a simple text-based fighting game i cooked up today, it's probably my most complicated program so-far:

Code: Select all

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/***********************************************************************
 * A text-based and turn-based simple fighting game.                   *
 *                                                                     *
 * Moves:                                                              *
 *                                                                     *
 * 1: Fight. (deal damage to the enemy)                                *
 * 2: Recover. (recover players energy)                                *
 * 3: Skip turn. (what it says)                                        *
 *                                                                     *
 * Ruleset:                                                            *
 *                                                                     *
 * 1: When selecting the move "Fight.", the players/ai's energy        *
 *    is subtracted by 10. The enemy's health is subtracted            *
 *    by the attackers damage value and then has their recover         *
 *    value added to the result.                                       *
 *                                                                     *
 * 2: When selecting the move "Recover.", the player/ai's energy       *
 *    is increased by their recover value.                             *
 *                                                                     *
 * 3: When selecting the move "Skip turn." the player's (this move     *
 *    isn't viable for the ai) turn is skipped.                        *
 *                                                                     *
 ***********************************************************************/

int status;
int class;
int health;
int energy;
int attack;
int recover;
int turn;
int choice;
int enemy_health;
int enemy_energy;
int enemy_attack;
int enemy_recover;

int defaults() //sets these values every time the program is executed
{
  enemy_health = 100;
  enemy_energy = 40;
  enemy_attack = 30;
  enemy_recover = 5;

  status = 0;

  if(class == 1)
    {
      health = 100;
      energy = 40;
      attack = 20;
      recover = 5;
    }

  if(class == 2)
    {
      health = 90;
      energy = 30;
      attack = 30;
      recover = 10;
    }
}

int enemy() //a function that takes a number (0-2) and makes decisions based on the result
{
  if(turn == 1)
    {
      printf("\nEnemy's turn!");
      int r = rand() % 3; //grabbing a number (0-2)

      switch(r)
	{
	case 0:
	  /*fall through (which makes the enemy more likely to attack)*/
	case 1:	 
	  if(enemy_energy >= 10)
	    {
	      health += recover - enemy_attack; //attacking player
	      enemy_energy -= 10;
	      printf("\n\nThe enemy attacked!\n");
	      break;
	    }
	  /*fall through (so the enemy has to recover if they're unable to attack)*/
	case 2:	
	  enemy_energy += enemy_recover; //recovering energy
	  printf("\n\nThe enemy recovered energy.\n");
	  break;
	}
    }
}  
    
int win() //a function that checks if the player or enemy() won
{
  if(enemy_health <= 0) //checking if the enemy's health is 0 or less
    {
      printf("\nYou won!\n\n");
      status = 1; //changing status to 1 so the loop breaks
    }
  else
    if(health <= 0) //checking if player's health is 0 or less
      {
	printf("\nYou lost!\n\n");
	status = 1; //changing status to 1 so the loop breaks
      }
}

main()
{

  printf("\nPlease choose a class (1 or 2): "); //initial prompt
  scanf("%d", &class);

  defaults();

  while(status == 0) //loop repeats as long as the condition is met
    {
      printf("\n>>>>>>>STATS<<<<<<<   >>>>>>>ENEMY<<<<<<<");
      printf("\n*******************   *******************");
      printf("\n Health: %d            Health: %d         ", health, enemy_health);
      printf("\n Energy: %d            Energy: %d         ", energy, enemy_energy);
      printf("\n Attack: %d            Attack: %d         ", attack, enemy_attack);
      printf("\n Recover: %d           Recover: %d        ", recover, enemy_recover);
      printf("\n*******************   *******************\n");

      turn = 0; //sets turn to players beginning of every loop

      if(turn == 0) //takes input if conditions are met
	{
	  printf("\nYour turn!\n");
 
	  while(turn == 0)
	    {
	      printf("\n1) Fight.\n2) Recover.\n3) Skip turn.\n");
	      scanf("%d", &choice);
	      
	      if(choice == 1) //calculates the input and makes decisions based on it      
		{
		  if(energy >= 10)
		    {
		      enemy_health += enemy_recover - attack; //attacking enemy
		      energy -= 10;
		      break; //breaking the loop
		    }
		  else;
		  printf("\nYou dont have enough energy to attack!\n");
		  continue; //restarting the loop
		}	    
	      
	      if(choice == 2)
		energy += recover; //recover energy
	      break;
	      if(choice == 3)
		status = status; //the if statement executes nothing (hack)
	      break;
	      if(choice == 4) 
		status = 1;
	      break;
	    }
	}
    
      win(); //check if user won or lost
      if(status == 1)
	break; //breaking the loop if status == 1
      
      turn = 1; //sets turn to enemy() function end of every loop
      enemy();
    }
      

  return(0);
}
EDIT: can anyone tell me why pressing '4' doesn't end the program? I was sure i covered everything...
EDIT2: nvm i figured it out...
Hey, what can i say? I'm the bad guy.

User avatar
Stix
Member
Posts: 1385
Joined: Fri Aug 04, 2017 14:19
IRC: nil
In-game: Stix [+alts]
Location: USA

Re: Post your code!

by Stix » Post

I made my biggest program yet, it's basically the combinations of my text-adventure and fighting game's and might even be considered fun:

Code: Select all

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int hunger;
int food;
int thirst;
int water;
int medkit;
int day;
int choice;
int amount;
int turn;
int status;
int status1;
int item_value;
int situation;
int health;
int energy;
int attack;
int recover;
int enemy_health;
int enemy_energy;
int enemy_attack;
int enemy_recover;
char death[100];
char item[100];
char situation1[100];
char choice1[100];
char choice2[100];
char choice3[100];
char choice4[100];

int defaults() //stores defaults values that are called at th beginning of the program
{
  status1 = 0;
  status = 0;
  day = 0;
  health = 10;
  hunger = 0;
  thirst = 0;
  food = 5;
  water = 3;
  medkit = 1;
}

int fight_defaults() //stores default values for the functions fight()
{
  enemy_health = 10;
  enemy_energy = 4;
  enemy_attack = 3;
  enemy_recover = 2;
 
  energy = 4;
  attack = 3;
  recover = 2;
}

int drink()
{
  if(water < 1)
    printf("\nYou have no more water to drink.\n");
  else
    if(thirst > 0)
      {
	thirst -= 5;
	water--;
      }
  if(thirst < 0)
    thirst = 0;
}

int eat()
{
  if(food < 1)
    printf("\nYou have no more food to eat.\n");
  else
    if(hunger > 0)
      {
	hunger -= 3;
	food--;
      }
  if(hunger < 0)
    hunger = 0;
}

int do_nothing() //a function that does nothing (hack)
{
  status = status;
}

int heal()
{
  if(medkit < 1)
    printf("\nYou don't have any medkits.\n");
  else  
    if(health < 10)
      { 
	printf("\nYou healed.\n");
	health += 3;
	medkit--;
      }
    else
      printf("\nYou are already at full health.\n");
}

int choices() //a function that gives a set of choices based on the current situation
{ 
  int r2 = rand() % 3;
  int r3 = rand() % 5;
  int r4 = rand() % 2;
  
  if(situation == 1)
    {
      if(choice == 1)
	drink();
      if(choice == 2)
	eat();
      if(choice == 3)
	do_nothing;
      if(choice == 4)
	heal();
      if(choice == 5)
	status = 1;
    }
 
  if(situation == 2)
    {
      switch(choice)
	{
	case 1:
	  printf("\nYou started a fight!\n");
	  fight();
	  break;
	case 2:		  
	  if(r2 == 2)
	    {
	      printf("\nYou got attacked by a stranger!\n");
	      fight();
	    }
	  if(r2 <= 1)
	    {
	      printf("\nYou ran away from a fight.\n");
	      do_nothing();
	    }
	  break;
	case 3:		 
	  if(r4 == 0)
	    break;
	  if(r4 == 1)
	    printf("\nYou got attacked by a stranger!\n");
	  fight();
	  break;
	case 4:
	  do_nothing();
	  break;
	case 5:
	  status = 1;
	  break;
	}
    }
  
  if(situation == 3)
    {         
      if(r3 == 0)
	{
	  strcpy(item, "food-item");
	  item_value = 1;
	}
      if(r3 == 1)
	{
	  strcpy(item, "water-bottle");
	  item_value = 2;
	}
      if(r3 == 2)
	{
	  strcpy(item, "medkit");
	  item_value = 3;
	}  
      if(r3 >= 3)
	printf("\nThe box was empty!\n");
               
      amount = r3;
   
      if(r3 <= 2)
	{   
	  if(choice == 1)
	    {
	      printf("\nYou found %d %s(s).\n", amount, item);
	      
	      if(item_value == 1)
		food += amount;
	      if(item_value == 2)
		water += amount;
	      if(item_value == 3)
		medkit += amount;
	    }
	}
      
      if(choice == 2)
	do_nothing();
      if(choice == 3)
	do_nothing();
      if(choice == 4)
	do_nothing();
      if(choice == 5)
	status = 1;
    }
}


int situations() //a function that randomly picks a situation to be current
{
  int r = rand() % 5; //grabbing a random number (0-4)

  if(r <= 2)
    {
      strcpy(situation1, "You are walking through an abandoned town."); //setting situation
      strcpy(choice1, "Drink."); //setting choices for the situation
      strcpy(choice2, "Eat.");
      strcpy(choice3, "Do nothing.");
      strcpy(choice4, "Heal.");
      situation = 1;
    }
  
  if(r == 3)
    {
      strcpy(situation1, "While walking you meet a stranger."); //setting situation
      strcpy(choice1, "Fight."); //setting choices for the situation
      strcpy(choice2, "Run.");
      strcpy(choice3, "Do nothing.");
      strcpy(choice4, " ");
      situation = 2;
    }

  if(r == 4)
    {
      strcpy(situation1, "While walking you find a box."); //setting situation
      strcpy(choice1, "Open it."); //setting choices for the situation
      strcpy(choice2, "Do nothing.");
      strcpy(choice3, " ");
      strcpy(choice4, " ");
      situation = 3;
    }
}

int fight() //a function that handles fighting between the player and enemy ai
{
  fight_defaults();
  
  while(1) //loop repeats unntil a 'break' is called
    {
      printf("\n>>>>>>>STATS<<<<<<<   >>>>>>>ENEMY<<<<<<<");
      printf("\n*******************   *******************");
      printf("\n Health: %d            Health: %d         ", health, enemy_health);
      printf("\n Energy: %d            Energy: %d         ", energy, enemy_energy);
      printf("\n Attack: %d            Attack: %d         ", attack, enemy_attack);
      printf("\n Recover: %d           Recover: %d        ", recover, enemy_recover);
      printf("\n*******************   *******************\n");
      
      turn = 0; //sets turn to players beginning of every loop
      
      if(turn == 0) //takes input if conditions are met
	{
	  printf("\nYour turn!\n");
	  
	  while(turn == 0)
	    {
	      printf("\n1) Fight.\n2) Recover.\n3) Skip turn.\n");
	      scanf("%d", &choice);
	      
	      if(choice == 1) //calculates the input and makes decisions based on it      
		{
		  if(energy >= 1)
		    {
		      enemy_health += enemy_recover - attack; //attacking enemy
		      energy -= 1;
		      break; //breaking the loop
		    }
		  else
		    printf("\nYou dont have enough energy to attack!\n");
		  continue; //restarting the loop
		}
	      
	      if(choice == 2)
		energy += recover; //recover energy
	      break;
	      if(choice == 3)
		do_nothing(); //the if statement executes nothing (hack)
	      break;		      
	    }		    	          
	}
  
      if(enemy_health < 1) //checking if the player won the fight
	{
	  printf("\nYou won the fight!\n");
	  break;
	}
      
      death_event();

      if(status1 == 1)
	break;
      
      turn = 1; //sets turn to enemy() function end of every loop
      enemy();
    }
}

int enemy() //a function that takes a number (0-2) and makes decisions based on the result
{
  if(turn == 1)
    {
      printf("\nEnemy's turn!");
      int r = rand() % 3; //grabbing a number (0-2)
      
      switch(r)
	{
	case 0:
	  /*fall through (which makes the enemy more likely to attack)*/
	case 1:	 
	  if(enemy_energy >= 1)
	    {
	      health += recover - enemy_attack; //attacking player
	      enemy_energy -= 1;
	      printf("\n\nThe enemy attacked!\n");
	      break;
	    }
	  /*fall through (so the enemy has to recover if they're unable to attack)*/
	case 2:	
	  enemy_energy += enemy_recover; //recovering energy
	  printf("\n\nThe enemy recovered energy.\n");
	  break;
	}
    }
}  

int death_event() //Computes cause of death and prints the death-message accordingly.
{
  if(hunger > 10) //checks if the player has starved
    { 
      status = 3;
      strcpy(death, "hunger");
    }
  if(thirst > 10) //checks if the player is dehydrated
    {
      status = 3;
      strcpy(death, "thirst");
    }
  if(health < 1) //checks if the player was killed by the enemy ai
    {
      status = 3;
      strcpy(death, "a stranger");
    }
  if(status == 3)
    {
      /*notifying the user of their characters death*/
      printf("\nDeath by %s, you survived %d days. ", death, day);
      status = 1;
      printf("Press \'1\' to restart or \'2\' to quit: ");
      scanf("%d", &choice);
      
      if(choice == 1)
	{
	  defaults();
	  status = 2;
	  status1 = 1;
	}
      
      if(choice == 2)
	{
	  status = 1;
	  status1 = 1;
	}
      
      if(choice > 2)
	{	  
	  /*informing the user of an invalid number for input*/
	  printf("\nError: to high a value.\n\n");
	  status = 1;
	}
    }
}


int win() //checks if the user wins and notifies them accordingly
{
  if(day > 29)
    printf("\nCongratulations, you survived all %d days!\n\n", day);
}


main()
{
  
  defaults(); //grabbing default values
  
  for(day = 1; day < 31; day++) //a loop that will run until day == 30
    {
      situations(); //executing a function that randomly sets the situation
      
      printf("\nDay %d: %s\n", day, situation1);
      printf("\n>>>>>>>>>>>>>>>>>>STATS<<<<<<<<<<<<<<<<<<");
      printf("\n*****************************************");
      printf("\nHealth: %d out of 10", health);
      printf("\nHunger: %d out of 10", hunger);
      printf("\nThirst: %d out of 10", thirst);
      printf("\n\nYou have %d water-bottle(s).", water);
      printf("\nYou have %d food-item(s).", food);
      printf("\nYou have %d medkit(s).", medkit);
      printf("\n*****************************************\n");
      printf("\nShould you:\n1) %s\n2) %s\n3) %s\n4) %s\n", choice1, choice2, choice3, choice4);
      
      scanf("%d", &choice);
      
      /*executing a function that will make decisions based on the current situation and
        the users input*/ 
      choices();

      if(situation == 1) //incrementing hunger/thirst every loop if the condition is met
	{
	  hunger++; 
	  thirst+=2;
	}

      if(hunger < 1) //healing the player if they arent hungry nor thirsty each loop
	{
	  if(thirst < 1)
	    printf("\nYou healed because you weren't hungry or thirst.\n");
	    health += 3;
	  if(health > 10)
	    health = 10;
	}

      death_event(); //executing a function that checks if the player died
      win(); //executing a function that will check if the user won
     
      if(status == 1)
	break;
      if(status == 2)
	defaults(); //grabbing default values
      continue;
    }

  return(0);
}
Hey, what can i say? I'm the bad guy.

Post Reply

Who is online

Users browsing this forum: No registered users and 16 guests